aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/map/libmap/perspective.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/map/libmap/perspective.c')
-rw-r--r--src/cmd/map/libmap/perspective.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/cmd/map/libmap/perspective.c b/src/cmd/map/libmap/perspective.c
new file mode 100644
index 00000000..7ce6b0d6
--- /dev/null
+++ b/src/cmd/map/libmap/perspective.c
@@ -0,0 +1,84 @@
+#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;
+}