Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <stdio.h>
4 #include "map.h"
5 #include "iplot.h"
7 #define NSYMBOL 20
9 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 void
28 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 int
39 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 else
99 symbol[n] = 0;
100 return 1;
103 static int
104 getrange(FILE *sf)
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;
118 /* r=0 upright;=1 normal;=-1 reverse*/
119 int
120 putsym(struct place *p, char *name, double s, int r)
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;
147 break;
149 return 1;
152 static double rot[2][2];
154 static void
155 setrot(struct place *p, double s, int r)
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;
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;
187 static void
188 dorot(struct symb *sp, double *px, double *py)
190 *px = rot[0][0]*sp->x + rot[0][1]*sp->y;
191 *py = rot[1][0]*sp->x + rot[1][1]*sp->y;