Why not?
This commit is contained in:
parent
a01e58366c
commit
28994509cc
82 changed files with 13293 additions and 0 deletions
88
src/cmd/map/index.c
Normal file
88
src/cmd/map/index.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static proj Yaitoff(double p0, double p1){USED(p0); USED(p1); return aitoff();}
|
||||
static proj Yalbers(double p0,double p1){USED(p0); USED(p1); return albers(p0,p1);}
|
||||
static proj Yazequalarea(double p0, double p1){USED(p0); USED(p1); return azequalarea();}
|
||||
static proj Yazequidistant(double p0, double p1){USED(p0); USED(p1); return azequidistant();}
|
||||
static proj Ybicentric(double p0,double p1){USED(p0); USED(p1); return bicentric(p0);}
|
||||
static proj Ybonne(double p0,double p1){USED(p0); USED(p1); return bonne(p0);}
|
||||
static proj Yconic(double p0,double p1){USED(p0); USED(p1); return conic(p0);}
|
||||
static proj Ycylequalarea(double p0,double p1){USED(p0); USED(p1); return cylequalarea(p0);}
|
||||
static proj Ycylindrical(double p0, double p1){USED(p0); USED(p1); return cylindrical();}
|
||||
static proj Yelliptic(double p0,double p1){USED(p0); USED(p1); return elliptic(p0);}
|
||||
static proj Yfisheye(double p0,double p1){USED(p0); USED(p1); return fisheye(p0);}
|
||||
static proj Ygall(double p0,double p1){USED(p0); USED(p1); return gall(p0);}
|
||||
static proj Ygilbert(double p0, double p1){USED(p0); USED(p1); return gilbert();}
|
||||
static proj Yglobular(double p0, double p1){USED(p0); USED(p1); return globular();}
|
||||
static proj Ygnomonic(double p0, double p1){USED(p0); USED(p1); return gnomonic();}
|
||||
static proj Yguyou(double p0, double p1){USED(p0); USED(p1); return guyou();}
|
||||
static proj Yharrison(double p0,double p1){USED(p0); USED(p1); return harrison(p0,p1);}
|
||||
static proj Yhex(double p0, double p1){USED(p0); USED(p1); return hex();}
|
||||
static proj Yhoming(double p0,double p1){USED(p0); USED(p1); return homing(p0);}
|
||||
static proj Ylagrange(double p0, double p1){USED(p0); USED(p1); return lagrange();}
|
||||
static proj Ylambert(double p0,double p1){USED(p0); USED(p1); return lambert(p0,p1);}
|
||||
static proj Ylaue(double p0, double p1){USED(p0); USED(p1); return laue();}
|
||||
static proj Ylune(double p0,double p1){USED(p0); USED(p1); return lune(p0,p1);}
|
||||
static proj Ymecca(double p0, double p1){USED(p0); USED(p1); return mecca(p0);}
|
||||
static proj Ymercator(double p0, double p1){USED(p0); USED(p1); return mercator();}
|
||||
static proj Ymollweide(double p0, double p1){USED(p0); USED(p1); return mollweide();}
|
||||
static proj Ynewyorker(double p0,double p1){USED(p0); USED(p1); return newyorker(p0);}
|
||||
static proj Yorthographic(double p0, double p1){USED(p0); USED(p1); return orthographic();}
|
||||
static proj Yperspective(double p0,double p1){USED(p0); USED(p1); return perspective(p0);}
|
||||
static proj Ypolyconic(double p0, double p1){USED(p0); USED(p1); return polyconic();}
|
||||
static proj Yrectangular(double p0,double p1){USED(p0); USED(p1); return rectangular(p0);}
|
||||
static proj Ysimpleconic(double p0,double p1){USED(p0); USED(p1); return simpleconic(p0,p1);}
|
||||
static proj Ysinusoidal(double p0, double p1){USED(p0); USED(p1); return sinusoidal();}
|
||||
static proj Ysp_albers(double p0,double p1){USED(p0); USED(p1); return sp_albers(p0,p1);}
|
||||
static proj Ysp_mercator(double p0, double p1){USED(p0); USED(p1); return sp_mercator();}
|
||||
static proj Ysquare(double p0, double p1){USED(p0); USED(p1); return square();}
|
||||
static proj Ystereographic(double p0, double p1){USED(p0); USED(p1); return stereographic();}
|
||||
static proj Ytetra(double p0, double p1){USED(p0); USED(p1); return tetra();}
|
||||
static proj Ytrapezoidal(double p0,double p1){USED(p0); USED(p1); return trapezoidal(p0,p1);}
|
||||
static proj Yvandergrinten(double p0, double p1){USED(p0); USED(p1); return vandergrinten();}
|
||||
|
||||
struct index index[] = {
|
||||
{"aitoff", Yaitoff, 0, picut, 0, 0, 0},
|
||||
{"albers", Yalbers, 2, picut, 3, 0, 0},
|
||||
{"azequalarea", Yazequalarea, 0, nocut, 1, 0, 0},
|
||||
{"azequidistant", Yazequidistant, 0, nocut, 1, 0, 0},
|
||||
{"bicentric", Ybicentric, 1, nocut, 0, 0, 0},
|
||||
{"bonne", Ybonne, 1, picut, 0, 0, 0},
|
||||
{"conic", Yconic, 1, picut, 0, 0, 0},
|
||||
{"cylequalarea", Ycylequalarea, 1, picut, 3, 0, 0},
|
||||
{"cylindrical", Ycylindrical, 0, picut, 0, 0, 0},
|
||||
{"elliptic", Yelliptic, 1, picut, 0, 0, 0},
|
||||
{"fisheye", Yfisheye, 1, nocut, 0, 0, 0},
|
||||
{"gall", Ygall, 1, picut, 3, 0, 0},
|
||||
{"gilbert", Ygilbert, 0, picut, 0, 0, 0},
|
||||
{"globular", Yglobular, 0, picut, 0, 0, 0},
|
||||
{"gnomonic", Ygnomonic, 0, nocut, 0, 0, plimb},
|
||||
{"guyou", Yguyou, 0, guycut, 0, 0, 0},
|
||||
{"harrison", Yharrison, 2, nocut, 0, 0, plimb},
|
||||
{"hex", Yhex, 0, hexcut, 0, 0, 0},
|
||||
{"homing", Yhoming, 1, nocut, 3, 0, hlimb},
|
||||
{"lagrange", Ylagrange,0,picut,0, 0, 0},
|
||||
{"lambert", Ylambert, 2, picut, 0, 0, 0},
|
||||
{"laue", Ylaue, 0, nocut, 0, 0, 0},
|
||||
{"lune", Ylune, 2, nocut, 0, 0, 0},
|
||||
{"mecca", Ymecca, 1, picut, 3, 0, mlimb},
|
||||
{"mercator", Ymercator, 0, picut, 3, 0, 0},
|
||||
{"mollweide", Ymollweide, 0, picut, 0, 0, 0},
|
||||
{"newyorker", Ynewyorker, 1, nocut, 0, 0, 0},
|
||||
{"orthographic", Yorthographic, 0, nocut, 0, 0, olimb},
|
||||
{"perspective", Yperspective, 1, nocut, 0, 0, plimb},
|
||||
{"polyconic", Ypolyconic, 0, picut, 0, 0, 0},
|
||||
{"rectangular", Yrectangular, 1, picut, 3, 0, 0},
|
||||
{"simpleconic", Ysimpleconic, 2, picut, 3, 0, 0},
|
||||
{"sinusoidal", Ysinusoidal, 0, picut, 0, 0, 0},
|
||||
{"sp_albers", Ysp_albers, 2, picut, 3, 1, 0},
|
||||
{"sp_mercator", Ysp_mercator, 0, picut, 0, 1, 0},
|
||||
{"square", Ysquare, 0, picut, 0, 0, 0},
|
||||
{"stereographic", Ystereographic, 0, nocut, 0, 0, 0},
|
||||
{"tetra", Ytetra, 0, tetracut, 0, 0, 0},
|
||||
{"trapezoidal", Ytrapezoidal, 2, picut, 3, 0, 0},
|
||||
{"vandergrinten", Yvandergrinten, 0, picut, 0, 0, 0},
|
||||
0
|
||||
};
|
||||
51
src/cmd/map/iplot.h
Normal file
51
src/cmd/map/iplot.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* Plotting functions for v8 and v9 systems */
|
||||
/* This file is an alternative to plot.h */
|
||||
|
||||
/* open the plotting output */
|
||||
#define openpl() print("o\n")
|
||||
|
||||
/* close the plotting output */
|
||||
#define closepl() print("cl\n")
|
||||
|
||||
/* make sure the page or screen is clear */
|
||||
#define erase() print("e\n")
|
||||
|
||||
/* plot a point at _x,_y, which becomes current */
|
||||
#define point(_x,_y) print("poi %d %d\n", _x,_y)
|
||||
|
||||
/* coordinates to be assigned to lower left and upper right
|
||||
corners of (square) plotting area */
|
||||
#define range(_x,_y,_X,_Y) print("ra %d %d %d %d\n", _x,_y,_X,_Y)
|
||||
|
||||
/* place text, first letter at current point, which does not change */
|
||||
#define text(_s) {if(*(_s) == ' ')print("t \"%s\"\n",_s); else print("t %s\n", _s); }
|
||||
|
||||
/* draw line from current point to _x,_y, which becomes current */
|
||||
#define vec(_x,_y) print("v %d %d\n", _x,_y)
|
||||
|
||||
/* _x,_y becomes current point */
|
||||
#define move(_x, _y) print("m %d %d\n", _x, _y)
|
||||
|
||||
/* specify style for drawing lines */
|
||||
|
||||
#define SOLID "solid"
|
||||
#define DOTTED "dotted"
|
||||
#define DASHED "dashed"
|
||||
#define DOTDASH "dotdash"
|
||||
|
||||
#define pen(_s) print("pe %s\n", _s)
|
||||
|
||||
#define BLACK "z"
|
||||
#define RED "r"
|
||||
#define YELLOW "y"
|
||||
#define GREEN "g"
|
||||
#define BLUE "b"
|
||||
#define CYAN "c"
|
||||
#define MAGENTA "m"
|
||||
#define WHITE "w"
|
||||
|
||||
#define colorcode(_s) ((strcmp(_s,"black")==0)?BLACK:_s)
|
||||
|
||||
#define colorx(_s) print("co %s\n", _s); /* funny name is all ken's fault */
|
||||
|
||||
#define comment(s,f)
|
||||
26
src/cmd/map/libmap/aitoff.c
Normal file
26
src/cmd/map/libmap/aitoff.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
#define Xaitwist Xaitpole.nlat
|
||||
static struct place Xaitpole;
|
||||
|
||||
static int
|
||||
Xaitoff(struct place *place, double *x, double *y)
|
||||
{
|
||||
struct place p;
|
||||
copyplace(place,&p);
|
||||
p.wlon.l /= 2.;
|
||||
sincos(&p.wlon);
|
||||
norm(&p,&Xaitpole,&Xaitwist);
|
||||
Xazequalarea(&p,x,y);
|
||||
*x *= 2.;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
aitoff(void)
|
||||
{
|
||||
latlon(0.,0.,&Xaitpole);
|
||||
return(Xaitoff);
|
||||
}
|
||||
117
src/cmd/map/libmap/albers.c
Normal file
117
src/cmd/map/libmap/albers.c
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
/* For Albers formulas see Deetz and Adams "Elements of Map Projection", */
|
||||
/* USGS Special Publication No. 68, GPO 1921 */
|
||||
|
||||
static double r0sq, r1sq, d2, n, den, sinb1, sinb2;
|
||||
static struct coord plat1, plat2;
|
||||
static int southpole;
|
||||
|
||||
static double num(double s)
|
||||
{
|
||||
if(d2==0)
|
||||
return(1);
|
||||
s = d2*s*s;
|
||||
return(1+s*(2./3+s*(3./5+s*(4./7+s*5./9))));
|
||||
}
|
||||
|
||||
/* Albers projection for a spheroid, good only when N pole is fixed */
|
||||
|
||||
static int
|
||||
Xspalbers(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r = sqrt(r0sq-2*(1-d2)*place->nlat.s*num(place->nlat.s)/n);
|
||||
double t = n*place->wlon.l;
|
||||
*y = r*cos(t);
|
||||
*x = -r*sin(t);
|
||||
if(!southpole)
|
||||
*y = -*y;
|
||||
else
|
||||
*x = -*x;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* lat1, lat2: std parallels; e2: squared eccentricity */
|
||||
|
||||
static proj albinit(double lat1, double lat2, double e2)
|
||||
{
|
||||
double r1;
|
||||
double t;
|
||||
for(;;) {
|
||||
if(lat1 < -90)
|
||||
lat1 = -180 - lat1;
|
||||
if(lat2 > 90)
|
||||
lat2 = 180 - lat2;
|
||||
if(lat1 <= lat2)
|
||||
break;
|
||||
t = lat1; lat1 = lat2; lat2 = t;
|
||||
}
|
||||
if(lat2-lat1 < 1) {
|
||||
if(lat1 > 89)
|
||||
return(azequalarea());
|
||||
return(0);
|
||||
}
|
||||
if(fabs(lat2+lat1) < 1)
|
||||
return(cylequalarea(lat1));
|
||||
d2 = e2;
|
||||
den = num(1.);
|
||||
deg2rad(lat1,&plat1);
|
||||
deg2rad(lat2,&plat2);
|
||||
sinb1 = plat1.s*num(plat1.s)/den;
|
||||
sinb2 = plat2.s*num(plat2.s)/den;
|
||||
n = (plat1.c*plat1.c/(1-e2*plat1.s*plat1.s) -
|
||||
plat2.c*plat2.c/(1-e2*plat2.s*plat2.s)) /
|
||||
(2*(1-e2)*den*(sinb2-sinb1));
|
||||
r1 = plat1.c/(n*sqrt(1-e2*plat1.s*plat1.s));
|
||||
r1sq = r1*r1;
|
||||
r0sq = r1sq + 2*(1-e2)*den*sinb1/n;
|
||||
southpole = lat1<0 && plat2.c>plat1.c;
|
||||
return(Xspalbers);
|
||||
}
|
||||
|
||||
proj
|
||||
sp_albers(double lat1, double lat2)
|
||||
{
|
||||
return(albinit(lat1,lat2,EC2));
|
||||
}
|
||||
|
||||
proj
|
||||
albers(double lat1, double lat2)
|
||||
{
|
||||
return(albinit(lat1,lat2,0.));
|
||||
}
|
||||
|
||||
static double scale = 1;
|
||||
static double twist = 0;
|
||||
|
||||
void
|
||||
albscale(double x, double y, double lat, double lon)
|
||||
{
|
||||
struct place place;
|
||||
double alat, alon, x1,y1;
|
||||
scale = 1;
|
||||
twist = 0;
|
||||
invalb(x,y,&alat,&alon);
|
||||
twist = lon - alon;
|
||||
deg2rad(lat,&place.nlat);
|
||||
deg2rad(lon,&place.wlon);
|
||||
Xspalbers(&place,&x1,&y1);
|
||||
scale = sqrt((x1*x1+y1*y1)/(x*x+y*y));
|
||||
}
|
||||
|
||||
void
|
||||
invalb(double x, double y, double *lat, double *lon)
|
||||
{
|
||||
int i;
|
||||
double sinb_den, sinp;
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
*lon = atan2(-x,fabs(y))/(RAD*n) + twist;
|
||||
sinb_den = (r0sq - x*x - y*y)*n/(2*(1-d2));
|
||||
sinp = sinb_den;
|
||||
for(i=0; i<5; i++)
|
||||
sinp = sinb_den/num(sinp);
|
||||
*lat = asin(sinp)/RAD;
|
||||
}
|
||||
19
src/cmd/map/libmap/azequalarea.c
Normal file
19
src/cmd/map/libmap/azequalarea.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int
|
||||
Xazequalarea(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r;
|
||||
r = sqrt(1. - place->nlat.s);
|
||||
*x = - r * place->wlon.s;
|
||||
*y = - r * place->wlon.c;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
azequalarea(void)
|
||||
{
|
||||
return(Xazequalarea);
|
||||
}
|
||||
19
src/cmd/map/libmap/azequidist.c
Normal file
19
src/cmd/map/libmap/azequidist.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int
|
||||
Xazequidistant(struct place *place, double *x, double *y)
|
||||
{
|
||||
double colat;
|
||||
colat = PI/2 - place->nlat.l;
|
||||
*x = -colat * place->wlon.s;
|
||||
*y = -colat * place->wlon.c;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
azequidistant(void)
|
||||
{
|
||||
return(Xazequidistant);
|
||||
}
|
||||
25
src/cmd/map/libmap/bicentric.c
Normal file
25
src/cmd/map/libmap/bicentric.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct coord center;
|
||||
|
||||
static int
|
||||
Xbicentric(struct place *place, double *x, double *y)
|
||||
{
|
||||
if(place->wlon.c<=.01||place->nlat.c<=.01)
|
||||
return(-1);
|
||||
*x = -center.c*place->wlon.s/place->wlon.c;
|
||||
*y = place->nlat.s/(place->nlat.c*place->wlon.c);
|
||||
return(*x**x+*y**y<=9);
|
||||
}
|
||||
|
||||
proj
|
||||
bicentric(double l)
|
||||
{
|
||||
l = fabs(l);
|
||||
if(l>89)
|
||||
return(0);
|
||||
deg2rad(l,¢er);
|
||||
return(Xbicentric);
|
||||
}
|
||||
36
src/cmd/map/libmap/bonne.c
Normal file
36
src/cmd/map/libmap/bonne.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct coord stdpar;
|
||||
static double r0;
|
||||
|
||||
static int
|
||||
Xbonne(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r, alpha;
|
||||
r = r0 - place->nlat.l;
|
||||
if(r<.001)
|
||||
if(fabs(stdpar.c)<1e-10)
|
||||
alpha = place->wlon.l;
|
||||
else if(fabs(place->nlat.c)==0)
|
||||
alpha = 0;
|
||||
else
|
||||
alpha = place->wlon.l/(1+
|
||||
stdpar.c*stdpar.c*stdpar.c/place->nlat.c/3);
|
||||
else
|
||||
alpha = place->wlon.l * place->nlat.c / r;
|
||||
*x = - r*sin(alpha);
|
||||
*y = - r*cos(alpha);
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
bonne(double par)
|
||||
{
|
||||
if(fabs(par*RAD) < .01)
|
||||
return(Xsinusoidal);
|
||||
deg2rad(par, &stdpar);
|
||||
r0 = stdpar.c/stdpar.s + stdpar.l;
|
||||
return(Xbonne);
|
||||
}
|
||||
13
src/cmd/map/libmap/ccubrt.c
Normal file
13
src/cmd/map/libmap/ccubrt.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
void
|
||||
ccubrt(double zr, double zi, double *wr, double *wi)
|
||||
{
|
||||
double r, theta;
|
||||
theta = atan2(zi,zr);
|
||||
r = cubrt(hypot(zr,zi));
|
||||
*wr = r*cos(theta/3);
|
||||
*wi = r*sin(theta/3);
|
||||
}
|
||||
85
src/cmd/map/libmap/complex.c
Normal file
85
src/cmd/map/libmap/complex.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
/*complex divide, defensive against overflow from
|
||||
* * and /, but not from + and -
|
||||
* assumes underflow yields 0.0
|
||||
* uses identities:
|
||||
* (a + bi)/(c + di) = ((a + bd/c) + (b - ad/c)i)/(c + dd/c)
|
||||
* (a + bi)/(c + di) = (b - ai)/(d - ci)
|
||||
*/
|
||||
void
|
||||
cdiv(double a, double b, double c, double d, double *u, double *v)
|
||||
{
|
||||
double r,t;
|
||||
if(fabs(c)<fabs(d)) {
|
||||
t = -c; c = d; d = t;
|
||||
t = -a; a = b; b = t;
|
||||
}
|
||||
r = d/c;
|
||||
t = c + r*d;
|
||||
*u = (a + r*b)/t;
|
||||
*v = (b - r*a)/t;
|
||||
}
|
||||
|
||||
void
|
||||
cmul(double c1, double c2, double d1, double d2, double *e1, double *e2)
|
||||
{
|
||||
*e1 = c1*d1 - c2*d2;
|
||||
*e2 = c1*d2 + c2*d1;
|
||||
}
|
||||
|
||||
void
|
||||
csq(double c1, double c2, double *e1, double *e2)
|
||||
{
|
||||
*e1 = c1*c1 - c2*c2;
|
||||
*e2 = c1*c2*2;
|
||||
}
|
||||
|
||||
/* complex square root
|
||||
* assumes underflow yields 0.0
|
||||
* uses these identities:
|
||||
* sqrt(x+_iy) = sqrt(r(cos(t)+_isin(t))
|
||||
* = sqrt(r)(cos(t/2)+_isin(t/2))
|
||||
* cos(t/2) = sin(t)/2sin(t/2) = sqrt((1+cos(t)/2)
|
||||
* sin(t/2) = sin(t)/2cos(t/2) = sqrt((1-cos(t)/2)
|
||||
*/
|
||||
void
|
||||
csqrt(double c1, double c2, double *e1, double *e2)
|
||||
{
|
||||
double r,s;
|
||||
double x,y;
|
||||
x = fabs(c1);
|
||||
y = fabs(c2);
|
||||
if(x>=y) {
|
||||
if(x==0) {
|
||||
*e1 = *e2 = 0;
|
||||
return;
|
||||
}
|
||||
r = x;
|
||||
s = y/x;
|
||||
} else {
|
||||
r = y;
|
||||
s = x/y;
|
||||
}
|
||||
r *= sqrt(1+ s*s);
|
||||
if(c1>0) {
|
||||
*e1 = sqrt((r+c1)/2);
|
||||
*e2 = c2/(2* *e1);
|
||||
} else {
|
||||
*e2 = sqrt((r-c1)/2);
|
||||
if(c2<0)
|
||||
*e2 = -*e2;
|
||||
*e1 = c2/(2* *e2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cpow(double c1, double c2, double *d1, double *d2, double pwr)
|
||||
{
|
||||
double theta = pwr*atan2(c2,c1);
|
||||
double r = pow(hypot(c1,c2), pwr);
|
||||
*d1 = r*cos(theta);
|
||||
*d2 = r*sin(theta);
|
||||
}
|
||||
27
src/cmd/map/libmap/conic.c
Normal file
27
src/cmd/map/libmap/conic.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct coord stdpar;
|
||||
|
||||
static int
|
||||
Xconic(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r;
|
||||
if(fabs(place->nlat.l-stdpar.l) > 80.*RAD)
|
||||
return(-1);
|
||||
r = stdpar.c/stdpar.s - tan(place->nlat.l - stdpar.l);
|
||||
*x = - r*sin(place->wlon.l * stdpar.s);
|
||||
*y = - r*cos(place->wlon.l * stdpar.s);
|
||||
if(r>3) return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
conic(double par)
|
||||
{
|
||||
if(fabs(par) <.1)
|
||||
return(Xcylindrical);
|
||||
deg2rad(par, &stdpar);
|
||||
return(Xconic);
|
||||
}
|
||||
30
src/cmd/map/libmap/cubrt.c
Normal file
30
src/cmd/map/libmap/cubrt.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
double
|
||||
cubrt(double a)
|
||||
{
|
||||
double x,y,x1;
|
||||
if(a==0)
|
||||
return(0.);
|
||||
y = 1;
|
||||
if(a<0) {
|
||||
y = -y;
|
||||
a = -a;
|
||||
}
|
||||
while(a<1) {
|
||||
a *= 8;
|
||||
y /= 2;
|
||||
}
|
||||
while(a>1) {
|
||||
a /= 8;
|
||||
y *= 2;
|
||||
}
|
||||
x = 1;
|
||||
do {
|
||||
x1 = x;
|
||||
x = (2*x1+a/(x1*x1))/3;
|
||||
} while(fabs(x-x1)>10.e-15);
|
||||
return(x*y);
|
||||
}
|
||||
39
src/cmd/map/libmap/cuts.c
Normal file
39
src/cmd/map/libmap/cuts.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
extern void abort(void);
|
||||
|
||||
/* these routines duplicate names found in map.c. they are
|
||||
called from routines in hex.c, guyou.c, and tetra.c, which
|
||||
are in turn invoked directly from map.c. this bad organization
|
||||
arises from data hiding; only these three files know stuff
|
||||
that's necessary for the proper handling of the unusual cuts
|
||||
involved in these projections.
|
||||
|
||||
the calling routines are not advertised as part of the library,
|
||||
and the library duplicates should never get loaded, however they
|
||||
are included to make the libary self-standing.*/
|
||||
|
||||
int
|
||||
picut(struct place *g, struct place *og, double *cutlon)
|
||||
{
|
||||
g; og; cutlon;
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ckcut(struct place *g1, struct place *g2, double lon)
|
||||
{
|
||||
g1; g2; lon;
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
double
|
||||
reduce(double x)
|
||||
{
|
||||
x;
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
24
src/cmd/map/libmap/cylequalarea.c
Normal file
24
src/cmd/map/libmap/cylequalarea.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double a;
|
||||
|
||||
static int
|
||||
Xcylequalarea(struct place *place, double *x, double *y)
|
||||
{
|
||||
*x = - place->wlon.l * a;
|
||||
*y = place->nlat.s;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
cylequalarea(double par)
|
||||
{
|
||||
struct coord stdp0;
|
||||
if(par > 89.0)
|
||||
return(0);
|
||||
deg2rad(par, &stdp0);
|
||||
a = stdp0.c*stdp0.c;
|
||||
return(Xcylequalarea);
|
||||
}
|
||||
19
src/cmd/map/libmap/cylindrical.c
Normal file
19
src/cmd/map/libmap/cylindrical.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int
|
||||
Xcylindrical(struct place *place, double *x, double *y)
|
||||
{
|
||||
if(fabs(place->nlat.l) > 80.*RAD)
|
||||
return(-1);
|
||||
*x = - place->wlon.l;
|
||||
*y = place->nlat.s / place->nlat.c;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
cylindrical(void)
|
||||
{
|
||||
return(Xcylindrical);
|
||||
}
|
||||
132
src/cmd/map/libmap/elco2.c
Normal file
132
src/cmd/map/libmap/elco2.c
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
/* elliptic integral routine, R.Bulirsch,
|
||||
* Numerische Mathematik 7(1965) 78-90
|
||||
* calculate integral from 0 to x+iy of
|
||||
* (a+b*t^2)/((1+t^2)*sqrt((1+t^2)*(1+kc^2*t^2)))
|
||||
* yields about D valid figures, where CC=10e-D
|
||||
* for a*b>=0, except at branchpoints x=0,y=+-i,+-i/kc;
|
||||
* there the accuracy may be reduced.
|
||||
* fails for kc=0 or x<0
|
||||
* return(1) for success, return(0) for fail
|
||||
*
|
||||
* special case a=b=1 is equivalent to
|
||||
* standard elliptic integral of first kind
|
||||
* from 0 to atan(x+iy) of
|
||||
* 1/sqrt(1-k^2*(sin(t))^2) where k^2=1-kc^2
|
||||
*/
|
||||
|
||||
#define ROOTINF 10.e18
|
||||
#define CC 1.e-6
|
||||
|
||||
int
|
||||
elco2(double x, double y, double kc, double a, double b, double *u, double *v)
|
||||
{
|
||||
double c,d,dn1,dn2,e,e1,e2,f,f1,f2,h,k,m,m1,m2,sy;
|
||||
double d1[13],d2[13];
|
||||
int i,l;
|
||||
if(kc==0||x<0)
|
||||
return(0);
|
||||
sy = y>0? 1: y==0? 0: -1;
|
||||
y = fabs(y);
|
||||
csq(x,y,&c,&e2);
|
||||
d = kc*kc;
|
||||
k = 1-d;
|
||||
e1 = 1+c;
|
||||
cdiv2(1+d*c,d*e2,e1,e2,&f1,&f2);
|
||||
f2 = -k*x*y*2/f2;
|
||||
csqr(f1,f2,&dn1,&dn2);
|
||||
if(f1<0) {
|
||||
f1 = dn1;
|
||||
dn1 = -dn2;
|
||||
dn2 = -f1;
|
||||
}
|
||||
if(k<0) {
|
||||
dn1 = fabs(dn1);
|
||||
dn2 = fabs(dn2);
|
||||
}
|
||||
c = 1+dn1;
|
||||
cmul(e1,e2,c,dn2,&f1,&f2);
|
||||
cdiv(x,y,f1,f2,&d1[0],&d2[0]);
|
||||
h = a-b;
|
||||
d = f = m = 1;
|
||||
kc = fabs(kc);
|
||||
e = a;
|
||||
a += b;
|
||||
l = 4;
|
||||
for(i=1;;i++) {
|
||||
m1 = (kc+m)/2;
|
||||
m2 = m1*m1;
|
||||
k *= f/(m2*4);
|
||||
b += e*kc;
|
||||
e = a;
|
||||
cdiv2(kc+m*dn1,m*dn2,c,dn2,&f1,&f2);
|
||||
csqr(f1/m1,k*dn2*2/f2,&dn1,&dn2);
|
||||
cmul(dn1,dn2,x,y,&f1,&f2);
|
||||
x = fabs(f1);
|
||||
y = fabs(f2);
|
||||
a += b/m1;
|
||||
l *= 2;
|
||||
c = 1 +dn1;
|
||||
d *= k/2;
|
||||
cmul(x,y,x,y,&e1,&e2);
|
||||
k *= k;
|
||||
|
||||
cmul(c,dn2,1+e1*m2,e2*m2,&f1,&f2);
|
||||
cdiv(d*x,d*y,f1,f2,&d1[i],&d2[i]);
|
||||
if(k<=CC)
|
||||
break;
|
||||
kc = sqrt(m*kc);
|
||||
f = m2;
|
||||
m = m1;
|
||||
}
|
||||
f1 = f2 = 0;
|
||||
for(;i>=0;i--) {
|
||||
f1 += d1[i];
|
||||
f2 += d2[i];
|
||||
}
|
||||
x *= m1;
|
||||
y *= m1;
|
||||
cdiv2(1-y,x,1+y,-x,&e1,&e2);
|
||||
e2 = x*2/e2;
|
||||
d = a/(m1*l);
|
||||
*u = atan2(e2,e1);
|
||||
if(*u<0)
|
||||
*u += PI;
|
||||
a = d*sy/2;
|
||||
*u = d*(*u) + f1*h;
|
||||
*v = (-1-log(e1*e1+e2*e2))*a + f2*h*sy + a;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
cdiv2(double c1, double c2, double d1, double d2, double *e1, double *e2)
|
||||
{
|
||||
double t;
|
||||
if(fabs(d2)>fabs(d1)) {
|
||||
t = d1, d1 = d2, d2 = t;
|
||||
t = c1, c1 = c2, c2 = t;
|
||||
}
|
||||
if(fabs(d1)>ROOTINF)
|
||||
*e2 = ROOTINF*ROOTINF;
|
||||
else
|
||||
*e2 = d1*d1 + d2*d2;
|
||||
t = d2/d1;
|
||||
*e1 = (c1+t*c2)/(d1+t*d2); /* (c1*d1+c2*d2)/(d1*d1+d2*d2) */
|
||||
}
|
||||
|
||||
/* complex square root of |x|+iy */
|
||||
void
|
||||
csqr(double c1, double c2, double *e1, double *e2)
|
||||
{
|
||||
double r2;
|
||||
r2 = c1*c1 + c2*c2;
|
||||
if(r2<=0) {
|
||||
*e1 = *e2 = 0;
|
||||
return;
|
||||
}
|
||||
*e1 = sqrt((sqrt(r2) + fabs(c1))/2);
|
||||
*e2 = c2/(*e1*2);
|
||||
}
|
||||
35
src/cmd/map/libmap/elliptic.c
Normal file
35
src/cmd/map/libmap/elliptic.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
struct coord center;
|
||||
|
||||
static int
|
||||
Xelliptic(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r1,r2;
|
||||
r1 = acos(place->nlat.c*(place->wlon.c*center.c
|
||||
- place->wlon.s*center.s));
|
||||
r2 = acos(place->nlat.c*(place->wlon.c*center.c
|
||||
+ place->wlon.s*center.s));
|
||||
*x = -(r1*r1 - r2*r2)/(4*center.l);
|
||||
*y = (r1*r1+r2*r2)/2 - (center.l*center.l+*x**x);
|
||||
if(*y < 0)
|
||||
*y = 0;
|
||||
*y = sqrt(*y);
|
||||
if(place->nlat.l<0)
|
||||
*y = -*y;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
elliptic(double l)
|
||||
{
|
||||
l = fabs(l);
|
||||
if(l>89)
|
||||
return(0);
|
||||
if(l<1)
|
||||
return(Xazequidistant);
|
||||
deg2rad(l,¢er);
|
||||
return(Xelliptic);
|
||||
}
|
||||
26
src/cmd/map/libmap/fisheye.c
Normal file
26
src/cmd/map/libmap/fisheye.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
/* refractive fisheye, not logarithmic */
|
||||
|
||||
static double n;
|
||||
|
||||
static int
|
||||
Xfisheye(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r;
|
||||
double u = sin(PI/4-place->nlat.l/2)/n;
|
||||
if(fabs(u) > .97)
|
||||
return -1;
|
||||
r = tan(asin(u));
|
||||
*x = -r*place->wlon.s;
|
||||
*y = -r*place->wlon.c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
fisheye(double par)
|
||||
{
|
||||
n = par;
|
||||
return n<.1? 0: Xfisheye;
|
||||
}
|
||||
29
src/cmd/map/libmap/gall.c
Normal file
29
src/cmd/map/libmap/gall.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double scale;
|
||||
|
||||
static int
|
||||
Xgall(struct place *place, double *x, double *y)
|
||||
{
|
||||
/* two ways to compute tan(place->nlat.l/2) */
|
||||
if(fabs(place->nlat.s)<.1)
|
||||
*y = sin(place->nlat.l/2)/cos(place->nlat.l/2);
|
||||
else
|
||||
*y = (1-place->nlat.c)/place->nlat.s;
|
||||
*x = -scale*place->wlon.l;
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
gall(double par)
|
||||
{
|
||||
double coshalf;
|
||||
if(fabs(par)>80)
|
||||
return 0;
|
||||
par *= RAD;
|
||||
coshalf = cos(par/2);
|
||||
scale = cos(par)/(2*coshalf*coshalf);
|
||||
return Xgall;
|
||||
}
|
||||
51
src/cmd/map/libmap/gilbert.c
Normal file
51
src/cmd/map/libmap/gilbert.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int
|
||||
Xgilbert(struct place *p, double *x, double *y)
|
||||
{
|
||||
/* the interesting part - map the sphere onto a hemisphere */
|
||||
struct place q;
|
||||
q.nlat.s = tan(0.5*(p->nlat.l));
|
||||
if(q.nlat.s > 1) q.nlat.s = 1;
|
||||
if(q.nlat.s < -1) q.nlat.s = -1;
|
||||
q.nlat.c = sqrt(1 - q.nlat.s*q.nlat.s);
|
||||
q.wlon.l = p->wlon.l/2;
|
||||
sincos(&q.wlon);
|
||||
/* the dull part: present the hemisphere orthogrpahically */
|
||||
*y = q.nlat.s;
|
||||
*x = -q.wlon.s*q.nlat.c;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
gilbert(void)
|
||||
{
|
||||
return(Xgilbert);
|
||||
}
|
||||
|
||||
/* derivation of the interesting part:
|
||||
map the sphere onto the plane by stereographic projection;
|
||||
map the plane onto a half plane by sqrt;
|
||||
map the half plane back to the sphere by stereographic
|
||||
projection
|
||||
|
||||
n,w are original lat and lon
|
||||
r is stereographic radius
|
||||
primes are transformed versions
|
||||
|
||||
r = cos(n)/(1+sin(n))
|
||||
r' = sqrt(r) = cos(n')/(1+sin(n'))
|
||||
|
||||
r'^2 = (1-sin(n')^2)/(1+sin(n')^2) = cos(n)/(1+sin(n))
|
||||
|
||||
this is a linear equation for sin n', with solution
|
||||
|
||||
sin n' = (1+sin(n)-cos(n))/(1+sin(n)+cos(n))
|
||||
|
||||
use standard formula: tan x/2 = (1-cos x)/sin x = sin x/(1+cos x)
|
||||
to show that the right side of the last equation is tan(n/2)
|
||||
*/
|
||||
|
||||
|
||||
101
src/cmd/map/libmap/guyou.c
Normal file
101
src/cmd/map/libmap/guyou.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct place gywhem, gyehem;
|
||||
static struct coord gytwist;
|
||||
static double gyconst, gykc, gyside;
|
||||
|
||||
|
||||
static void
|
||||
dosquare(double z1, double z2, double *x, double *y)
|
||||
{
|
||||
double w1,w2;
|
||||
w1 = z1 -1;
|
||||
if(fabs(w1*w1+z2*z2)>.000001) {
|
||||
cdiv(z1+1,z2,w1,z2,&w1,&w2);
|
||||
w1 *= gyconst;
|
||||
w2 *= gyconst;
|
||||
if(w1<0)
|
||||
w1 = 0;
|
||||
elco2(w1,w2,gykc,1.,1.,x,y);
|
||||
} else {
|
||||
*x = gyside;
|
||||
*y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Xguyou(struct place *place, double *x, double *y)
|
||||
{
|
||||
int ew; /*which hemisphere*/
|
||||
double z1,z2;
|
||||
struct place pl;
|
||||
ew = place->wlon.l<0;
|
||||
copyplace(place,&pl);
|
||||
norm(&pl,ew?&gyehem:&gywhem,&gytwist);
|
||||
Xstereographic(&pl,&z1,&z2);
|
||||
dosquare(z1/2,z2/2,x,y);
|
||||
if(!ew)
|
||||
*x -= gyside;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
guyou(void)
|
||||
{
|
||||
double junk;
|
||||
gykc = 1/(3+2*sqrt(2.));
|
||||
gyconst = -(1+sqrt(2.));
|
||||
elco2(-gyconst,0.,gykc,1.,1.,&gyside,&junk);
|
||||
gyside *= 2;
|
||||
latlon(0.,90.,&gywhem);
|
||||
latlon(0.,-90.,&gyehem);
|
||||
deg2rad(0.,&gytwist);
|
||||
return(Xguyou);
|
||||
}
|
||||
|
||||
int
|
||||
guycut(struct place *g, struct place *og, double *cutlon)
|
||||
{
|
||||
int c;
|
||||
c = picut(g,og,cutlon);
|
||||
if(c!=1)
|
||||
return(c);
|
||||
*cutlon = 0.;
|
||||
if(g->nlat.c<.7071||og->nlat.c<.7071)
|
||||
return(ckcut(g,og,0.));
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
Xsquare(struct place *place, double *x, double *y)
|
||||
{
|
||||
double z1,z2;
|
||||
double r, theta;
|
||||
struct place p;
|
||||
copyplace(place,&p);
|
||||
if(place->nlat.l<0) {
|
||||
p.nlat.l = -p.nlat.l;
|
||||
p.nlat.s = -p.nlat.s;
|
||||
}
|
||||
if(p.nlat.l<FUZZ && fabs(p.wlon.l)>PI-FUZZ){
|
||||
*y = -gyside/2;
|
||||
*x = p.wlon.l>0?0:gyside;
|
||||
return(1);
|
||||
}
|
||||
Xstereographic(&p,&z1,&z2);
|
||||
r = sqrt(sqrt(hypot(z1,z2)/2));
|
||||
theta = atan2(z1,-z2)/4;
|
||||
dosquare(r*sin(theta),-r*cos(theta),x,y);
|
||||
if(place->nlat.l<0)
|
||||
*y = -gyside - *y;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
square(void)
|
||||
{
|
||||
guyou();
|
||||
return(Xsquare);
|
||||
}
|
||||
40
src/cmd/map/libmap/harrison.c
Normal file
40
src/cmd/map/libmap/harrison.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double v3,u2,u3,a,b; /*v=view,p=obj,u=unit.y*/
|
||||
|
||||
static int
|
||||
Xharrison(struct place *place, double *x, double *y)
|
||||
{
|
||||
double p1 = -place->nlat.c*place->wlon.s;
|
||||
double p2 = -place->nlat.c*place->wlon.c;
|
||||
double p3 = place->nlat.s;
|
||||
double d = b + u3*p2 - u2*p3;
|
||||
double t;
|
||||
if(d < .01)
|
||||
return -1;
|
||||
t = a/d;
|
||||
if(v3*place->nlat.s < 1.)
|
||||
return -1;
|
||||
*y = t*p2*u2 + (v3-t*(v3-p3))*u3;
|
||||
*x = t*p1;
|
||||
if(t < 0)
|
||||
return 0;
|
||||
if(*x * *x + *y * *y > 16)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
harrison(double r, double alpha)
|
||||
{
|
||||
u2 = cos(alpha*RAD);
|
||||
u3 = sin(alpha*RAD);
|
||||
v3 = r;
|
||||
b = r*u2;
|
||||
a = 1 + b;
|
||||
if(r<1.001 || a<sqrt(r*r-1))
|
||||
return 0;
|
||||
return Xharrison;
|
||||
}
|
||||
122
src/cmd/map/libmap/hex.c
Normal file
122
src/cmd/map/libmap/hex.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
#define BIG 1.e15
|
||||
#define HFUZZ .0001
|
||||
|
||||
static double hcut[3] ;
|
||||
static double kr[3] = { .5, -1., .5 };
|
||||
static double ki[3] = { -1., 0., 1. }; /*to multiply by sqrt(3)/2*/
|
||||
static double cr[3];
|
||||
static double ci[3];
|
||||
static struct place hem;
|
||||
static struct coord twist;
|
||||
static double rootroot3, hkc;
|
||||
static double w2;
|
||||
static double rootk;
|
||||
|
||||
static void
|
||||
reflect(int i, double wr, double wi, double *x, double *y)
|
||||
{
|
||||
double pr,pi,l;
|
||||
pr = cr[i]-wr;
|
||||
pi = ci[i]-wi;
|
||||
l = 2*(kr[i]*pr + ki[i]*pi);
|
||||
*x = wr + l*kr[i];
|
||||
*y = wi + l*ki[i];
|
||||
}
|
||||
|
||||
static int
|
||||
Xhex(struct place *place, double *x, double *y)
|
||||
{
|
||||
int ns;
|
||||
int i;
|
||||
double zr,zi;
|
||||
double sr,si,tr,ti,ur,ui,vr,vi,yr,yi;
|
||||
struct place p;
|
||||
copyplace(place,&p);
|
||||
ns = place->nlat.l >= 0;
|
||||
if(!ns) {
|
||||
p.nlat.l = -p.nlat.l;
|
||||
p.nlat.s = -p.nlat.s;
|
||||
}
|
||||
if(p.nlat.l<HFUZZ) {
|
||||
for(i=0;i<3;i++)
|
||||
if(fabs(reduce(p.wlon.l-hcut[i]))<HFUZZ) {
|
||||
if(i==2) {
|
||||
*x = 2*cr[0] - cr[1];
|
||||
*y = 0;
|
||||
} else {
|
||||
*x = cr[1];
|
||||
*y = 2*ci[2*i];
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
p.nlat.l = HFUZZ;
|
||||
sincos(&p.nlat);
|
||||
}
|
||||
norm(&p,&hem,&twist);
|
||||
Xstereographic(&p,&zr,&zi);
|
||||
zr /= 2;
|
||||
zi /= 2;
|
||||
cdiv(1-zr,-zi,1+zr,zi,&sr,&si);
|
||||
csq(sr,si,&tr,&ti);
|
||||
ccubrt(1+3*tr,3*ti,&ur,&ui);
|
||||
csqrt(ur-1,ui,&vr,&vi);
|
||||
cdiv(rootroot3+vr,vi,rootroot3-vr,-vi,&yr,&yi);
|
||||
yr /= rootk;
|
||||
yi /= rootk;
|
||||
elco2(fabs(yr),yi,hkc,1.,1.,x,y);
|
||||
if(yr < 0)
|
||||
*x = w2 - *x;
|
||||
if(!ns) reflect(hcut[0]>place->wlon.l?0:
|
||||
hcut[1]>=place->wlon.l?1:
|
||||
2,*x,*y,x,y);
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
hex(void)
|
||||
{
|
||||
int i;
|
||||
double t;
|
||||
double root3;
|
||||
double c,d;
|
||||
struct place p;
|
||||
hcut[2] = PI;
|
||||
hcut[1] = hcut[2]/3;
|
||||
hcut[0] = -hcut[1];
|
||||
root3 = sqrt(3.);
|
||||
rootroot3 = sqrt(root3);
|
||||
t = 15 -8*root3;
|
||||
hkc = t*(1-sqrt(1-1/(t*t)));
|
||||
elco2(BIG,0.,hkc,1.,1.,&w2,&t);
|
||||
w2 *= 2;
|
||||
rootk = sqrt(hkc);
|
||||
latlon(90.,90.,&hem);
|
||||
latlon(90.,0.,&p);
|
||||
Xhex(&p,&c,&t);
|
||||
latlon(0.,0.,&p);
|
||||
Xhex(&p,&d,&t);
|
||||
for(i=0;i<3;i++) {
|
||||
ki[i] *= root3/2;
|
||||
cr[i] = c + (c-d)*kr[i];
|
||||
ci[i] = (c-d)*ki[i];
|
||||
}
|
||||
deg2rad(0.,&twist);
|
||||
return(Xhex);
|
||||
}
|
||||
|
||||
int
|
||||
hexcut(struct place *g, struct place *og, double *cutlon)
|
||||
{
|
||||
int t,i;
|
||||
if(g->nlat.l>=-HFUZZ&&og->nlat.l>=-HFUZZ)
|
||||
return(1);
|
||||
for(i=0;i<3;i++) {
|
||||
t = ckcut(g,og,*cutlon=hcut[i]);
|
||||
if(t!=1) return(t);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
121
src/cmd/map/libmap/homing.c
Normal file
121
src/cmd/map/libmap/homing.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct coord p0; /* standard parallel */
|
||||
|
||||
int first;
|
||||
|
||||
static double
|
||||
trigclamp(double x)
|
||||
{
|
||||
return x>1? 1: x<-1? -1: x;
|
||||
}
|
||||
|
||||
static struct coord az; /* azimuth of p0 seen from place */
|
||||
static struct coord rad; /* angular dist from place to p0 */
|
||||
|
||||
static int
|
||||
azimuth(struct place *place)
|
||||
{
|
||||
if(place->nlat.c < FUZZ) {
|
||||
az.l = PI/2 + place->nlat.l - place->wlon.l;
|
||||
sincos(&az);
|
||||
rad.l = fabs(place->nlat.l - p0.l);
|
||||
if(rad.l > PI)
|
||||
rad.l = 2*PI - rad.l;
|
||||
sincos(&rad);
|
||||
return 1;
|
||||
}
|
||||
rad.c = trigclamp(p0.s*place->nlat.s + /* law of cosines */
|
||||
p0.c*place->nlat.c*place->wlon.c);
|
||||
rad.s = sqrt(1 - rad.c*rad.c);
|
||||
if(fabs(rad.s) < .001) {
|
||||
az.s = 0;
|
||||
az.c = 1;
|
||||
} else {
|
||||
az.s = trigclamp(p0.c*place->wlon.s/rad.s); /* sines */
|
||||
az.c = trigclamp((p0.s - rad.c*place->nlat.s)
|
||||
/(rad.s*place->nlat.c));
|
||||
}
|
||||
rad.l = atan2(rad.s, rad.c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
Xmecca(struct place *place, double *x, double *y)
|
||||
{
|
||||
if(!azimuth(place))
|
||||
return 0;
|
||||
*x = -place->wlon.l;
|
||||
*y = fabs(az.s)<.02? -az.c*rad.s/p0.c: *x*az.c/az.s;
|
||||
return fabs(*y)>2? -1:
|
||||
rad.c<0? 0:
|
||||
1;
|
||||
}
|
||||
|
||||
proj
|
||||
mecca(double par)
|
||||
{
|
||||
first = 1;
|
||||
if(fabs(par)>80.)
|
||||
return(0);
|
||||
deg2rad(par,&p0);
|
||||
return(Xmecca);
|
||||
}
|
||||
|
||||
static int
|
||||
Xhoming(struct place *place, double *x, double *y)
|
||||
{
|
||||
if(!azimuth(place))
|
||||
return 0;
|
||||
*x = -rad.l*az.s;
|
||||
*y = -rad.l*az.c;
|
||||
return place->wlon.c<0? 0: 1;
|
||||
}
|
||||
|
||||
proj
|
||||
homing(double par)
|
||||
{
|
||||
first = 1;
|
||||
if(fabs(par)>80.)
|
||||
return(0);
|
||||
deg2rad(par,&p0);
|
||||
return(Xhoming);
|
||||
}
|
||||
|
||||
int
|
||||
hlimb(double *lat, double *lon, double res)
|
||||
{
|
||||
if(first) {
|
||||
*lon = -90;
|
||||
*lat = -90;
|
||||
first = 0;
|
||||
return 0;
|
||||
}
|
||||
*lat += res;
|
||||
if(*lat <= 90)
|
||||
return 1;
|
||||
if(*lon == 90)
|
||||
return -1;
|
||||
*lon = 90;
|
||||
*lat = -90;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mlimb(double *lat, double *lon, double res)
|
||||
{
|
||||
int ret = !first;
|
||||
if(fabs(p0.s) < .01)
|
||||
return -1;
|
||||
if(first) {
|
||||
*lon = -180;
|
||||
first = 0;
|
||||
} else
|
||||
*lon += res;
|
||||
if(*lon > 180)
|
||||
return -1;
|
||||
*lat = atan(-cos(*lon*RAD)/p0.s*p0.c)/RAD;
|
||||
return ret;
|
||||
}
|
||||
30
src/cmd/map/libmap/lagrange.c
Normal file
30
src/cmd/map/libmap/lagrange.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static int
|
||||
Xlagrange(struct place *place, double *x, double *y)
|
||||
{
|
||||
double z1,z2;
|
||||
double w1,w2,t1,t2;
|
||||
struct place p;
|
||||
copyplace(place,&p);
|
||||
if(place->nlat.l<0) {
|
||||
p.nlat.l = -p.nlat.l;
|
||||
p.nlat.s = -p.nlat.s;
|
||||
}
|
||||
Xstereographic(&p,&z1,&z2);
|
||||
csqrt(-z2/2,z1/2,&w1,&w2);
|
||||
cdiv(w1-1,w2,w1+1,w2,&t1,&t2);
|
||||
*y = -t1;
|
||||
*x = t2;
|
||||
if(place->nlat.l<0)
|
||||
*y = -*y;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
lagrange(void)
|
||||
{
|
||||
return(Xlagrange);
|
||||
}
|
||||
46
src/cmd/map/libmap/lambert.c
Normal file
46
src/cmd/map/libmap/lambert.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct coord stdp0, stdp1;
|
||||
static double k;
|
||||
|
||||
static int
|
||||
Xlambert(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r;
|
||||
if(place->nlat.l < -80.*RAD)
|
||||
return(-1);
|
||||
if(place->nlat.l > 89.*RAD)
|
||||
r = 0; /* slovenly */
|
||||
else
|
||||
r = stdp0.c*exp(0.5*k*log(
|
||||
(1+stdp0.s)*(1-place->nlat.s)/((1-stdp0.s)*(1+place->nlat.s))));
|
||||
if(stdp1.l<0.)
|
||||
r = -r;
|
||||
*x = - r*sin(k * place->wlon.l);
|
||||
*y = - r*cos(k * place->wlon.l);
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
lambert(double par0, double par1)
|
||||
{
|
||||
double temp;
|
||||
if(fabs(par0)>fabs(par1)){
|
||||
temp = par0;
|
||||
par0 = par1;
|
||||
par1 = temp;
|
||||
}
|
||||
deg2rad(par0, &stdp0);
|
||||
deg2rad(par1, &stdp1);
|
||||
if(fabs(par1+par0)<.1)
|
||||
return(mercator());
|
||||
if(fabs(par1-par0)<.1)
|
||||
return(perspective(-1.));
|
||||
if(fabs(par0)>89.5||fabs(par1)>89.5)
|
||||
return(0);
|
||||
k = 2*log(stdp1.c/stdp0.c)/log(
|
||||
(1+stdp0.s)*(1-stdp1.s)/((1-stdp0.s)*(1+stdp1.s)));
|
||||
return(Xlambert);
|
||||
}
|
||||
24
src/cmd/map/libmap/laue.c
Normal file
24
src/cmd/map/libmap/laue.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
|
||||
static int
|
||||
Xlaue(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r;
|
||||
if(place->nlat.l<PI/4+FUZZ)
|
||||
return(-1);
|
||||
r = tan(PI-2*place->nlat.l);
|
||||
if(r>3)
|
||||
return(-1);
|
||||
*x = - r * place->wlon.s;
|
||||
*y = - r * place->wlon.c;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
laue(void)
|
||||
{
|
||||
return(Xlaue);
|
||||
}
|
||||
62
src/cmd/map/libmap/lune.c
Normal file
62
src/cmd/map/libmap/lune.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int Xstereographic(struct place *place, double *x, double *y);
|
||||
|
||||
static struct place eastpole;
|
||||
static struct place westpole;
|
||||
static double eastx, easty;
|
||||
static double westx, westy;
|
||||
static double scale;
|
||||
static double pwr;
|
||||
|
||||
/* conformal map w = ((1+z)^A - (1-z)^A)/((1+z)^A + (1-z)^A),
|
||||
where A<1, maps unit circle onto a convex lune with x= +-1
|
||||
mapping to vertices of angle A*PI at w = +-1 */
|
||||
|
||||
/* there are cuts from E and W poles to S pole,
|
||||
in absence of a cut routine, error is returned for
|
||||
points outside a polar cap through E and W poles */
|
||||
|
||||
static int Xlune(struct place *place, double *x, double *y)
|
||||
{
|
||||
double stereox, stereoy;
|
||||
double z1x, z1y, z2x, z2y;
|
||||
double w1x, w1y, w2x, w2y;
|
||||
double numx, numy, denx, deny;
|
||||
if(place->nlat.l < eastpole.nlat.l-FUZZ)
|
||||
return -1;
|
||||
Xstereographic(place, &stereox, &stereoy);
|
||||
stereox *= scale;
|
||||
stereoy *= scale;
|
||||
z1x = 1 + stereox;
|
||||
z1y = stereoy;
|
||||
z2x = 1 - stereox;
|
||||
z2y = -stereoy;
|
||||
cpow(z1x,z1y,&w1x,&w1y,pwr);
|
||||
cpow(z2x,z2y,&w2x,&w2y,pwr);
|
||||
numx = w1x - w2x;
|
||||
numy = w1y - w2y;
|
||||
denx = w1x + w2x;
|
||||
deny = w1y + w2y;
|
||||
cdiv(numx, numy, denx, deny, x, y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
lune(double lat, double theta)
|
||||
{
|
||||
deg2rad(lat, &eastpole.nlat);
|
||||
deg2rad(-90.,&eastpole.wlon);
|
||||
deg2rad(lat, &westpole.nlat);
|
||||
deg2rad(90. ,&westpole.wlon);
|
||||
Xstereographic(&eastpole, &eastx, &easty);
|
||||
Xstereographic(&westpole, &westx, &westy);
|
||||
if(fabs(easty)>FUZZ || fabs(westy)>FUZZ ||
|
||||
fabs(eastx+westx)>FUZZ)
|
||||
abort();
|
||||
scale = 1/eastx;
|
||||
pwr = theta/180;
|
||||
return Xlune;
|
||||
}
|
||||
36
src/cmd/map/libmap/mercator.c
Normal file
36
src/cmd/map/libmap/mercator.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static int
|
||||
Xmercator(struct place *place, double *x, double *y)
|
||||
{
|
||||
if(fabs(place->nlat.l) > 80.*RAD)
|
||||
return(-1);
|
||||
*x = -place->wlon.l;
|
||||
*y = 0.5*log((1+place->nlat.s)/(1-place->nlat.s));
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
mercator(void)
|
||||
{
|
||||
return(Xmercator);
|
||||
}
|
||||
|
||||
static double ecc = ECC;
|
||||
|
||||
static int
|
||||
Xspmercator(struct place *place, double *x, double *y)
|
||||
{
|
||||
if(Xmercator(place,x,y) < 0)
|
||||
return(-1);
|
||||
*y += 0.5*ecc*log((1-ecc*place->nlat.s)/(1+ecc*place->nlat.s));
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
sp_mercator(void)
|
||||
{
|
||||
return(Xspmercator);
|
||||
}
|
||||
50
src/cmd/map/libmap/mkfile
Normal file
50
src/cmd/map/libmap/mkfile
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<$PLAN9/src/mkhdr
|
||||
|
||||
LIB=libmap.a
|
||||
OFILES=aitoff.$O\
|
||||
albers.$O\
|
||||
azequalarea.$O\
|
||||
azequidist.$O\
|
||||
bicentric.$O\
|
||||
bonne.$O\
|
||||
ccubrt.$O\
|
||||
complex.$O\
|
||||
conic.$O\
|
||||
cubrt.$O\
|
||||
cylequalarea.$O\
|
||||
cylindrical.$O\
|
||||
elco2.$O\
|
||||
elliptic.$O\
|
||||
fisheye.$O\
|
||||
gall.$O\
|
||||
gilbert.$O\
|
||||
guyou.$O\
|
||||
harrison.$O\
|
||||
hex.$O\
|
||||
homing.$O\
|
||||
lagrange.$O\
|
||||
lambert.$O\
|
||||
laue.$O\
|
||||
lune.$O\
|
||||
mercator.$O\
|
||||
mollweide.$O\
|
||||
newyorker.$O\
|
||||
orthographic.$O\
|
||||
perspective.$O\
|
||||
polyconic.$O\
|
||||
rectangular.$O\
|
||||
simpleconic.$O\
|
||||
sinusoidal.$O\
|
||||
tetra.$O\
|
||||
trapezoidal.$O\
|
||||
twocirc.$O\
|
||||
zcoord.$O\
|
||||
|
||||
HFILES=../map.h\
|
||||
|
||||
<$PLAN9/src/mklib
|
||||
CFLAGS=$CFLAGS -I..
|
||||
|
||||
nuke:V:
|
||||
mk clean
|
||||
rm -f libmap.a[$OS]
|
||||
25
src/cmd/map/libmap/mollweide.c
Normal file
25
src/cmd/map/libmap/mollweide.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static int
|
||||
Xmollweide(struct place *place, double *x, double *y)
|
||||
{
|
||||
double z;
|
||||
double w;
|
||||
z = place->nlat.l;
|
||||
if(fabs(z)<89.9*RAD)
|
||||
do { /*newton for 2z+sin2z=pi*sin(lat)*/
|
||||
w = (2*z+sin(2*z)-PI*place->nlat.s)/(2+2*cos(2*z));
|
||||
z -= w;
|
||||
} while(fabs(w)>=.00001);
|
||||
*y = sin(z);
|
||||
*x = - (2/PI)*cos(z)*place->wlon.l;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
mollweide(void)
|
||||
{
|
||||
return(Xmollweide);
|
||||
}
|
||||
28
src/cmd/map/libmap/newyorker.c
Normal file
28
src/cmd/map/libmap/newyorker.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double a;
|
||||
|
||||
static int
|
||||
Xnewyorker(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r = PI/2 - place->nlat.l;
|
||||
double s;
|
||||
if(r<.001) /* cheat to plot center */
|
||||
s = 0;
|
||||
else if(r<a)
|
||||
return -1;
|
||||
else
|
||||
s = log(r/a);
|
||||
*x = -s * place->wlon.s;
|
||||
*y = -s * place->wlon.c;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
newyorker(double a0)
|
||||
{
|
||||
a = a0*RAD;
|
||||
return(Xnewyorker);
|
||||
}
|
||||
35
src/cmd/map/libmap/orthographic.c
Normal file
35
src/cmd/map/libmap/orthographic.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
|
||||
int
|
||||
Xorthographic(struct place *place, double *x, double *y)
|
||||
{
|
||||
*x = - place->nlat.c * place->wlon.s;
|
||||
*y = - place->nlat.c * place->wlon.c;
|
||||
return(place->nlat.l<0.? 0 : 1);
|
||||
}
|
||||
|
||||
proj
|
||||
orthographic(void)
|
||||
{
|
||||
return(Xorthographic);
|
||||
}
|
||||
|
||||
int
|
||||
olimb(double *lat, double *lon, double res)
|
||||
{
|
||||
static int first = 1;
|
||||
if(first) {
|
||||
*lat = 0;
|
||||
*lon = -180;
|
||||
first = 0;
|
||||
return 0;
|
||||
}
|
||||
*lon += res;
|
||||
if(*lon <= 180)
|
||||
return 1;
|
||||
first = 1;
|
||||
return -1;
|
||||
}
|
||||
84
src/cmd/map/libmap/perspective.c
Normal file
84
src/cmd/map/libmap/perspective.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
28
src/cmd/map/libmap/polyconic.c
Normal file
28
src/cmd/map/libmap/polyconic.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int
|
||||
Xpolyconic(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r, alpha;
|
||||
double lat2, lon2;
|
||||
if(fabs(place->nlat.l) > .01) {
|
||||
r = place->nlat.c / place->nlat.s;
|
||||
alpha = place->wlon.l * place->nlat.s;
|
||||
*y = place->nlat.l + r*(1 - cos(alpha));
|
||||
*x = - r*sin(alpha);
|
||||
} else {
|
||||
lon2 = place->wlon.l * place->wlon.l;
|
||||
lat2 = place->nlat.l * place->nlat.l;
|
||||
*y = place->nlat.l * (1+(lon2/2)*(1-(8+lon2)*lat2/12));
|
||||
*x = - place->wlon.l * (1-lat2*(3+lon2)/6);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
polyconic(void)
|
||||
{
|
||||
return(Xpolyconic);
|
||||
}
|
||||
22
src/cmd/map/libmap/rectangular.c
Normal file
22
src/cmd/map/libmap/rectangular.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double scale;
|
||||
|
||||
static int
|
||||
Xrectangular(struct place *place, double *x, double *y)
|
||||
{
|
||||
*x = -scale*place->wlon.l;
|
||||
*y = place->nlat.l;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
rectangular(double par)
|
||||
{
|
||||
scale = cos(par*RAD);
|
||||
if(scale<.1)
|
||||
return 0;
|
||||
return(Xrectangular);
|
||||
}
|
||||
34
src/cmd/map/libmap/simpleconic.c
Normal file
34
src/cmd/map/libmap/simpleconic.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double r0, a;
|
||||
|
||||
static int
|
||||
Xsimpleconic(struct place *place, double *x, double *y)
|
||||
{
|
||||
double r = r0 - place->nlat.l;
|
||||
double t = a*place->wlon.l;
|
||||
*x = -r*sin(t);
|
||||
*y = -r*cos(t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
simpleconic(double par0, double par1)
|
||||
{
|
||||
struct coord lat0;
|
||||
struct coord lat1;
|
||||
deg2rad(par0,&lat0);
|
||||
deg2rad(par1,&lat1);
|
||||
if(fabs(lat0.l+lat1.l)<.01)
|
||||
return rectangular(par0);
|
||||
if(fabs(lat0.l-lat1.l)<.01) {
|
||||
a = lat0.s/lat0.l;
|
||||
r0 = lat0.c/lat0.s + lat0.l;
|
||||
} else {
|
||||
a = (lat1.c-lat0.c)/(lat0.l-lat1.l);
|
||||
r0 = ((lat0.c+lat1.c)/a + lat1.l + lat0.l)/2;
|
||||
}
|
||||
return Xsimpleconic;
|
||||
}
|
||||
17
src/cmd/map/libmap/sinusoidal.c
Normal file
17
src/cmd/map/libmap/sinusoidal.c
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
int
|
||||
Xsinusoidal(struct place *place, double *x, double *y)
|
||||
{
|
||||
*x = - place->wlon.l * place->nlat.c;
|
||||
*y = place->nlat.l;
|
||||
return(1);
|
||||
}
|
||||
|
||||
proj
|
||||
sinusoidal(void)
|
||||
{
|
||||
return(Xsinusoidal);
|
||||
}
|
||||
206
src/cmd/map/libmap/tetra.c
Normal file
206
src/cmd/map/libmap/tetra.c
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
/*
|
||||
* conformal map of earth onto tetrahedron
|
||||
* the stages of mapping are
|
||||
* (a) stereo projection of tetrahedral face onto
|
||||
* isosceles curvilinear triangle with 3 120-degree
|
||||
* angles and one straight side
|
||||
* (b) map of this triangle onto half plane cut along
|
||||
* 3 rays from the roots of unity to infinity
|
||||
* formula (z^4+2*3^.5*z^2-1)/(z^4-2*3^.5*z^2-1)
|
||||
* (c) do 3 times for each sector of plane:
|
||||
* map of |arg z|<=pi/6, cut along z>1 into
|
||||
* triangle |arg z|<=pi/6, Re z<=const,
|
||||
* with upper side of cut going into upper half of
|
||||
* of vertical side of triangle and lowere into lower
|
||||
* formula int from 0 to z dz/sqrt(1-z^3)
|
||||
*
|
||||
* int from u to 1 3^.25*du/sqrt(1-u^3) =
|
||||
F(acos((rt3-1+u)/(rt3+1-u)),sqrt(1/2+rt3/4))
|
||||
* int from 1 to u 3^.25*du/sqrt(u^3-1) =
|
||||
* F(acos((rt3+1-u)/(rt3-1+u)),sqrt(1/2-rt3/4))
|
||||
* this latter formula extends analytically down to
|
||||
* u=0 and is the basis of this routine, with the
|
||||
* argument of complex elliptic integral elco2
|
||||
* being tan(acos...)
|
||||
* the formula F(pi-x,k) = 2*F(pi/2,k)-F(x,k) is
|
||||
* used to cross over into the region where Re(acos...)>pi/2
|
||||
* f0 and fpi are suitably scaled complete integrals
|
||||
*/
|
||||
|
||||
#define TFUZZ 0.00001
|
||||
|
||||
static struct place tpole[4]; /* point of tangency of tetrahedron face*/
|
||||
static double tpoleinit[4][2] = {
|
||||
1., 0.,
|
||||
1., 180.,
|
||||
-1., 90.,
|
||||
-1., -90.
|
||||
};
|
||||
static struct tproj {
|
||||
double tlat,tlon; /* center of stereo projection*/
|
||||
double ttwist; /* rotatn before stereo*/
|
||||
double trot; /*rotate after projection*/
|
||||
struct place projpl; /*same as tlat,tlon*/
|
||||
struct coord projtw; /*same as ttwist*/
|
||||
struct coord postrot; /*same as trot*/
|
||||
} tproj[4][4] = {
|
||||
{/*00*/ {0.},
|
||||
/*01*/ {90., 0., 90., -90.},
|
||||
/*02*/ {0., 45., -45., 150.},
|
||||
/*03*/ {0., -45., -135., 30.}
|
||||
},
|
||||
{/*10*/ {90., 0., -90., 90.},
|
||||
/*11*/ {0.},
|
||||
/*12*/ {0., 135., -135., -150.},
|
||||
/*13*/ {0., -135., -45., -30.}
|
||||
},
|
||||
{/*20*/ {0., 45., 135., -30.},
|
||||
/*21*/ {0., 135., 45., -150.},
|
||||
/*22*/ {0.},
|
||||
/*23*/ {-90., 0., 180., 90.}
|
||||
},
|
||||
{/*30*/ {0., -45., 45., -150.},
|
||||
/*31*/ {0., -135., 135., -30.},
|
||||
/*32*/ {-90., 0., 0., 90.},
|
||||
/*33*/ {0.}
|
||||
}};
|
||||
static double tx[4] = { /*where to move facet after final rotation*/
|
||||
0., 0., -1., 1. /*-1,1 to be sqrt(3)*/
|
||||
};
|
||||
static double ty[4] = {
|
||||
0., 2., -1., -1.
|
||||
};
|
||||
static double root3;
|
||||
static double rt3inv;
|
||||
static double two_rt3;
|
||||
static double tkc,tk,tcon;
|
||||
static double f0r,f0i,fpir,fpii;
|
||||
|
||||
static void
|
||||
twhichp(struct place *g, int *p, int *q)
|
||||
{
|
||||
int i,j,k;
|
||||
double cosdist[4];
|
||||
struct place *tp;
|
||||
for(i=0;i<4;i++) {
|
||||
tp = &tpole[i];
|
||||
cosdist[i] = g->nlat.s*tp->nlat.s +
|
||||
g->nlat.c*tp->nlat.c*(
|
||||
g->wlon.s*tp->wlon.s +
|
||||
g->wlon.c*tp->wlon.c);
|
||||
}
|
||||
j = 0;
|
||||
for(i=1;i<4;i++)
|
||||
if(cosdist[i] > cosdist[j])
|
||||
j = i;
|
||||
*p = j;
|
||||
k = j==0?1:0;
|
||||
for(i=0;i<4;i++)
|
||||
if(i!=j&&cosdist[i]>cosdist[k])
|
||||
k = i;
|
||||
*q = k;
|
||||
}
|
||||
|
||||
int
|
||||
Xtetra(struct place *place, double *x, double *y)
|
||||
{
|
||||
int i,j;
|
||||
struct place pl;
|
||||
register struct tproj *tpp;
|
||||
double vr, vi;
|
||||
double br, bi;
|
||||
double zr,zi,z2r,z2i,z4r,z4i,sr,si,tr,ti;
|
||||
twhichp(place,&i,&j);
|
||||
copyplace(place,&pl);
|
||||
norm(&pl,&tproj[i][j].projpl,&tproj[i][j].projtw);
|
||||
Xstereographic(&pl,&vr,&vi);
|
||||
zr = vr/2;
|
||||
zi = vi/2;
|
||||
if(zr<=TFUZZ)
|
||||
zr = TFUZZ;
|
||||
csq(zr,zi,&z2r,&z2i);
|
||||
csq(z2r,z2i,&z4r,&z4i);
|
||||
z2r *= two_rt3;
|
||||
z2i *= two_rt3;
|
||||
cdiv(z4r+z2r-1,z4i+z2i,z4r-z2r-1,z4i-z2i,&sr,&si);
|
||||
csqrt(sr-1,si,&tr,&ti);
|
||||
cdiv(tcon*tr,tcon*ti,root3+1-sr,-si,&br,&bi);
|
||||
if(br<0) {
|
||||
br = -br;
|
||||
bi = -bi;
|
||||
if(!elco2(br,bi,tk,1.,1.,&vr,&vi))
|
||||
return 0;
|
||||
vr = fpir - vr;
|
||||
vi = fpii - vi;
|
||||
} else
|
||||
if(!elco2(br,bi,tk,1.,1.,&vr,&vi))
|
||||
return 0;
|
||||
if(si>=0) {
|
||||
tr = f0r - vi;
|
||||
ti = f0i + vr;
|
||||
} else {
|
||||
tr = f0r + vi;
|
||||
ti = f0i - vr;
|
||||
}
|
||||
tpp = &tproj[i][j];
|
||||
*x = tr*tpp->postrot.c +
|
||||
ti*tpp->postrot.s + tx[i];
|
||||
*y = ti*tpp->postrot.c -
|
||||
tr*tpp->postrot.s + ty[i];
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
tetracut(struct place *g, struct place *og, double *cutlon)
|
||||
{
|
||||
int i,j,k;
|
||||
if((g->nlat.s<=-rt3inv&&og->nlat.s<=-rt3inv) &&
|
||||
(ckcut(g,og,*cutlon=0.)==2||ckcut(g,og,*cutlon=PI)==2))
|
||||
return(2);
|
||||
twhichp(g,&i,&k);
|
||||
twhichp(og,&j,&k);
|
||||
if(i==j||i==0||j==0)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
proj
|
||||
tetra(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
register struct place *tp;
|
||||
register struct tproj *tpp;
|
||||
double t;
|
||||
root3 = sqrt(3.);
|
||||
rt3inv = 1/root3;
|
||||
two_rt3 = 2*root3;
|
||||
tkc = sqrt(.5-.25*root3);
|
||||
tk = sqrt(.5+.25*root3);
|
||||
tcon = 2*sqrt(root3);
|
||||
elco2(tcon/(root3-1),0.,tkc,1.,1.,&f0r,&f0i);
|
||||
elco2(1.e15,0.,tk,1.,1.,&fpir,&fpii);
|
||||
fpir *= 2;
|
||||
fpii *= 2;
|
||||
for(i=0;i<4;i++) {
|
||||
tx[i] *= f0r*root3;
|
||||
ty[i] *= f0r;
|
||||
tp = &tpole[i];
|
||||
t = tp->nlat.s = tpoleinit[i][0]/root3;
|
||||
tp->nlat.c = sqrt(1 - t*t);
|
||||
tp->nlat.l = atan2(tp->nlat.s,tp->nlat.c);
|
||||
deg2rad(tpoleinit[i][1],&tp->wlon);
|
||||
for(j=0;j<4;j++) {
|
||||
tpp = &tproj[i][j];
|
||||
latlon(tpp->tlat,tpp->tlon,&tpp->projpl);
|
||||
deg2rad(tpp->ttwist,&tpp->projtw);
|
||||
deg2rad(tpp->trot,&tpp->postrot);
|
||||
}
|
||||
}
|
||||
return(Xtetra);
|
||||
}
|
||||
|
||||
30
src/cmd/map/libmap/trapezoidal.c
Normal file
30
src/cmd/map/libmap/trapezoidal.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static struct coord stdpar0, stdpar1;
|
||||
static double k;
|
||||
static double yeq;
|
||||
|
||||
static int
|
||||
Xtrapezoidal(struct place *place, double *x, double *y)
|
||||
{
|
||||
*y = yeq + place->nlat.l;
|
||||
*x = *y*k*place->wlon.l;
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
trapezoidal(double par0, double par1)
|
||||
{
|
||||
if(fabs(fabs(par0)-fabs(par1))<.1)
|
||||
return rectangular(par0);
|
||||
deg2rad(par0,&stdpar0);
|
||||
deg2rad(par1,&stdpar1);
|
||||
if(fabs(par1-par0) < .1)
|
||||
k = stdpar1.s;
|
||||
else
|
||||
k = (stdpar1.c-stdpar0.c)/(stdpar0.l-stdpar1.l);
|
||||
yeq = -stdpar1.l - stdpar1.c/k;
|
||||
return Xtrapezoidal;
|
||||
}
|
||||
80
src/cmd/map/libmap/twocirc.c
Normal file
80
src/cmd/map/libmap/twocirc.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
static double
|
||||
quadratic(double a, double b, double c)
|
||||
{
|
||||
double disc = b*b - 4*a*c;
|
||||
return disc<0? 0: (-b-sqrt(disc))/(2*a);
|
||||
}
|
||||
|
||||
/* for projections with meridians being circles centered
|
||||
on the x axis and parallels being circles centered on the y
|
||||
axis. Find the intersection of the meridian thru (m,0), (90,0),
|
||||
with the parallel thru (0,p), (p1,p2) */
|
||||
|
||||
static int
|
||||
twocircles(double m, double p, double p1, double p2, double *x, double *y)
|
||||
{
|
||||
double a; /* center of meridian circle, a>0 */
|
||||
double b; /* center of parallel circle, b>0 */
|
||||
double t,bb;
|
||||
if(m > 0) {
|
||||
twocircles(-m,p,p1,p2,x,y);
|
||||
*x = -*x;
|
||||
} else if(p < 0) {
|
||||
twocircles(m,-p,p1,-p2,x,y);
|
||||
*y = -*y;
|
||||
} else if(p < .01) {
|
||||
*x = m;
|
||||
t = m/p1;
|
||||
*y = p + (p2-p)*t*t;
|
||||
} else if(m > -.01) {
|
||||
*y = p;
|
||||
*x = m - m*p*p;
|
||||
} else {
|
||||
b = p>=1? 1: p>.99? 0.5*(p+1 + p1*p1/(1-p)):
|
||||
0.5*(p*p-p1*p1-p2*p2)/(p-p2);
|
||||
a = .5*(m - 1/m);
|
||||
t = m*m-p*p+2*(b*p-a*m);
|
||||
bb = b*b;
|
||||
*x = quadratic(1+a*a/bb, -2*a + a*t/bb,
|
||||
t*t/(4*bb) - m*m + 2*a*m);
|
||||
*y = (*x*a+t/2)/b;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
Xglobular(struct place *place, double *x, double *y)
|
||||
{
|
||||
twocircles(-2*place->wlon.l/PI,
|
||||
2*place->nlat.l/PI, place->nlat.c, place->nlat.s, x, y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
globular(void)
|
||||
{
|
||||
return Xglobular;
|
||||
}
|
||||
|
||||
static int
|
||||
Xvandergrinten(struct place *place, double *x, double *y)
|
||||
{
|
||||
double t = 2*place->nlat.l/PI;
|
||||
double abst = fabs(t);
|
||||
double pval = abst>=1? 1: abst/(1+sqrt(1-t*t));
|
||||
double p2 = 2*pval/(1+pval);
|
||||
twocircles(-place->wlon.l/PI, pval, sqrt(1-p2*p2), p2, x, y);
|
||||
if(t < 0)
|
||||
*y = -*y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
proj
|
||||
vandergrinten(void)
|
||||
{
|
||||
return Xvandergrinten;
|
||||
}
|
||||
143
src/cmd/map/libmap/zcoord.c
Normal file
143
src/cmd/map/libmap/zcoord.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
double
|
||||
tan(double x)
|
||||
{
|
||||
return(sin(x)/cos(x));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
1226
src/cmd/map/map.c
Normal file
1226
src/cmd/map/map.c
Normal file
File diff suppressed because it is too large
Load diff
147
src/cmd/map/map.h
Normal file
147
src/cmd/map/map.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
#pragma lib "/sys/src/cmd/map/libmap/libmap.a$O"
|
||||
#pragma src "/sys/src/cmd/map/libmap"
|
||||
*/
|
||||
|
||||
#define index index0
|
||||
#ifndef PI
|
||||
#define PI 3.1415926535897932384626433832795028841971693993751
|
||||
#endif
|
||||
|
||||
#define TWOPI (2*PI)
|
||||
#define RAD (PI/180)
|
||||
double hypot(double, double); /* sqrt(a*a+b*b) */
|
||||
double tan(double); /* not in K&R library */
|
||||
|
||||
#define ECC .08227185422 /* eccentricity of earth */
|
||||
#define EC2 .006768657997
|
||||
|
||||
#define FUZZ .0001
|
||||
#define UNUSED 0.0 /* a dummy double parameter */
|
||||
|
||||
struct coord {
|
||||
double l; /* lat or lon in radians*/
|
||||
double s; /* sin */
|
||||
double c; /* cos */
|
||||
};
|
||||
struct place {
|
||||
struct coord nlat;
|
||||
struct coord wlon;
|
||||
};
|
||||
|
||||
typedef int (*proj)(struct place *, double *, double *);
|
||||
|
||||
struct index { /* index of known projections */
|
||||
char *name; /* name of projection */
|
||||
proj (*prog)(double, double);
|
||||
/* pointer to projection function */
|
||||
int npar; /* number of params */
|
||||
int (*cut)(struct place *, struct place *, double *);
|
||||
/* function that handles cuts--eg longitude 180 */
|
||||
int poles; /*1 S pole is a line, 2 N pole is, 3 both*/
|
||||
int spheroid; /* poles must be at 90 deg if nonzero */
|
||||
int (*limb)(double *lat, double *lon, double resolution);
|
||||
/* get next place on limb */
|
||||
/* return -1 if done, 0 at gap, else 1 */
|
||||
};
|
||||
|
||||
|
||||
proj aitoff(void);
|
||||
proj albers(double, double);
|
||||
int Xazequalarea(struct place *, double *, double *);
|
||||
proj azequalarea(void);
|
||||
int Xazequidistant(struct place *, double *, double *);
|
||||
proj azequidistant(void);
|
||||
proj bicentric(double);
|
||||
proj bonne(double);
|
||||
proj conic(double);
|
||||
proj cylequalarea(double);
|
||||
int Xcylindrical(struct place *, double *, double *);
|
||||
proj cylindrical(void);
|
||||
proj elliptic(double);
|
||||
proj fisheye(double);
|
||||
proj gall(double);
|
||||
proj gilbert(void);
|
||||
proj globular(void);
|
||||
proj gnomonic(void);
|
||||
int guycut(struct place *, struct place *, double *);
|
||||
int Xguyou(struct place *, double *, double *);
|
||||
proj guyou(void);
|
||||
proj harrison(double, double);
|
||||
int hexcut(struct place *, struct place *, double *);
|
||||
proj hex(void);
|
||||
proj homing(double);
|
||||
int hlimb(double*, double*, double resolution);
|
||||
proj lagrange(void);
|
||||
proj lambert(double, double);
|
||||
proj laue(void);
|
||||
proj lune(double, double);
|
||||
proj loxodromic(double); /* not in library */
|
||||
proj mecca(double);
|
||||
int mlimb(double*, double*, double resolution);
|
||||
proj mercator(void);
|
||||
proj mollweide(void);
|
||||
proj newyorker(double);
|
||||
proj ortelius(double, double); /* not in library */
|
||||
int Xorthographic(struct place *place, double *x, double *y);
|
||||
proj orthographic(void);
|
||||
int olimb(double*, double*, double);
|
||||
proj perspective(double);
|
||||
int plimb(double*, double*, double resolution);
|
||||
int Xpolyconic(struct place *, double *, double *);
|
||||
proj polyconic(void);
|
||||
proj rectangular(double);
|
||||
proj simpleconic(double, double);
|
||||
int Xsinusoidal(struct place *, double *, double *);
|
||||
proj sinusoidal(void);
|
||||
proj sp_albers(double, double);
|
||||
proj sp_mercator(void);
|
||||
proj square(void);
|
||||
int Xstereographic(struct place *, double *, double *);
|
||||
proj stereographic(void);
|
||||
int Xtetra(struct place *, double *, double *);
|
||||
int tetracut(struct place *, struct place *, double *);
|
||||
proj tetra(void);
|
||||
proj trapezoidal(double, double);
|
||||
proj vandergrinten(void);
|
||||
proj wreath(double, double); /* not in library */
|
||||
|
||||
void findxy(double, double *, double *);
|
||||
void albscale(double, double, double, double);
|
||||
void invalb(double, double, double *, double *);
|
||||
|
||||
void cdiv(double, double, double, double, double *, double *);
|
||||
void cmul(double, double, double, double, double *, double *);
|
||||
void cpow(double, double, double *, double *, double);
|
||||
void csq(double, double, double *, double *);
|
||||
void csqrt(double, double, double *, double *);
|
||||
void ccubrt(double, double, double *, double *);
|
||||
double cubrt(double);
|
||||
int elco2(double, double, double, double, double, double *, double *);
|
||||
void cdiv2(double, double, double, double, double *, double *);
|
||||
void csqr(double, double, double *, double *);
|
||||
|
||||
void orient(double, double, double);
|
||||
void latlon(double, double, struct place *);
|
||||
void deg2rad(double, struct coord *);
|
||||
void sincos(struct coord *);
|
||||
void normalize(struct place *);
|
||||
void invert(struct place *);
|
||||
void norm(struct place *, struct place *, struct coord *);
|
||||
void printp(struct place *);
|
||||
void copyplace(struct place *, struct place *);
|
||||
|
||||
int picut(struct place *, struct place *, double *);
|
||||
int ckcut(struct place *, struct place *, double);
|
||||
double reduce(double);
|
||||
|
||||
void getsyms(char *);
|
||||
int putsym(struct place *, char *, double, int);
|
||||
void filerror(char *s, char *f);
|
||||
void error(char *s);
|
||||
int doproj(struct place *, int *, int *);
|
||||
int cpoint(int, int, int);
|
||||
int plotpt(struct place *, int);
|
||||
int nocut(struct place *, struct place *, double *);
|
||||
|
||||
extern int (*projection)(struct place *, double *, double *);
|
||||
103
src/cmd/map/map.rc
Executable file
103
src/cmd/map/map.rc
Executable file
|
|
@ -0,0 +1,103 @@
|
|||
#!/bin/rc
|
||||
|
||||
rfork en
|
||||
|
||||
# F FEATUREs, M map files, A other arguments
|
||||
FEATURE=no
|
||||
|
||||
if (~ $MAPPROG '')
|
||||
MAPPROG=/bin/aux/mapd
|
||||
|
||||
if (~ $MAPDIR '')
|
||||
MAPDIR=/lib/map
|
||||
|
||||
F=(); M=(); A=();
|
||||
for (i) {
|
||||
switch ($FEATURE) {
|
||||
case no
|
||||
switch ($i) {
|
||||
case -f
|
||||
FEATURE=yes
|
||||
F=($F)
|
||||
case *
|
||||
A=($A $i)
|
||||
}
|
||||
case yes
|
||||
switch ($i) {
|
||||
case -f
|
||||
case -*
|
||||
A=($A $i)
|
||||
FEATURE=no
|
||||
case riv*2
|
||||
F=($F 201 202)
|
||||
case riv*3
|
||||
F=($F 201 202 203)
|
||||
case riv*4
|
||||
F=($F 201 202 203 204)
|
||||
case riv*
|
||||
F=($F 201)
|
||||
case iriv*2
|
||||
F=($F 206 207)
|
||||
case iriv*[34]
|
||||
F=($F 206 207 208)
|
||||
case iriv*
|
||||
F=($F 206)
|
||||
case coast*2 shore*2 lake*2
|
||||
F=($F 102)
|
||||
case coast*3 shore*3 lake*3
|
||||
F=($F 102 103)
|
||||
case coast*4 shore*4 lake*4
|
||||
F=($F 102 103 104)
|
||||
case coast* shore* lake*
|
||||
case ilake*[234] ishore*[234]
|
||||
F=($F 106 107)
|
||||
case ilake* ishore*
|
||||
F=($F 106)
|
||||
case reef*
|
||||
F=($F 108)
|
||||
case canal*2
|
||||
F=($F 210 211)
|
||||
case canal*[34]
|
||||
F=($F 210 211 212)
|
||||
case canal*
|
||||
F=($F 210)
|
||||
case glacier*
|
||||
F=($F 115)
|
||||
case state* province*
|
||||
F=($F 401)
|
||||
case countr*2
|
||||
F=($F 301 302)
|
||||
case countr*[34]
|
||||
F=($F 301 302 303)
|
||||
case countr*
|
||||
F=($F 301)
|
||||
case salt*[234]
|
||||
F=($F 109 110)
|
||||
case salt*
|
||||
F=($F 109)
|
||||
case ice*[234] shel*[234]
|
||||
F=($F 113 114)
|
||||
case ice* shel*
|
||||
F=($F 113)
|
||||
case *
|
||||
echo map: unknown feature $i >[1=2]
|
||||
exits "unknown feature"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j in $F) {
|
||||
if (test -r $MAPDIR/$j)
|
||||
M=($M $MAPDIR/$j)
|
||||
}
|
||||
|
||||
if (~ $F ?*) {
|
||||
if (test -r $MAPDIR/101)
|
||||
M=(101 $M)
|
||||
M=(-m $M)
|
||||
}
|
||||
|
||||
if (~ $MAP '')
|
||||
MAP=world
|
||||
|
||||
MAP=$MAP MAPDIR=$MAPDIR $MAPPROG $A $M
|
||||
83
src/cmd/map/mapdemo.rc
Executable file
83
src/cmd/map/mapdemo.rc
Executable file
|
|
@ -0,0 +1,83 @@
|
|||
#!/bin/rc
|
||||
|
||||
fn demo {proj=$1; shift;
|
||||
label=$1; shift;
|
||||
{ echo 'o'
|
||||
echo 'ra -8192 -8492 8192 8492'
|
||||
echo 'e'
|
||||
echo 'm -8192 8192'
|
||||
echo t $type
|
||||
echo 'm -8192 -8192'
|
||||
echo t $proj - $label
|
||||
MAP=world MAPDIR=/lib/map map $proj $* -s -d 5
|
||||
}
|
||||
sleep 5
|
||||
}
|
||||
|
||||
rfork en
|
||||
{
|
||||
type='Equatorial projections centered on long. 0. Parallels are straight lines.'
|
||||
|
||||
demo mercator 'equally spaced straight meridians, conformal, straight compass courses'
|
||||
demo sinusoidal 'equally spaced parallels, equal-area, same as bonne(0)'
|
||||
demo cylequalarea 'equally spaced straight meridians, equal-area, true scale on Eq' 0
|
||||
demo cylindrical 'central projection on tangent cylinder'
|
||||
demo rectangular 'equally spaced parallels, equally spaced straight meridians, true scale on Eq' 0
|
||||
demo gall 'parallels spaced stereographically on prime meridian, equally spaced straight meridians, true scale on Eq' 0
|
||||
demo mollweide '(homalographic) equal-area, hemisphere is a circle'
|
||||
demo gilbert 'globe mapped conformally on hemisphere, viewed orthographically'
|
||||
|
||||
type='Azimuthal: centered on the North Pole, Parallels are concentric circles, Meridians are equally spaced radial lines'
|
||||
|
||||
demo azequidistant 'equally spaced parallels, true distances from pole'
|
||||
demo azequalarea 'equal area'
|
||||
demo gnomonic 'central projecton on tangent plane, straight great circles'
|
||||
demo perspective 'viewed along earth''s axis 2 earth radii from center of earth' 2
|
||||
demo orthographic 'viewed from infinity'
|
||||
demo stereographic 'conformal, projected from opposite pole'
|
||||
demo laue 'radius = tan(2\(mu colatitude ), used in xray crystallography'
|
||||
demo fisheye 'fisheye view of stereographic map, index of refraction 2' 2 -o 40.75 74
|
||||
demo newyorker 'New Yorker map from viewing pedestal of radius .5' .5 -o 40.75 74
|
||||
|
||||
type='Polar conic projections symmetric about the Prime Meridian. Parallels are segments of concentric circles.'
|
||||
|
||||
demo conic 'central projection on cone tangent at 40' 40
|
||||
demo simpleconic 'equally spaced parallels, true scale on 20 and 50' 20 50
|
||||
demo lambert 'conformal, true scale on 20 and 50' 20 50
|
||||
demo albers 'equal-area, true scale on 20 and 50' 20 50
|
||||
demo bonne 'equally spaced parallels, equal-area, parallel 40 developed from tangent cone' 40
|
||||
|
||||
type='Projections with bilateral symmetry about the Prime Meridian and the equator.'
|
||||
|
||||
demo polyconic 'parallels developed from tangent cones, equally spaced along Prime Meridian'
|
||||
demo aitoff 'equal-area projection of globe onto 2-to-1 ellipse, based on azequalarea'
|
||||
demo lagrange 'conformal, maps whole sphere into a circle'
|
||||
demo bicentric 'points plotted at true azimuth from two centers on the equator at longitudes +-40, great circles are straight lines' 40
|
||||
demo elliptic 'points are plotted at true distance from two centers on the equator at longitudes +-40' 40
|
||||
demo globular 'hemisphere is circle, circular meridians and parallels'
|
||||
demo vandergrinten 'sphere is circle, meridians as in globular, circular arc parallels resemble mercator'
|
||||
|
||||
type='Doubly periodic conformal projections.'
|
||||
|
||||
demo guyou 'W and E hemispheres are square'
|
||||
demo square 'World is square with Poles at diagonally opposite corners'
|
||||
demo tetra 'map on tetrahedron with edge tangent to Prime Meridian at S Pole, unfolded into equilateral triangle'
|
||||
demo hex 'world is hexagon centered on N Pole, N and S hemispheres are equilateral
|
||||
triangles'
|
||||
|
||||
type='Retroazimuthal projections. Directions to center are true.'
|
||||
|
||||
demo mecca 'equally spaced vertical meridians' 21.4 -o 90 -39.8
|
||||
demo homing 'distances to Mecca are true' 21.4 -o 90 -39.8
|
||||
|
||||
type='Miscellaneous projections.'
|
||||
|
||||
demo harrison 'oblique perspective from above the North Pole, 2 earth radii from the earth, looking along the Date Line 40 degrees off vertical' 2 40
|
||||
demo trapezoidal 'equally spaced parallels, straight meridians equally spaced along parallels, true scale at 20 and 50 on Prime Meridian' 20 50
|
||||
demo lune 'conformal, polar cap above Eq is 60-degree lune' 0 60
|
||||
|
||||
type='Maps based on the spheroid'
|
||||
|
||||
demo sp_mercator 'equally spaced straight meridians, conformal'
|
||||
demo sp_albers 'equal-area, true scale on 20 and 50' 20 50
|
||||
} | plot
|
||||
32
src/cmd/map/mkfile
Normal file
32
src/cmd/map/mkfile
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<$PLAN9/src/mkhdr
|
||||
|
||||
TARG=mapd
|
||||
LIB=libmap/libmap.a
|
||||
OFILES=map.$O\
|
||||
symbol.$O\
|
||||
index.$O\
|
||||
sqrt.$O\
|
||||
|
||||
HFILES=map.h\
|
||||
iplot.h\
|
||||
|
||||
<$PLAN9/src/mkone
|
||||
|
||||
|
||||
$O.out:V: $OFILES $LIB
|
||||
$LD $LDFLAGS -o $target $prereq
|
||||
|
||||
$LIB:V:
|
||||
cd libmap
|
||||
mk install
|
||||
|
||||
installall:V:
|
||||
for(objtype in $CPUS)
|
||||
mk install
|
||||
cp map.rc /rc/bin/map
|
||||
cp mapdemo.rc /rc/bin/mapdemo
|
||||
|
||||
clean nuke:V:
|
||||
rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG
|
||||
cd libmap; mk clean
|
||||
|
||||
131
src/cmd/map/route.c
Normal file
131
src/cmd/map/route.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "map.h"
|
||||
|
||||
/* Given two lat-lon pairs, find an orientation for the
|
||||
-o option of "map" that will place those two points
|
||||
on the equator of a standard projection, equally spaced
|
||||
about the prime meridian.
|
||||
|
||||
-w and -l options are suggested also.
|
||||
|
||||
Option -t prints out a series of
|
||||
coordinates that follows the (great circle) track
|
||||
in the original coordinate system,
|
||||
followed by ".
|
||||
This data is just right for map -t.
|
||||
|
||||
Option -i inverts the map top-to-bottom.
|
||||
*/
|
||||
struct place pole;
|
||||
struct coord twist;
|
||||
int track;
|
||||
int inv = -1;
|
||||
|
||||
extern void doroute(double, double, double, double, double);
|
||||
|
||||
void
|
||||
dorot(double a, double b, double *x, double *y, void (*f)(struct place *))
|
||||
{
|
||||
struct place g;
|
||||
deg2rad(a,&g.nlat);
|
||||
deg2rad(b,&g.wlon);
|
||||
(*f)(&g);
|
||||
*x = g.nlat.l/RAD;
|
||||
*y = g.wlon.l/RAD;
|
||||
}
|
||||
|
||||
void
|
||||
rotate(double a, double b, double *x, double *y)
|
||||
{
|
||||
dorot(a,b,x,y,normalize);
|
||||
}
|
||||
|
||||
void
|
||||
rinvert(double a, double b, double *x, double *y)
|
||||
{
|
||||
dorot(a,b,x,y,invert);
|
||||
}
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
#pragma ref argv
|
||||
double an,aw,bn,bw;
|
||||
ARGBEGIN {
|
||||
case 't':
|
||||
track = 1;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
inv = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
exits("route: bad option");
|
||||
} ARGEND;
|
||||
if (argc<4) {
|
||||
print("use route [-t] [-i] lat lon lat lon\n");
|
||||
exits("arg count");
|
||||
}
|
||||
an = atof(argv[0]);
|
||||
aw = atof(argv[1]);
|
||||
bn = atof(argv[2]);
|
||||
bw = atof(argv[3]);
|
||||
doroute(inv*90.,an,aw,bn,bw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
doroute(double dir, double an, double aw, double bn, double bw)
|
||||
{
|
||||
double an1,aw1,bn1,bw1,pn,pw;
|
||||
double theta;
|
||||
double cn,cw,cn1,cw1;
|
||||
int i,n;
|
||||
orient(an,aw,0.);
|
||||
rotate(bn,bw,&bn1,&bw1);
|
||||
/* printf("b %f %f\n",bn1,bw1);*/
|
||||
orient(an,aw,bw1);
|
||||
rinvert(0.,dir,&pn,&pw);
|
||||
/* printf("p %f %f\n",pn,pw);*/
|
||||
orient(pn,pw,0.);
|
||||
rotate(an,aw,&an1,&aw1);
|
||||
rotate(bn,bw,&bn1,&bw1);
|
||||
theta = (aw1+bw1)/2;
|
||||
/* printf("a %f %f \n",an1,aw1);*/
|
||||
orient(pn,pw,theta);
|
||||
rotate(an,aw,&an1,&aw1);
|
||||
rotate(bn,bw,&bn1,&bw1);
|
||||
if(fabs(aw1-bw1)>180)
|
||||
if(theta<0.) theta+=180;
|
||||
else theta -= 180;
|
||||
orient(pn,pw,theta);
|
||||
rotate(an,aw,&an1,&aw1);
|
||||
rotate(bn,bw,&bn1,&bw1);
|
||||
if(!track) {
|
||||
double dlat, dlon, t;
|
||||
/* printf("A %.4f %.4f\n",an1,aw1); */
|
||||
/* printf("B %.4f %.4f\n",bn1,bw1); */
|
||||
cw1 = fabs(bw1-aw1); /* angular difference for map margins */
|
||||
/* while (aw<0.0)
|
||||
aw += 360.;
|
||||
while (bw<0.0)
|
||||
bw += 360.; */
|
||||
dlon = fabs(aw-bw);
|
||||
if (dlon>180)
|
||||
dlon = 360-dlon;
|
||||
dlat = fabs(an-bn);
|
||||
printf("-o %.4f %.4f %.4f -w %.2f %.2f %.2f %.2f \n",
|
||||
pn,pw,theta, -0.3*cw1, .3*cw1, -.6*cw1, .6*cw1);
|
||||
|
||||
} else {
|
||||
cn1 = 0;
|
||||
n = 1 + fabs(bw1-aw1)/.2;
|
||||
for(i=0;i<=n;i++) {
|
||||
cw1 = aw1 + i*(bw1-aw1)/n;
|
||||
rinvert(cn1,cw1,&cn,&cw);
|
||||
printf("%f %f\n",cn,cw);
|
||||
}
|
||||
printf("\"\n");
|
||||
}
|
||||
}
|
||||
52
src/cmd/map/sqrt.c
Normal file
52
src/cmd/map/sqrt.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
sqrt returns the square root of its floating
|
||||
point argument. Newton's method.
|
||||
|
||||
calls frexp
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
double
|
||||
sqrt(double arg)
|
||||
{
|
||||
double x, temp;
|
||||
int exp, i;
|
||||
|
||||
if(arg <= 0) {
|
||||
if(arg < 0)
|
||||
return 0.;
|
||||
return 0;
|
||||
}
|
||||
x = frexp(arg, &exp);
|
||||
while(x < 0.5) {
|
||||
x *= 2;
|
||||
exp--;
|
||||
}
|
||||
/*
|
||||
* NOTE
|
||||
* this wont work on 1's comp
|
||||
*/
|
||||
if(exp & 1) {
|
||||
x *= 2;
|
||||
exp--;
|
||||
}
|
||||
temp = 0.5 * (1.0+x);
|
||||
|
||||
while(exp > 60) {
|
||||
temp *= (1L<<30);
|
||||
exp -= 60;
|
||||
}
|
||||
while(exp < -60) {
|
||||
temp /= (1L<<30);
|
||||
exp += 60;
|
||||
}
|
||||
if(exp >= 0)
|
||||
temp *= 1L << (exp/2);
|
||||
else
|
||||
temp /= 1L << (-exp/2);
|
||||
for(i=0; i<=4; i++)
|
||||
temp = 0.5*(temp + arg/temp);
|
||||
return temp;
|
||||
}
|
||||
192
src/cmd/map/symbol.c
Normal file
192
src/cmd/map/symbol.c
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <stdio.h>
|
||||
#include "map.h"
|
||||
#include "iplot.h"
|
||||
|
||||
#define NSYMBOL 20
|
||||
|
||||
enum flag { POINT,ENDSEG,ENDSYM };
|
||||
struct symb {
|
||||
double x, y;
|
||||
char name[10+1];
|
||||
enum flag flag;
|
||||
} *symbol[NSYMBOL];
|
||||
|
||||
static int nsymbol;
|
||||
static double halfrange = 1;
|
||||
extern int halfwidth;
|
||||
extern int vflag;
|
||||
|
||||
static int getrange(FILE *);
|
||||
static int getsymbol(FILE *, int);
|
||||
static void setrot(struct place *, double, int);
|
||||
static void dorot(struct symb *, double *, double *);
|
||||
|
||||
|
||||
void
|
||||
getsyms(char *file)
|
||||
{
|
||||
FILE *sf = fopen(file,"r");
|
||||
if(sf==0)
|
||||
filerror("cannot open", file);
|
||||
while(nsymbol<NSYMBOL-1 && getsymbol(sf,nsymbol))
|
||||
nsymbol++;
|
||||
fclose(sf);
|
||||
}
|
||||
|
||||
static int
|
||||
getsymbol(FILE *sf, int n)
|
||||
{
|
||||
double x,y;
|
||||
char s[2];
|
||||
int i;
|
||||
struct symb *sp;
|
||||
for(;;) {
|
||||
if(fscanf(sf,"%1s",s)==EOF)
|
||||
return 0;
|
||||
switch(s[0]) {
|
||||
case ':':
|
||||
break;
|
||||
case 'o':
|
||||
case 'c': /* cl */
|
||||
fscanf(sf,"%*[^\n]");
|
||||
continue;
|
||||
case 'r':
|
||||
if(getrange(sf))
|
||||
continue;
|
||||
default:
|
||||
error("-y file syntax error");
|
||||
}
|
||||
break;
|
||||
}
|
||||
sp = (struct symb*)malloc(sizeof(struct symb));
|
||||
symbol[n] = sp;
|
||||
if(fscanf(sf,"%10s",sp->name)!=1)
|
||||
return 0;
|
||||
i = 0;
|
||||
while(fscanf(sf,"%1s",s)!=EOF) {
|
||||
switch(s[0]) {
|
||||
case 'r':
|
||||
if(!getrange(sf))
|
||||
break;
|
||||
continue;
|
||||
case 'm':
|
||||
if(i>0)
|
||||
symbol[n][i-1].flag = ENDSEG;
|
||||
continue;
|
||||
case ':':
|
||||
ungetc(s[0],sf);
|
||||
break;
|
||||
default:
|
||||
ungetc(s[0],sf);
|
||||
case 'v':
|
||||
if(fscanf(sf,"%lf %lf",&x,&y)!=2)
|
||||
break;
|
||||
sp[i].x = x*halfwidth/halfrange;
|
||||
sp[i].y = y*halfwidth/halfrange;
|
||||
sp[i].flag = POINT;
|
||||
i++;
|
||||
sp = symbol[n] = (struct symb*)realloc(symbol[n],
|
||||
(i+1)*sizeof(struct symb));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(i>0)
|
||||
symbol[n][i-1].flag = ENDSYM;
|
||||
else
|
||||
symbol[n] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
getrange(FILE *sf)
|
||||
{
|
||||
double x,y,xmin,ymin;
|
||||
if(fscanf(sf,"%*s %lf %lf %lf %lf",
|
||||
&xmin,&ymin,&x,&y)!=4)
|
||||
return 0;
|
||||
x -= xmin;
|
||||
y -= ymin;
|
||||
halfrange = (x>y? x: y)/2;
|
||||
if(halfrange<=0)
|
||||
error("bad ra command in -y file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* r=0 upright;=1 normal;=-1 reverse*/
|
||||
int
|
||||
putsym(struct place *p, char *name, double s, int r)
|
||||
{
|
||||
int x,y,n;
|
||||
struct symb *sp;
|
||||
double dx,dy;
|
||||
int conn = 0;
|
||||
for(n=0; symbol[n]; n++)
|
||||
if(strcmp(name,symbol[n]->name)==0)
|
||||
break;
|
||||
sp = symbol[n];
|
||||
if(sp==0)
|
||||
return 0;
|
||||
if(doproj(p,&x,&y)*vflag <= 0)
|
||||
return 1;
|
||||
setrot(p,s,r);
|
||||
for(;;) {
|
||||
dorot(sp,&dx,&dy);
|
||||
conn = cpoint(x+(int)dx,y+(int)dy,conn);
|
||||
switch(sp->flag) {
|
||||
case ENDSEG:
|
||||
conn = 0;
|
||||
case POINT:
|
||||
sp++;
|
||||
continue;
|
||||
case ENDSYM:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static double rot[2][2];
|
||||
|
||||
static void
|
||||
setrot(struct place *p, double s, int r)
|
||||
{
|
||||
double x0,y0,x1,y1;
|
||||
struct place up;
|
||||
up = *p;
|
||||
up.nlat.l += .5*RAD;
|
||||
sincos(&up.nlat);
|
||||
if(r&&(*projection)(p,&x0,&y0)) {
|
||||
if((*projection)(&up,&x1,&y1)<=0) {
|
||||
up.nlat.l -= RAD;
|
||||
sincos(&up.nlat);
|
||||
if((*projection)(&up,&x1,&y1)<=0)
|
||||
goto unit;
|
||||
x1 = x0 - x1;
|
||||
y1 = y0 - y1;
|
||||
} else {
|
||||
x1 -= x0;
|
||||
y1 -= y0;
|
||||
}
|
||||
x1 = r*x1;
|
||||
s /= hypot(x1,y1);
|
||||
rot[0][0] = y1*s;
|
||||
rot[0][1] = x1*s;
|
||||
rot[1][0] = -x1*s;
|
||||
rot[1][1] = y1*s;
|
||||
} else {
|
||||
unit:
|
||||
rot[0][0] = rot[1][1] = s;
|
||||
rot[0][1] = rot[1][0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dorot(struct symb *sp, double *px, double *py)
|
||||
{
|
||||
*px = rot[0][0]*sp->x + rot[0][1]*sp->y;
|
||||
*py = rot[1][0]*sp->x + rot[1][1]*sp->y;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue