138 lines
2.4 KiB
C
138 lines
2.4 KiB
C
#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;
|
|
}
|