xref: /plan9/sys/src/cmd/map/symbol.c (revision 59cc4ca53493a3c6d2349fe2b7f7c40f7dce7294)
1*59cc4ca5SDavid du Colombier #include <u.h>
2*59cc4ca5SDavid du Colombier #include <libc.h>
3*59cc4ca5SDavid du Colombier #include <stdio.h>
43e12c5d1SDavid du Colombier #include "map.h"
57dd7cddfSDavid du Colombier #include "iplot.h"
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier #define NSYMBOL 20
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier enum flag { POINT,ENDSEG,ENDSYM };
103e12c5d1SDavid du Colombier struct symb {
11219b2ee8SDavid du Colombier 	double x, y;
123e12c5d1SDavid du Colombier 	char name[10+1];
133e12c5d1SDavid du Colombier 	enum flag flag;
143e12c5d1SDavid du Colombier } *symbol[NSYMBOL];
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier static int nsymbol;
17219b2ee8SDavid du Colombier static double halfrange = 1;
183e12c5d1SDavid du Colombier extern int halfwidth;
19219b2ee8SDavid du Colombier extern int vflag;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier static int	getrange(FILE *);
223e12c5d1SDavid du Colombier static int	getsymbol(FILE *, int);
233e12c5d1SDavid du Colombier static void	setrot(struct place *, double, int);
24219b2ee8SDavid du Colombier static void	dorot(struct symb *, double *, double *);
253e12c5d1SDavid du Colombier 
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier void
getsyms(char * file)283e12c5d1SDavid du Colombier getsyms(char *file)
293e12c5d1SDavid du Colombier {
303e12c5d1SDavid du Colombier 	FILE *sf = fopen(file,"r");
313e12c5d1SDavid du Colombier 	if(sf==0)
323e12c5d1SDavid du Colombier 		filerror("cannot open", file);
333e12c5d1SDavid du Colombier 	while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))
343e12c5d1SDavid du Colombier 		nsymbol++;
353e12c5d1SDavid du Colombier 	fclose(sf);
363e12c5d1SDavid du Colombier }
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier static int
getsymbol(FILE * sf,int n)393e12c5d1SDavid du Colombier getsymbol(FILE *sf, int n)
403e12c5d1SDavid du Colombier {
41219b2ee8SDavid du Colombier 	double x,y;
423e12c5d1SDavid du Colombier 	char s[2];
433e12c5d1SDavid du Colombier 	int i;
443e12c5d1SDavid du Colombier 	struct symb *sp;
453e12c5d1SDavid du Colombier 	for(;;) {
463e12c5d1SDavid du Colombier 		if(fscanf(sf,"%1s",s)==EOF)
473e12c5d1SDavid du Colombier 			return 0;
483e12c5d1SDavid du Colombier 		switch(s[0]) {
493e12c5d1SDavid du Colombier 		case ':':
503e12c5d1SDavid du Colombier 			break;
513e12c5d1SDavid du Colombier 		case 'o':
523e12c5d1SDavid du Colombier 		case 'c':	/* cl */
533e12c5d1SDavid du Colombier 			fscanf(sf,"%*[^\n]");
543e12c5d1SDavid du Colombier 			continue;
553e12c5d1SDavid du Colombier 		case 'r':
563e12c5d1SDavid du Colombier 			if(getrange(sf))
573e12c5d1SDavid du Colombier 				continue;
583e12c5d1SDavid du Colombier 		default:
593e12c5d1SDavid du Colombier 			error("-y file syntax error");
603e12c5d1SDavid du Colombier 		}
613e12c5d1SDavid du Colombier 		break;
623e12c5d1SDavid du Colombier 	}
633e12c5d1SDavid du Colombier 	sp = (struct symb*)malloc(sizeof(struct symb));
643e12c5d1SDavid du Colombier 	symbol[n] = sp;
653e12c5d1SDavid du Colombier 	if(fscanf(sf,"%10s",sp->name)!=1)
663e12c5d1SDavid du Colombier 		return 0;
673e12c5d1SDavid du Colombier 	i = 0;
683e12c5d1SDavid du Colombier 	while(fscanf(sf,"%1s",s)!=EOF) {
693e12c5d1SDavid du Colombier 		switch(s[0]) {
703e12c5d1SDavid du Colombier 		case 'r':
713e12c5d1SDavid du Colombier 			if(!getrange(sf))
723e12c5d1SDavid du Colombier 				break;
733e12c5d1SDavid du Colombier 			continue;
743e12c5d1SDavid du Colombier 		case 'm':
753e12c5d1SDavid du Colombier 			if(i>0)
763e12c5d1SDavid du Colombier 				symbol[n][i-1].flag = ENDSEG;
773e12c5d1SDavid du Colombier 			continue;
783e12c5d1SDavid du Colombier 		case ':':
793e12c5d1SDavid du Colombier 			ungetc(s[0],sf);
803e12c5d1SDavid du Colombier 			break;
813e12c5d1SDavid du Colombier 		default:
823e12c5d1SDavid du Colombier 			ungetc(s[0],sf);
833e12c5d1SDavid du Colombier 		case 'v':
84219b2ee8SDavid du Colombier 			if(fscanf(sf,"%lf %lf",&x,&y)!=2)
853e12c5d1SDavid du Colombier 				break;
867dd7cddfSDavid du Colombier 			sp[i].x = x*halfwidth/halfrange;
877dd7cddfSDavid du Colombier 			sp[i].y = y*halfwidth/halfrange;
887dd7cddfSDavid du Colombier 			sp[i].flag = POINT;
893e12c5d1SDavid du Colombier 			i++;
907dd7cddfSDavid du Colombier 			sp = symbol[n] = (struct symb*)realloc(symbol[n],
913e12c5d1SDavid du Colombier 					(i+1)*sizeof(struct symb));
923e12c5d1SDavid du Colombier 			continue;
933e12c5d1SDavid du Colombier 		}
943e12c5d1SDavid du Colombier 		break;
953e12c5d1SDavid du Colombier 	}
963e12c5d1SDavid du Colombier 	if(i>0)
973e12c5d1SDavid du Colombier 		symbol[n][i-1].flag = ENDSYM;
983e12c5d1SDavid du Colombier 	else
993e12c5d1SDavid du Colombier 		symbol[n] = 0;
1003e12c5d1SDavid du Colombier 	return 1;
1013e12c5d1SDavid du Colombier }
1023e12c5d1SDavid du Colombier 
1033e12c5d1SDavid du Colombier static int
getrange(FILE * sf)1043e12c5d1SDavid du Colombier getrange(FILE *sf)
1053e12c5d1SDavid du Colombier {
106219b2ee8SDavid du Colombier 	double x,y,xmin,ymin;
107219b2ee8SDavid du Colombier 	if(fscanf(sf,"%*s %lf %lf %lf %lf",
1083e12c5d1SDavid du Colombier 		&xmin,&ymin,&x,&y)!=4)
1093e12c5d1SDavid du Colombier 		return 0;
1103e12c5d1SDavid du Colombier 	x -= xmin;
1113e12c5d1SDavid du Colombier 	y -= ymin;
1123e12c5d1SDavid du Colombier 	halfrange = (x>y? x: y)/2;
1133e12c5d1SDavid du Colombier 	if(halfrange<=0)
1143e12c5d1SDavid du Colombier 		error("bad ra command in -y file");
1153e12c5d1SDavid du Colombier 	return 1;
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier /* r=0 upright;=1 normal;=-1 reverse*/
1193e12c5d1SDavid du Colombier int
putsym(struct place * p,char * name,double s,int r)1203e12c5d1SDavid du Colombier putsym(struct place *p, char *name, double s, int r)
1213e12c5d1SDavid du Colombier {
1223e12c5d1SDavid du Colombier 	int x,y,n;
1233e12c5d1SDavid du Colombier 	struct symb *sp;
124219b2ee8SDavid du Colombier 	double dx,dy;
1253e12c5d1SDavid du Colombier 	int conn = 0;
1263e12c5d1SDavid du Colombier 	for(n=0; symbol[n]; n++)
1273e12c5d1SDavid du Colombier 		if(strcmp(name,symbol[n]->name)==0)
1283e12c5d1SDavid du Colombier 			break;
1293e12c5d1SDavid du Colombier 	sp = symbol[n];
1303e12c5d1SDavid du Colombier 	if(sp==0)
1313e12c5d1SDavid du Colombier 		return 0;
132219b2ee8SDavid du Colombier 	if(doproj(p,&x,&y)*vflag <= 0)
1333e12c5d1SDavid du Colombier 		return 1;
1343e12c5d1SDavid du Colombier 	setrot(p,s,r);
1353e12c5d1SDavid du Colombier 	for(;;) {
1363e12c5d1SDavid du Colombier 		dorot(sp,&dx,&dy);
1373e12c5d1SDavid du Colombier 		conn = cpoint(x+(int)dx,y+(int)dy,conn);
1383e12c5d1SDavid du Colombier 		switch(sp->flag) {
1393e12c5d1SDavid du Colombier 		case ENDSEG:
1403e12c5d1SDavid du Colombier 			conn = 0;
1413e12c5d1SDavid du Colombier 		case POINT:
1423e12c5d1SDavid du Colombier 			sp++;
1433e12c5d1SDavid du Colombier 			continue;
1443e12c5d1SDavid du Colombier 		case ENDSYM:
1453e12c5d1SDavid du Colombier 			break;
1463e12c5d1SDavid du Colombier 		}
1473e12c5d1SDavid du Colombier 		break;
1483e12c5d1SDavid du Colombier 	}
1493e12c5d1SDavid du Colombier 	return 1;
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier 
152219b2ee8SDavid du Colombier static double rot[2][2];
1533e12c5d1SDavid du Colombier 
1543e12c5d1SDavid du Colombier static void
setrot(struct place * p,double s,int r)1553e12c5d1SDavid du Colombier setrot(struct place *p, double s, int r)
1563e12c5d1SDavid du Colombier {
157219b2ee8SDavid du Colombier 	double x0,y0,x1,y1;
1583e12c5d1SDavid du Colombier 	struct place up;
1593e12c5d1SDavid du Colombier 	up = *p;
1603e12c5d1SDavid du Colombier 	up.nlat.l += .5*RAD;
1613e12c5d1SDavid du Colombier 	sincos(&up.nlat);
1623e12c5d1SDavid du Colombier 	if(r&&(*projection)(p,&x0,&y0)) {
1633e12c5d1SDavid du Colombier 		if((*projection)(&up,&x1,&y1)<=0) {
1643e12c5d1SDavid du Colombier 			up.nlat.l -= RAD;
1653e12c5d1SDavid du Colombier 			sincos(&up.nlat);
1663e12c5d1SDavid du Colombier 			if((*projection)(&up,&x1,&y1)<=0)
1673e12c5d1SDavid du Colombier 				goto unit;
1683e12c5d1SDavid du Colombier 			x1 = x0 - x1;
1693e12c5d1SDavid du Colombier 			y1 = y0 - y1;
1703e12c5d1SDavid du Colombier 		} else {
1713e12c5d1SDavid du Colombier 			x1 -= x0;
1723e12c5d1SDavid du Colombier 			y1 -= y0;
1733e12c5d1SDavid du Colombier 		}
1743e12c5d1SDavid du Colombier 		x1 = r*x1;
1753e12c5d1SDavid du Colombier 		s /= hypot(x1,y1);
1763e12c5d1SDavid du Colombier 		rot[0][0] = y1*s;
1773e12c5d1SDavid du Colombier 		rot[0][1] = x1*s;
1783e12c5d1SDavid du Colombier 		rot[1][0] = -x1*s;
1793e12c5d1SDavid du Colombier 		rot[1][1] = y1*s;
1803e12c5d1SDavid du Colombier 	} else {
1813e12c5d1SDavid du Colombier unit:
1823e12c5d1SDavid du Colombier 		rot[0][0] = rot[1][1] = s;
1833e12c5d1SDavid du Colombier 		rot[0][1] = rot[1][0] = 0;
1843e12c5d1SDavid du Colombier 	}
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier static void
dorot(struct symb * sp,double * px,double * py)188219b2ee8SDavid du Colombier dorot(struct symb *sp, double *px, double *py)
1893e12c5d1SDavid du Colombier {
1903e12c5d1SDavid du Colombier 	*px = rot[0][0]*sp->x + rot[0][1]*sp->y;
1913e12c5d1SDavid du Colombier 	*py = rot[1][0]*sp->x + rot[1][1]*sp->y;
1923e12c5d1SDavid du Colombier }
193