#include <u.h>
#include <libc.h>
#include "map.h"
#define ORTHRAD 1000
static double viewpt;
static int
Xperspective(struct place *place, double *x, double *y)
{
double r;
if(viewpt<=1+FUZZ && fabs(place->nlat.s<=viewpt+.01))
return(-1);
r = place->nlat.c*(viewpt - 1.)/(viewpt - place->nlat.s);
*x = - r*place->wlon.s;
*y = - r*place->wlon.c;
if(r>4.)
return(-1);
if(fabs(viewpt)>1 && place->nlat.s<1/viewpt ||
fabs(viewpt)<=1 && place->nlat.s<viewpt)
return 0;
return(1);
}
proj
perspective(double radius)
{
viewpt = radius;
if(viewpt >= ORTHRAD)
return(Xorthographic);
if(fabs(viewpt-1.)<.0001)
return(0);
return(Xperspective);
}
/* called from various conformal projections,
but not from stereographic itself */
int
Xstereographic(struct place *place, double *x, double *y)
{
double v = viewpt;
int retval;
viewpt = -1;
retval = Xperspective(place, x, y);
viewpt = v;
return retval;
}
proj
stereographic(void)
{
viewpt = -1.;
return(Xperspective);
}
proj
gnomonic(void)
{
viewpt = 0.;
return(Xperspective);
}
int
plimb(double *lat, double *lon, double res)
{
static first = 1;
if(viewpt >= ORTHRAD)
return olimb(lat, lon, res);
if(first) {
first = 0;
*lon = -180;
if(fabs(viewpt) < .01)
*lat = 0;
else if(fabs(viewpt)<=1)
*lat = asin(viewpt)/RAD;
else
*lat = asin(1/viewpt)/RAD;
} else
*lon += res;
if(*lon <= 180)
return 1;
first = 1;
return -1;
}
|