xref: /plan9-contrib/sys/src/cmd/map/libmap/perspective.c (revision 59cc4ca53493a3c6d2349fe2b7f7c40f7dce7294)
1*59cc4ca5SDavid du Colombier #include <u.h>
2*59cc4ca5SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include "map.h"
43e12c5d1SDavid du Colombier 
5219b2ee8SDavid du Colombier #define ORTHRAD 1000
6219b2ee8SDavid du Colombier static double viewpt;
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier static int
Xperspective(struct place * place,double * x,double * y)9219b2ee8SDavid du Colombier Xperspective(struct place *place, double *x, double *y)
103e12c5d1SDavid du Colombier {
11219b2ee8SDavid du Colombier 	double r;
12219b2ee8SDavid du Colombier 	if(viewpt<=1+FUZZ && fabs(place->nlat.s<=viewpt+.01))
133e12c5d1SDavid du Colombier 		return(-1);
143e12c5d1SDavid du Colombier 	r = place->nlat.c*(viewpt - 1.)/(viewpt - place->nlat.s);
153e12c5d1SDavid du Colombier 	*x = - r*place->wlon.s;
163e12c5d1SDavid du Colombier 	*y = - r*place->wlon.c;
173e12c5d1SDavid du Colombier 	if(r>4.)
18219b2ee8SDavid du Colombier 		return(-1);
19219b2ee8SDavid du Colombier 	if(fabs(viewpt)>1 && place->nlat.s<1/viewpt ||
20219b2ee8SDavid du Colombier 	   fabs(viewpt)<=1 && place->nlat.s<viewpt)
21219b2ee8SDavid du Colombier 			return 0;
223e12c5d1SDavid du Colombier 	return(1);
233e12c5d1SDavid du Colombier }
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier proj
perspective(double radius)26219b2ee8SDavid du Colombier perspective(double radius)
273e12c5d1SDavid du Colombier {
283e12c5d1SDavid du Colombier 	viewpt = radius;
29219b2ee8SDavid du Colombier 	if(viewpt >= ORTHRAD)
303e12c5d1SDavid du Colombier 		return(Xorthographic);
31219b2ee8SDavid du Colombier 	if(fabs(viewpt-1.)<.0001)
323e12c5d1SDavid du Colombier 		return(0);
333e12c5d1SDavid du Colombier 	return(Xperspective);
343e12c5d1SDavid du Colombier }
353e12c5d1SDavid du Colombier 
36219b2ee8SDavid du Colombier 	/* called from various conformal projections,
37219b2ee8SDavid du Colombier            but not from stereographic itself */
38219b2ee8SDavid du Colombier int
Xstereographic(struct place * place,double * x,double * y)39219b2ee8SDavid du Colombier Xstereographic(struct place *place, double *x, double *y)
40219b2ee8SDavid du Colombier {
41219b2ee8SDavid du Colombier 	double v = viewpt;
42219b2ee8SDavid du Colombier 	int retval;
43219b2ee8SDavid du Colombier 	viewpt = -1;
44219b2ee8SDavid du Colombier 	retval = Xperspective(place, x, y);
45219b2ee8SDavid du Colombier 	viewpt = v;
46219b2ee8SDavid du Colombier 	return retval;
47219b2ee8SDavid du Colombier }
48219b2ee8SDavid du Colombier 
493e12c5d1SDavid du Colombier proj
stereographic(void)503e12c5d1SDavid du Colombier stereographic(void)
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier 	viewpt = -1.;
533e12c5d1SDavid du Colombier 	return(Xperspective);
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier 
563e12c5d1SDavid du Colombier proj
gnomonic(void)573e12c5d1SDavid du Colombier gnomonic(void)
583e12c5d1SDavid du Colombier {
593e12c5d1SDavid du Colombier 	viewpt = 0.;
603e12c5d1SDavid du Colombier 	return(Xperspective);
613e12c5d1SDavid du Colombier }
62219b2ee8SDavid du Colombier 
63219b2ee8SDavid du Colombier int
plimb(double * lat,double * lon,double res)64219b2ee8SDavid du Colombier plimb(double *lat, double *lon, double res)
65219b2ee8SDavid du Colombier {
66219b2ee8SDavid du Colombier 	static first = 1;
67219b2ee8SDavid du Colombier 	if(viewpt >= ORTHRAD)
68219b2ee8SDavid du Colombier 		return olimb(lat, lon, res);
69219b2ee8SDavid du Colombier 	if(first) {
70219b2ee8SDavid du Colombier 		first = 0;
71219b2ee8SDavid du Colombier 		*lon = -180;
72219b2ee8SDavid du Colombier 		if(fabs(viewpt) < .01)
73219b2ee8SDavid du Colombier 			*lat = 0;
74219b2ee8SDavid du Colombier 		else if(fabs(viewpt)<=1)
75219b2ee8SDavid du Colombier 			*lat = asin(viewpt)/RAD;
76219b2ee8SDavid du Colombier 		else
77219b2ee8SDavid du Colombier 			*lat = asin(1/viewpt)/RAD;
78219b2ee8SDavid du Colombier 	} else
79219b2ee8SDavid du Colombier 		*lon += res;
80219b2ee8SDavid du Colombier 	if(*lon <= 180)
81219b2ee8SDavid du Colombier 		return 1;
82219b2ee8SDavid du Colombier 	first = 1;
83219b2ee8SDavid du Colombier 	return -1;
84219b2ee8SDavid du Colombier }
85