Blob


1 #include <u.h>
2 #include <libc.h>
3 #include "map.h"
5 static double
6 quadratic(double a, double b, double c)
7 {
8 double disc = b*b - 4*a*c;
9 return disc<0? 0: (-b-sqrt(disc))/(2*a);
10 }
12 /* for projections with meridians being circles centered
13 on the x axis and parallels being circles centered on the y
14 axis. Find the intersection of the meridian thru (m,0), (90,0),
15 with the parallel thru (0,p), (p1,p2) */
17 static int
18 twocircles(double m, double p, double p1, double p2, double *x, double *y)
19 {
20 double a; /* center of meridian circle, a>0 */
21 double b; /* center of parallel circle, b>0 */
22 double t,bb;
23 if(m > 0) {
24 twocircles(-m,p,p1,p2,x,y);
25 *x = -*x;
26 } else if(p < 0) {
27 twocircles(m,-p,p1,-p2,x,y);
28 *y = -*y;
29 } else if(p < .01) {
30 *x = m;
31 t = m/p1;
32 *y = p + (p2-p)*t*t;
33 } else if(m > -.01) {
34 *y = p;
35 *x = m - m*p*p;
36 } else {
37 b = p>=1? 1: p>.99? 0.5*(p+1 + p1*p1/(1-p)):
38 0.5*(p*p-p1*p1-p2*p2)/(p-p2);
39 a = .5*(m - 1/m);
40 t = m*m-p*p+2*(b*p-a*m);
41 bb = b*b;
42 *x = quadratic(1+a*a/bb, -2*a + a*t/bb,
43 t*t/(4*bb) - m*m + 2*a*m);
44 *y = (*x*a+t/2)/b;
45 }
46 return 1;
47 }
49 static int
50 Xglobular(struct place *place, double *x, double *y)
51 {
52 twocircles(-2*place->wlon.l/PI,
53 2*place->nlat.l/PI, place->nlat.c, place->nlat.s, x, y);
54 return 1;
55 }
57 proj
58 globular(void)
59 {
60 return Xglobular;
61 }
63 static int
64 Xvandergrinten(struct place *place, double *x, double *y)
65 {
66 double t = 2*place->nlat.l/PI;
67 double abst = fabs(t);
68 double pval = abst>=1? 1: abst/(1+sqrt(1-t*t));
69 double p2 = 2*pval/(1+pval);
70 twocircles(-place->wlon.l/PI, pval, sqrt(1-p2*p2), p2, x, y);
71 if(t < 0)
72 *y = -*y;
73 return 1;
74 }
76 proj
77 vandergrinten(void)
78 {
79 return Xvandergrinten;
80 }