Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}