143 lines · 2.5 KB · C
RawDownload
#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; voidorient(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);} voidlatlon(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);} voiddeg2rad(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 doublecirmod(double theta){	while(theta >= 180.)		theta -= 360;	while(theta<-180.)		theta += 360.;	return(theta);} voidsincos(struct coord *coord){	coord->s = sin(coord->l);	coord->c = cos(coord->l);} voidnormalize(struct place *gg){	norm(gg,&pole,&twist);} voidinvert(struct place *g){	norm(g,&ipole,&itwist);} voidnorm(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;} doubletan(double x){	return(sin(x)/cos(x));} voidprintp(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);} voidcopyplace(struct place *g1, struct place *g2){	*g2 = *g1;}