This is pointdata.c in view mode; [Download] [Up]
#import <stdio.h> #import <stdlib.h> #import "pointdata.h" #import "appkit/graphics.h" #import <math.h> /* This is pointdata.c. */ void newPointList(PointList *p) { p->head = NULL; p->tail = NULL; p->quantity = 0; } void freePointList(PointList *p) { pointNode *t; for(t=p->head;(t);t=p->head) { p->head = p->head->next; free(t); } p->head = NULL; p->tail = NULL; p->quantity = 0; } int addBlockTo(PointList *p) { p->tail->next = (pointNode *)malloc(sizeof(pointNode)); if (!(p->tail->next)) return 0; p->tail = p->tail->next; p->tail->contains = 0; p->tail->next = NULL; return 1; } int addStartBlockTo(PointList *p) { p->head = p->tail = (pointNode *)malloc(sizeof(pointNode)); if (!(p->head)) return 0; p->head->contains = 0; p->head->next = NULL; return 1; } void addPointTo(PointList *p, Point *pt) { int r; /* Requires that p->tail not be full!!!!!! */ r = p->tail->contains; p->tail->block[r].x = pt->x; p->tail->block[r].y = pt->y; p->tail->block[r].pen = pt->pen; p->tail->block[r].pencolour = pt->pencolour; p->tail->contains++; } int addToPointList(PointList *p, Point *pt) { if (pt->pen == SKIP) return 1; if (p->tail) { /* normal case */ if (p->tail->contains >= BLOCKSIZE) if (!(addBlockTo(p))) return 0; addPointTo(p,pt); } else { /* first point added. */ if (!(addStartBlockTo(p))) return 0; addPointTo(p,pt); } p->quantity++; return 1; } void eliminate(pointBlock b,int size, int index) { int i; for(i=index;(i<(size-1));i++) b[i] = b[i+1]; } int removeFromPointList(PointList *p,int index) { pointNode *s,*g; int sum = 0; int t = 1; g = NULL; if (index >= p->quantity) return 0; for(s = p->head;((s) && (t));) { sum = sum + s->contains; if (index < sum) t = 0; else { g = s; s=s->next; } } if (s) if (s->contains == 1) { if (g) { g->next = s->next; if (!(g->next)) p->tail = g; } else { p->head = s->next; if (!(s->next)) p->tail = NULL; } free(s); } else eliminate(s->block,s->contains,(index - (sum - s->contains))); else return 0; s->contains--; p->quantity--; return 1; } void insertpointat(pointBlock b, int index, int size, Point *pt) { int i; if (size >= BLOCKSIZE) size = BLOCKSIZE -1; for(i = size;(i>index);i--) b[i] = b[i-1]; b[index] = *pt; } int insertInPointListAt(PointList *p,Point *pt, int index) { pointNode *s, *g; int sum = 0; int t = 1; int base; if (pt->pen == SKIP) return 1; if (index > p->quantity) return 0; if (index == p->quantity) return addToPointList(p,pt); for(s = p->head;(t);) { sum = sum + s->contains; if (index < sum) t = 0; else { g = s; s= s->next; } } if (s) { base = sum - s->contains; if (s->contains == BLOCKSIZE) { /* can't insert to s->block (cause it's full.) */ if (s->next) { /* another node exists */ if (s->next->contains == BLOCKSIZE) {/* can't do next node either. */ /* so we insert a node. */ g = s->next; s->next = (pointNode *)malloc(sizeof(pointNode)); if (!(s->next)) return 0; s->next->block[0] = s->block[(BLOCKSIZE-1)]; s->next->next = g; s->next->contains = 1; insertpointat(s->block,(index-base),(s->contains),pt); } else { insertpointat(s->next->block,0,s->next->contains,&(s->block[BLOCKSIZE-1])); insertpointat(s->block,(index-base),s->contains,pt); (s->next->contains)++; } } else { /* s is full, s is tail. */ g = (pointNode *)malloc(sizeof(pointNode)); if (!(g)) return 0; g->block[0] = s->block[(BLOCKSIZE-1)]; g->contains = 1; g->next = NULL; s->next = g; p->tail = g; insertpointat(s->block,(index-base),s->contains,pt); } } else { /* ok to insert to s->block. */ insertpointat(s->block,(index-base),s->contains,pt); (s->contains)++; } } else return 0; p->quantity++; return 1; } int gotoPointInList(PointList *p,int index,Point **pt) { int total = 0; pointNode *n; int t=1; int base; if ((index >= p->quantity) || (index <0)) return 0; for(n=p->head;(t);) { total = total + n->contains; if (total > index) t = 0; else n = n->next; } base = total - n->contains; *pt = &(n->block[(index-base)]); p->curr = n; p->currpos = (index-base); p->currtot = index; return 1; } int gotoNextPointInList(PointList *p, Point **pt) { if (p->currtot >= (p->quantity-1)) return 0; if ((p->currpos+1) == p->curr->contains) { p->curr = p->curr->next; if (!(p->curr)) return 0; else { p->currpos = 0; *pt = &(p->curr->block[0]); } } else { if (!(p->curr)) return 0; *pt = &(p->curr->block[++(p->currpos)]); } p->currtot++; return 1; } int lastPointInList(PointList *p, Point **pt) { if (p->quantity == 0) return 0; *pt = &(p->tail->block[p->tail->contains-1]); return 1; } void doTestShape(PointList *p) { Point pt; pt.pencolour = NX_BLACK; pt.pen = DOWN; pt.x = 0.3; pt.y = 0.3; addToPointList(p,&pt); pt.x = -0.3; addToPointList(p,&pt); pt.y = -0.3; addToPointList(p,&pt); pt.x = 0.3; addToPointList(p,&pt); pt.y = -0.1; addToPointList(p,&pt); pt.x = 0.1; pt.pen = UP; addToPointList(p,&pt); } int savePointList(PointList *p,char *fn) { FILE *fp; int t; Point *pt; /* attempt to write the PointList. */ fp = fopen(fn,"w"); if (fp) { for(t=gotoPointInList(p,0,&pt);t;t=gotoNextPointInList(p,&pt)) fprintf(fp,"%f %f %d %f\n",pt->x,pt->y,pt->pen,pt->pencolour); fclose(fp); return 1; } else return 0; } int loadPointList(PointList *p,char *fn) { FILE *fp; Point pt; int t; fp = fopen(fn,"r"); if (fp) { for(t = fscanf(fp,"%f %f %d %f\n",&(pt.x),&(pt.y),&(pt.pen),&(pt.pencolour)); (t == 4); t = fscanf(fp,"%f %f %d %f\n",&(pt.x),&(pt.y),&(pt.pen),&(pt.pencolour))) addToPointList(p,&pt); fclose(fp); return 1; } else return 0; } int nearestPointInList(PointList *p,Point **pt,float x,float y,int *index) { int s; Point *pt2; float dist,mindist; int counter; if (p->quantity == 0) return 0; counter = 0; s = gotoPointInList(p,0,&pt2); mindist = ((x - pt2->x) * (x - pt2->x)) + ((y - pt2->y) * (y - pt2->y)); *pt = pt2; *index = counter; for(s=gotoNextPointInList(p,&pt2);s;s=gotoNextPointInList(p,&pt2)) { counter++; dist = (((x - pt2->x) * (x - pt2->x)) + ((y - pt2->y) * (y - pt2->y))); if (dist < mindist) { *pt = pt2; *index = counter; mindist = dist; } } return 1; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.