Blame


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