URI:
       tsymbol.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tsymbol.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 }