#include <stdio.h>
#include "geodata.h"
PTS_NODE *pts_list = NULL;
PTS_NODE *pts;
SEG_NODE *seg_list = NULL;
SEG_NODE *seg;
BND_NODE *bnd_list = NULL;
BND_NODE *bnd;
GEO_NODE *geo_list = NULL;
GEO_NODE *geo;
/*
* +---------------------------------------------------------+
* | Private routines needed to manipulate the geometry data |
* +---------------------------------------------------------+
*/
void rm_pnt(float x, float y);
PTS_NODE *last_item();
SEG_NODE *last_seg();
PTS_NODE *find_item(float x, float y);
PTS_NODE *left_insert_item(float x, float y);
void rigth_insert_item(float x, float y);
void rm_item(PTS_NODE *this);
void rm_seg(SEG_NODE *this);
PTS_NODE *find_pnt(float x, float y);
void rm_pnt(float x, float y);
BND_NODE *add_bnd(SEG_NODE *seg, GEO_NODE *geo);
BND_NODE *add_bnd(SEG_NODE *seg, GEO_NODE *geo)
{
bnd = (BND_NODE *)malloc(sizeof(BND_NODE));
if(bnd == NULL)
printf("out of memory\n");
bnd->seg = seg;
bnd->next = geo->bnd_list;
bnd->prev = NULL;
if(geo->bnd_list != NULL)
geo->bnd_list->prev = bnd;
geo->bnd_list = bnd;
return bnd_list;
}
PTS_NODE *last_item()
{
PTS_NODE *p;
if(pts_list == NULL)
;
else{
FOR_ALL_POINTS( p )
;
}
return p;
}
SEG_NODE *last_seg()
{
SEG_NODE *p;
if(seg_list == NULL)
;
else{
for( p = seg_list; p->next != NULL; p = p->next)
;
}
return p;
}
PTS_NODE *find_item(float x, float y)
{
PTS_NODE *p;
if(pts_list == NULL)
;
else{
FOR_ALL_POINTS( p ){
if(p->physicalX == x && p->physicalY == y){
return p;
}
}
return NULL;
}
return NULL;
}
PTS_NODE *left_insert_item(float x, float y)
{
pts = (PTS_NODE *)malloc(sizeof(PTS_NODE));
if(pts == NULL)
printf("out of memory\n");
pts->physicalX = x;
pts->physicalY = y;
pts->n = 0;
pts->next = pts_list;
pts->prev = NULL;
if(pts_list != NULL)
pts_list->prev = pts;
pts_list = pts;
return pts;
}
void rigth_insert_item(float x, float y)
{
PTS_NODE *p;
pts = (PTS_NODE *)malloc(sizeof(PTS_NODE));
if(pts == NULL)
printf("out of memory\n");
pts->physicalX = x;
pts->physicalY = y;
pts->n = 1;
p = last_item();
pts->prev = p;
pts->next = NULL;
p->next = pts;
}
void rm_item(PTS_NODE *this)
{
PTS_NODE *left;
PTS_NODE *right;
left = this->prev;
right= this->next;
free(this);
if(left != NULL)
left->next = right;
else
pts_list = right;
if(right != NULL)
right->prev = left;
}
void rm_seg(SEG_NODE *this)
{
SEG_NODE *left;
SEG_NODE *right;
left = this->prev;
right= this->next;
if(this->n > 1)
this->n--;
else{
free(this);
if(left != NULL)
left->next = right;
else
seg_list = right;
if(right != NULL)
right->prev = left;
}
}
void dump_items()
{
PTS_NODE *p;
if(pts_list == NULL)
printf("empty list\n");
else{
FOR_ALL_POINTS( p )
printf("%f -> ", p->x);
}
printf("\n");
}
void dump_all()
{
BND_NODE *p;
SEG_NODE *s;
GEO_NODE *g;
PTS_NODE *p1, *p2;
printf("There are currently %i boundaries\n", number_of_boundaries());
printf("There are currently %i points\n", number_of_points());
printf("Dumping all known boundaries\n");
FOR_ALL_BOUNDARIES( g ){
printf("bnd:\n");
FOR_ALL_SEGMENTS(g, p){
s = p->seg;
p1 = s->pts1;
p2 = s->pts2;
printf("(%f %f) ->(%f %f) \n", p1->physicalX, p1->physicalY,
p2->physicalX, p2->physicalY);
}
}
printf("\n");
}
PTS_NODE *find_pnt(float x, float y)
{
PTS_NODE *p;
if(pts_list == NULL)
;
else{
FOR_ALL_POINTS( p ){
if(p->physicalX == x && p->physicalY == y){
return p;
}
}
return NULL;
}
return NULL;
}
void rm_pnt(float x, float y)
{
PTS_NODE *p;
p = find_item(x, y);
if(p != NULL){
if(p->n > 1)
p->n--;
else
rm_item(p);
}
}
/*
*
* +-----------------+
* | Public routines |
* +-----------------+
*
*/
void init_geodata()
{
pts_list = NULL;
seg_list = NULL;
bnd_list = NULL;
geo_list = NULL;
}
/*
*
* +------------------------------+
* | Adds a point to the database |
* +------------------------------+
Arguments: x, y - The coordinates of the point
Returns: A pointer to the new point
Description:
*
*/
PTS_NODE *add_pnt(float x, float y)
{
PTS_NODE *p;
p = find_item(x, y);
if(p == NULL)
p = left_insert_item(x, y);
return p;
}
/*
* +----------------------------------------------------------+
* | Moves a specific point in the database to a new location |
* +----------------------------------------------------------+
Arguments: x, y - The old location
xnew, ynew - The new location
Returns:
Description: Finds the point at (x,y) and changes the
coordinates to (xnew,ynew)
*/
void mv_pnt(float x, float y, float xnew, float ynew)
{
PTS_NODE *p;
p = find_item(x, y);
if(p != NULL){
p->physicalX = xnew;
p->physicalY = ynew;
}
}
/*
* +---------------------------------------------+
* | Removes a complete boundary in the database |
* +---------------------------------------------+
Arguments: this - A pointer to the boundary that is removed
Returns:
Description:
*/
void rm_bnd(GEO_NODE *this)
{
GEO_NODE *left;
GEO_NODE *right;
BND_NODE *p;
SEG_NODE *s;
PTS_NODE *p1, *p2;
left = this->prev;
right= this->next;
FOR_ALL_SEGMENTS(this, p){
s = p->seg;
p1 = s->pts1;
p2 = s->pts2;
rm_seg(s);
rm_pnt(p1->physicalX, p1->physicalY);
rm_pnt(p2->physicalX, p2->physicalY);
}
free(this);
if(left != NULL)
left->next = right;
else
geo_list = right;
if(right != NULL)
right->prev = left;
}
/*
* +--------------------------------+
* | Adds a segment to the database |
* +--------------------------------+
Arguments: pts1, pts2 - The two points making up this segment
bnd - The boundary that the segment is added to
Returns: A pointer to a segment
Description:
*
*/
void clear_geometry()
{
GEO_NODE *g;
FOR_ALL_BOUNDARIES(g)
rm_bnd(g);
}
void add_seg(PTS_NODE *pts1, PTS_NODE *pts2, GEO_NODE *bnd)
{
SEG_NODE *seg;
seg = (SEG_NODE *)malloc(sizeof(SEG_NODE));
if(seg == NULL)
printf("out of memory\n");
seg->n = 1;
seg->pts1 = pts1;
seg->pts2 = pts2;
pts1->n++;
pts2->n++;
seg->next = seg_list;
seg->prev = NULL;
if(seg_list != NULL)
seg_list->prev = seg;
seg_list = seg;
add_bnd(seg, bnd);
}
void add_seg2(int seg_id, GEO_NODE *bnd)
{
SEG_NODE *seg;
seg = (SEG_NODE *)malloc(sizeof(SEG_NODE));
if(seg == NULL)
printf("out of memory\n");
seg->n = 1;
seg->id = seg_id;
seg->next = seg_list;
seg->prev = NULL;
if(seg_list != NULL)
seg_list->prev = seg;
seg_list = seg;
add_bnd(seg, bnd);
}
/*
* +-------------------------------------+
* | Adds a new boundary to the database |
* +-------------------------------------+
Arguments:
Returns: A pointer to the new boundary
Description:
*/
GEO_NODE *new_bnd()
{
geo = (GEO_NODE *)malloc(sizeof(GEO_NODE));
if(geo == NULL)
printf("out of memory\n");
geo->bnd_list = bnd_list;
geo->next = geo_list;
geo->prev = NULL;
if(geo_list != NULL)
geo_list->prev = geo;
geo_list = geo;
return geo_list;
}
/*
* +-------------------------------------------------+
* | Counts the number of boundaries in the database |
* +-------------------------------------------------+
Arguments:
Returns: The number of boundaries
Description:
*/
int number_of_boundaries()
{
int i;
GEO_NODE *g;
i = 0;
FOR_ALL_BOUNDARIES( g )
i++;
return i;
}
PTS_NODE *get_pts_pointer(int id)
{
PTS_NODE *p;
FOR_ALL_POINTS(p){
if(p->id == id)
return p;
}
return NULL;
}
/*
* +---------------------------------------------+
* | Counts the number of points in the database |
* +---------------------------------------------+
Arguments:
Returns: The number of points
Description:
*/
int number_of_points()
{
int i;
PTS_NODE *p;
i = 0;
FOR_ALL_POINTS( p )
i++;
return i;
}
/*
* +---------------------------------------------+
* | Counts the number of points in the database |
* +---------------------------------------------+
Arguments:
Returns: The number of points
Description:
*/
int number_of_segments(GEO_NODE *g)
{
int i;
BND_NODE *s;
i = 0;
FOR_ALL_SEGMENTS(g, s)
i++;
return i;
}
syntax highlighted by Code2HTML, v. 0.9.1