123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #include <u.h>
- #include <libc.h>
- #include <stdio.h>
- #include "map.h"
- #include "iplot.h"
- #define NSYMBOL 20
- enum flag { POINT,ENDSEG,ENDSYM };
- struct symb {
- double x, y;
- char name[10+1];
- enum flag flag;
- } *symbol[NSYMBOL];
- static int nsymbol;
- static double halfrange = 1;
- extern int halfwidth;
- extern int vflag;
- static int getrange(FILE *);
- static int getsymbol(FILE *, int);
- static void setrot(struct place *, double, int);
- static void dorot(struct symb *, double *, double *);
- void
- getsyms(char *file)
- {
- FILE *sf = fopen(file,"r");
- if(sf==0)
- filerror("cannot open", file);
- while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))
- nsymbol++;
- fclose(sf);
- }
- static int
- getsymbol(FILE *sf, int n)
- {
- double x,y;
- char s[2];
- int i;
- struct symb *sp;
- for(;;) {
- if(fscanf(sf,"%1s",s)==EOF)
- return 0;
- switch(s[0]) {
- case ':':
- break;
- case 'o':
- case 'c': /* cl */
- fscanf(sf,"%*[^\n]");
- continue;
- case 'r':
- if(getrange(sf))
- continue;
- default:
- error("-y file syntax error");
- }
- break;
- }
- sp = (struct symb*)malloc(sizeof(struct symb));
- symbol[n] = sp;
- if(fscanf(sf,"%10s",sp->name)!=1)
- return 0;
- i = 0;
- while(fscanf(sf,"%1s",s)!=EOF) {
- switch(s[0]) {
- case 'r':
- if(!getrange(sf))
- break;
- continue;
- case 'm':
- if(i>0)
- symbol[n][i-1].flag = ENDSEG;
- continue;
- case ':':
- ungetc(s[0],sf);
- break;
- default:
- ungetc(s[0],sf);
- case 'v':
- if(fscanf(sf,"%lf %lf",&x,&y)!=2)
- break;
- sp[i].x = x*halfwidth/halfrange;
- sp[i].y = y*halfwidth/halfrange;
- sp[i].flag = POINT;
- i++;
- sp = symbol[n] = (struct symb*)realloc(symbol[n],
- (i+1)*sizeof(struct symb));
- continue;
- }
- break;
- }
- if(i>0)
- symbol[n][i-1].flag = ENDSYM;
- else
- symbol[n] = 0;
- return 1;
- }
- static int
- getrange(FILE *sf)
- {
- double x,y,xmin,ymin;
- if(fscanf(sf,"%*s %lf %lf %lf %lf",
- &xmin,&ymin,&x,&y)!=4)
- return 0;
- x -= xmin;
- y -= ymin;
- halfrange = (x>y? x: y)/2;
- if(halfrange<=0)
- error("bad ra command in -y file");
- return 1;
- }
- /* r=0 upright;=1 normal;=-1 reverse*/
- int
- putsym(struct place *p, char *name, double s, int r)
- {
- int x,y,n;
- struct symb *sp;
- double dx,dy;
- int conn = 0;
- for(n=0; symbol[n]; n++)
- if(strcmp(name,symbol[n]->name)==0)
- break;
- sp = symbol[n];
- if(sp==0)
- return 0;
- if(doproj(p,&x,&y)*vflag <= 0)
- return 1;
- setrot(p,s,r);
- for(;;) {
- dorot(sp,&dx,&dy);
- conn = cpoint(x+(int)dx,y+(int)dy,conn);
- switch(sp->flag) {
- case ENDSEG:
- conn = 0;
- case POINT:
- sp++;
- continue;
- case ENDSYM:
- break;
- }
- break;
- }
- return 1;
- }
- static double rot[2][2];
- static void
- setrot(struct place *p, double s, int r)
- {
- double x0,y0,x1,y1;
- struct place up;
- up = *p;
- up.nlat.l += .5*RAD;
- sincos(&up.nlat);
- if(r&&(*projection)(p,&x0,&y0)) {
- if((*projection)(&up,&x1,&y1)<=0) {
- up.nlat.l -= RAD;
- sincos(&up.nlat);
- if((*projection)(&up,&x1,&y1)<=0)
- goto unit;
- x1 = x0 - x1;
- y1 = y0 - y1;
- } else {
- x1 -= x0;
- y1 -= y0;
- }
- x1 = r*x1;
- s /= hypot(x1,y1);
- rot[0][0] = y1*s;
- rot[0][1] = x1*s;
- rot[1][0] = -x1*s;
- rot[1][1] = y1*s;
- } else {
- unit:
- rot[0][0] = rot[1][1] = s;
- rot[0][1] = rot[1][0] = 0;
- }
- }
- static void
- dorot(struct symb *sp, double *px, double *py)
- {
- *px = rot[0][0]*sp->x + rot[0][1]*sp->y;
- *py = rot[1][0]*sp->x + rot[1][1]*sp->y;
- }
|