/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #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 *); voidgetsyms(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 intgetsymbol(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 intgetrange(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*/intputsym(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 voidsetrot(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 voiddorot(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;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#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;
}