xref: /plan9-contrib/sys/src/cmd/map/libmap/zcoord.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "map.h"
2 
3 static double cirmod(double);
4 
5 static struct place pole;	/* map pole is tilted to here */
6 static struct coord twist;	/* then twisted this much */
7 static struct place ipole;	/* inverse transfrom */
8 static struct coord itwist;
9 
10 void
11 orient(double lat, double lon, double theta)
12 {
13 	lat = cirmod(lat);
14 	if(lat>90.) {
15 		lat = 180. - lat;
16 		lon -= 180.;
17 		theta -= 180.;
18 	} else if(lat < -90.) {
19 		lat = -180. - lat;
20 		lon -= 180.;
21 		theta -= 180;
22 	}
23 	latlon(lat,lon,&pole);
24 	deg2rad(theta, &twist);
25 	latlon(lat,180.-theta,&ipole);
26 	deg2rad(180.-lon, &itwist);
27 }
28 
29 void
30 latlon(double lat, double lon, struct place *p)
31 {
32 	lat = cirmod(lat);
33 	if(lat>90.) {
34 		lat = 180. - lat;
35 		lon -= 180.;
36 	} else if(lat < -90.) {
37 		lat = -180. - lat;
38 		lon -= 180.;
39 	}
40 	deg2rad(lat,&p->nlat);
41 	deg2rad(lon,&p->wlon);
42 }
43 
44 void
45 deg2rad(double theta, struct coord *coord)
46 {
47 	theta = cirmod(theta);
48 	coord->l = theta*RAD;
49 	if(theta==90) {
50 		coord->s = 1;
51 		coord->c = 0;
52 	} else if(theta== -90) {
53 		coord->s = -1;
54 		coord->c = 0;
55 	} else
56 		sincos(coord);
57 }
58 
59 static double
60 cirmod(double theta)
61 {
62 	while(theta >= 180.)
63 		theta -= 360;
64 	while(theta<-180.)
65 		theta += 360.;
66 	return(theta);
67 }
68 
69 void
70 sincos(struct coord *coord)
71 {
72 	coord->s = sin(coord->l);
73 	coord->c = cos(coord->l);
74 }
75 
76 void
77 normalize(struct place *gg)
78 {
79 	norm(gg,&pole,&twist);
80 }
81 
82 void
83 invert(struct place *g)
84 {
85 	norm(g,&ipole,&itwist);
86 }
87 
88 void
89 norm(struct place *gg, struct place *pp, struct coord *tw)
90 {
91 	register struct place *g;	/*geographic coords */
92 	register struct place *p;	/* new pole in old coords*/
93 	struct place m;			/* standard map coords*/
94 	g = gg;
95 	p = pp;
96 	if(p->nlat.s == 1.) {
97 		if(p->wlon.l+tw->l == 0.)
98 			return;
99 		g->wlon.l -= p->wlon.l+tw->l;
100 	} else {
101 		if(p->wlon.l != 0) {
102 			g->wlon.l -= p->wlon.l;
103 			sincos(&g->wlon);
104 		}
105 		m.nlat.s = p->nlat.s * g->nlat.s
106 			+ p->nlat.c * g->nlat.c * g->wlon.c;
107 		m.nlat.c = sqrt(1. - m.nlat.s * m.nlat.s);
108 		m.nlat.l = atan2(m.nlat.s, m.nlat.c);
109 		m.wlon.s = g->nlat.c * g->wlon.s;
110 		m.wlon.c = p->nlat.c * g->nlat.s
111 			- p->nlat.s * g->nlat.c * g->wlon.c;
112 		m.wlon.l = atan2(m.wlon.s, - m.wlon.c)
113 			- tw->l;
114 		*g = m;
115 	}
116 	sincos(&g->wlon);
117 	if(g->wlon.l>PI)
118 		g->wlon.l -= 2*PI;
119 	else if(g->wlon.l<-PI)
120 		g->wlon.l += 2*PI;
121 }
122 
123 double
124 tan(double x)
125 {
126 	return(sin(x)/cos(x));
127 }
128 
129 void
130 printp(struct place *g)
131 {
132 printf("%.3f %.3f %.3f %.3f %.3f %.3f\n",
133 g->nlat.l,g->nlat.s,g->nlat.c,g->wlon.l,g->wlon.s,g->wlon.c);
134 }
135 
136 void
137 copyplace(struct place *g1, struct place *g2)
138 {
139 	*g2 = *g1;
140 }
141