|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <stdio.h> | 
|  | #include "map.h" | 
|  |  | 
|  | static double cirmod(double); | 
|  |  | 
|  | static struct place pole;	/* map pole is tilted to here */ | 
|  | static struct coord twist;	/* then twisted this much */ | 
|  | static struct place ipole;	/* inverse transfrom */ | 
|  | static struct coord itwist; | 
|  |  | 
|  | void | 
|  | orient(double lat, double lon, double theta) | 
|  | { | 
|  | lat = cirmod(lat); | 
|  | if(lat>90.) { | 
|  | lat = 180. - lat; | 
|  | lon -= 180.; | 
|  | theta -= 180.; | 
|  | } else if(lat < -90.) { | 
|  | lat = -180. - lat; | 
|  | lon -= 180.; | 
|  | theta -= 180; | 
|  | } | 
|  | latlon(lat,lon,&pole); | 
|  | deg2rad(theta, &twist); | 
|  | latlon(lat,180.-theta,&ipole); | 
|  | deg2rad(180.-lon, &itwist); | 
|  | } | 
|  |  | 
|  | void | 
|  | latlon(double lat, double lon, struct place *p) | 
|  | { | 
|  | lat = cirmod(lat); | 
|  | if(lat>90.) { | 
|  | lat = 180. - lat; | 
|  | lon -= 180.; | 
|  | } else if(lat < -90.) { | 
|  | lat = -180. - lat; | 
|  | lon -= 180.; | 
|  | } | 
|  | deg2rad(lat,&p->nlat); | 
|  | deg2rad(lon,&p->wlon); | 
|  | } | 
|  |  | 
|  | void | 
|  | deg2rad(double theta, struct coord *coord) | 
|  | { | 
|  | theta = cirmod(theta); | 
|  | coord->l = theta*RAD; | 
|  | if(theta==90) { | 
|  | coord->s = 1; | 
|  | coord->c = 0; | 
|  | } else if(theta== -90) { | 
|  | coord->s = -1; | 
|  | coord->c = 0; | 
|  | } else | 
|  | sincos(coord); | 
|  | } | 
|  |  | 
|  | static double | 
|  | cirmod(double theta) | 
|  | { | 
|  | while(theta >= 180.) | 
|  | theta -= 360; | 
|  | while(theta<-180.) | 
|  | theta += 360.; | 
|  | return(theta); | 
|  | } | 
|  |  | 
|  | void | 
|  | sincos(struct coord *coord) | 
|  | { | 
|  | coord->s = sin(coord->l); | 
|  | coord->c = cos(coord->l); | 
|  | } | 
|  |  | 
|  | void | 
|  | normalize(struct place *gg) | 
|  | { | 
|  | norm(gg,&pole,&twist); | 
|  | } | 
|  |  | 
|  | void | 
|  | invert(struct place *g) | 
|  | { | 
|  | norm(g,&ipole,&itwist); | 
|  | } | 
|  |  | 
|  | void | 
|  | norm(struct place *gg, struct place *pp, struct coord *tw) | 
|  | { | 
|  | register struct place *g;	/*geographic coords */ | 
|  | register struct place *p;	/* new pole in old coords*/ | 
|  | struct place m;			/* standard map coords*/ | 
|  | g = gg; | 
|  | p = pp; | 
|  | if(p->nlat.s == 1.) { | 
|  | if(p->wlon.l+tw->l == 0.) | 
|  | return; | 
|  | g->wlon.l -= p->wlon.l+tw->l; | 
|  | } else { | 
|  | if(p->wlon.l != 0) { | 
|  | g->wlon.l -= p->wlon.l; | 
|  | sincos(&g->wlon); | 
|  | } | 
|  | m.nlat.s = p->nlat.s * g->nlat.s | 
|  | + p->nlat.c * g->nlat.c * g->wlon.c; | 
|  | m.nlat.c = sqrt(1. - m.nlat.s * m.nlat.s); | 
|  | m.nlat.l = atan2(m.nlat.s, m.nlat.c); | 
|  | m.wlon.s = g->nlat.c * g->wlon.s; | 
|  | m.wlon.c = p->nlat.c * g->nlat.s | 
|  | - p->nlat.s * g->nlat.c * g->wlon.c; | 
|  | m.wlon.l = atan2(m.wlon.s, - m.wlon.c) | 
|  | - tw->l; | 
|  | *g = m; | 
|  | } | 
|  | sincos(&g->wlon); | 
|  | if(g->wlon.l>PI) | 
|  | g->wlon.l -= 2*PI; | 
|  | else if(g->wlon.l<-PI) | 
|  | g->wlon.l += 2*PI; | 
|  | } | 
|  |  | 
|  | void | 
|  | printp(struct place *g) | 
|  | { | 
|  | printf("%.3f %.3f %.3f %.3f %.3f %.3f\n", | 
|  | g->nlat.l,g->nlat.s,g->nlat.c,g->wlon.l,g->wlon.s,g->wlon.c); | 
|  | } | 
|  |  | 
|  | void | 
|  | copyplace(struct place *g1, struct place *g2) | 
|  | { | 
|  | *g2 = *g1; | 
|  | } |