| #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 int 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; |
| } |