ftp.nice.ch/pub/next/graphics/vector/MapMaker.0.9.N.bs.tar.gz#/MapMaker/pointdata.c

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.