|  | #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"); | 
|  | } | 
|  | } |