symbol.c (3310B)
1 #include <u.h> 2 #include <libc.h> 3 #include <stdio.h> 4 #include "map.h" 5 #include "iplot.h" 6 7 #define NSYMBOL 20 8 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]; 15 16 static int nsymbol; 17 static double halfrange = 1; 18 extern int halfwidth; 19 extern int vflag; 20 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 *); 25 26 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 } 37 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; 101 } 102 103 static int 104 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 } 117 118 /* r=0 upright;=1 normal;=-1 reverse*/ 119 int 120 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 } 151 152 static double rot[2][2]; 153 154 static void 155 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 } 186 187 static void 188 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 }