Blob
1 #include <u.h>2 #include <libc.h>3 #include <stdio.h>4 #include "map.h"5 #include "iplot.h"7 #define NSYMBOL 209 enum flag { POINT,ENDSEG,ENDSYM };10 struct symb {11 double x, y;12 char name[10+1];13 enum flag flag;14 } *symbol[NSYMBOL];16 static int nsymbol;17 static double halfrange = 1;18 extern int halfwidth;19 extern int vflag;21 static int getrange(FILE *);22 static int getsymbol(FILE *, int);23 static void setrot(struct place *, double, int);24 static void dorot(struct symb *, double *, double *);27 void28 getsyms(char *file)29 {30 FILE *sf = fopen(file,"r");31 if(sf==0)32 filerror("cannot open", file);33 while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))34 nsymbol++;35 fclose(sf);36 }38 static int39 getsymbol(FILE *sf, int n)40 {41 double x,y;42 char s[2];43 int i;44 struct symb *sp;45 for(;;) {46 if(fscanf(sf,"%1s",s)==EOF)47 return 0;48 switch(s[0]) {49 case ':':50 break;51 case 'o':52 case 'c': /* cl */53 fscanf(sf,"%*[^\n]");54 continue;55 case 'r':56 if(getrange(sf))57 continue;58 default:59 error("-y file syntax error");60 }61 break;62 }63 sp = (struct symb*)malloc(sizeof(struct symb));64 symbol[n] = sp;65 if(fscanf(sf,"%10s",sp->name)!=1)66 return 0;67 i = 0;68 while(fscanf(sf,"%1s",s)!=EOF) {69 switch(s[0]) {70 case 'r':71 if(!getrange(sf))72 break;73 continue;74 case 'm':75 if(i>0)76 symbol[n][i-1].flag = ENDSEG;77 continue;78 case ':':79 ungetc(s[0],sf);80 break;81 default:82 ungetc(s[0],sf);83 case 'v':84 if(fscanf(sf,"%lf %lf",&x,&y)!=2)85 break;86 sp[i].x = x*halfwidth/halfrange;87 sp[i].y = y*halfwidth/halfrange;88 sp[i].flag = POINT;89 i++;90 sp = symbol[n] = (struct symb*)realloc(symbol[n],91 (i+1)*sizeof(struct symb));92 continue;93 }94 break;95 }96 if(i>0)97 symbol[n][i-1].flag = ENDSYM;98 else99 symbol[n] = 0;100 return 1;101 }103 static int104 getrange(FILE *sf)105 {106 double x,y,xmin,ymin;107 if(fscanf(sf,"%*s %lf %lf %lf %lf",108 &xmin,&ymin,&x,&y)!=4)109 return 0;110 x -= xmin;111 y -= ymin;112 halfrange = (x>y? x: y)/2;113 if(halfrange<=0)114 error("bad ra command in -y file");115 return 1;116 }118 /* r=0 upright;=1 normal;=-1 reverse*/119 int120 putsym(struct place *p, char *name, double s, int r)121 {122 int x,y,n;123 struct symb *sp;124 double dx,dy;125 int conn = 0;126 for(n=0; symbol[n]; n++)127 if(strcmp(name,symbol[n]->name)==0)128 break;129 sp = symbol[n];130 if(sp==0)131 return 0;132 if(doproj(p,&x,&y)*vflag <= 0)133 return 1;134 setrot(p,s,r);135 for(;;) {136 dorot(sp,&dx,&dy);137 conn = cpoint(x+(int)dx,y+(int)dy,conn);138 switch(sp->flag) {139 case ENDSEG:140 conn = 0;141 case POINT:142 sp++;143 continue;144 case ENDSYM:145 break;146 }147 break;148 }149 return 1;150 }152 static double rot[2][2];154 static void155 setrot(struct place *p, double s, int r)156 {157 double x0,y0,x1,y1;158 struct place up;159 up = *p;160 up.nlat.l += .5*RAD;161 sincos(&up.nlat);162 if(r&&(*projection)(p,&x0,&y0)) {163 if((*projection)(&up,&x1,&y1)<=0) {164 up.nlat.l -= RAD;165 sincos(&up.nlat);166 if((*projection)(&up,&x1,&y1)<=0)167 goto unit;168 x1 = x0 - x1;169 y1 = y0 - y1;170 } else {171 x1 -= x0;172 y1 -= y0;173 }174 x1 = r*x1;175 s /= hypot(x1,y1);176 rot[0][0] = y1*s;177 rot[0][1] = x1*s;178 rot[1][0] = -x1*s;179 rot[1][1] = y1*s;180 } else {181 unit:182 rot[0][0] = rot[1][1] = s;183 rot[0][1] = rot[1][0] = 0;184 }185 }187 static void188 dorot(struct symb *sp, double *px, double *py)189 {190 *px = rot[0][0]*sp->x + rot[0][1]*sp->y;191 *py = rot[1][0]*sp->x + rot[1][1]*sp->y;192 }