1*59cc4ca5SDavid du Colombier #include <u.h>
2*59cc4ca5SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include "map.h"
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier /* Given two lat-lon pairs, find an orientation for the
67dd7cddfSDavid du Colombier -o option of "map" that will place those two points
77dd7cddfSDavid du Colombier on the equator of a standard projection, equally spaced
87dd7cddfSDavid du Colombier about the prime meridian.
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier -w and -l options are suggested also.
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier Option -t prints out a series of
137dd7cddfSDavid du Colombier coordinates that follows the (great circle) track
147dd7cddfSDavid du Colombier in the original coordinate system,
157dd7cddfSDavid du Colombier followed by ".
167dd7cddfSDavid du Colombier This data is just right for map -t.
177dd7cddfSDavid du Colombier
187dd7cddfSDavid du Colombier Option -i inverts the map top-to-bottom.
197dd7cddfSDavid du Colombier */
207dd7cddfSDavid du Colombier struct place pole;
217dd7cddfSDavid du Colombier struct coord twist;
227dd7cddfSDavid du Colombier int track;
237dd7cddfSDavid du Colombier int inv = -1;
247dd7cddfSDavid du Colombier
257dd7cddfSDavid du Colombier extern void doroute(double, double, double, double, double);
267dd7cddfSDavid du Colombier
277dd7cddfSDavid du Colombier void
dorot(double a,double b,double * x,double * y,void (* f)(struct place *))287dd7cddfSDavid du Colombier dorot(double a, double b, double *x, double *y, void (*f)(struct place *))
297dd7cddfSDavid du Colombier {
307dd7cddfSDavid du Colombier struct place g;
317dd7cddfSDavid du Colombier deg2rad(a,&g.nlat);
327dd7cddfSDavid du Colombier deg2rad(b,&g.wlon);
337dd7cddfSDavid du Colombier (*f)(&g);
347dd7cddfSDavid du Colombier *x = g.nlat.l/RAD;
357dd7cddfSDavid du Colombier *y = g.wlon.l/RAD;
367dd7cddfSDavid du Colombier }
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier void
rotate(double a,double b,double * x,double * y)397dd7cddfSDavid du Colombier rotate(double a, double b, double *x, double *y)
407dd7cddfSDavid du Colombier {
417dd7cddfSDavid du Colombier dorot(a,b,x,y,normalize);
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier void
rinvert(double a,double b,double * x,double * y)457dd7cddfSDavid du Colombier rinvert(double a, double b, double *x, double *y)
467dd7cddfSDavid du Colombier {
477dd7cddfSDavid du Colombier dorot(a,b,x,y,invert);
487dd7cddfSDavid du Colombier }
497dd7cddfSDavid du Colombier
main(int argc,char ** argv)507dd7cddfSDavid du Colombier main(int argc, char **argv)
517dd7cddfSDavid du Colombier {
527dd7cddfSDavid du Colombier #pragma ref argv
537dd7cddfSDavid du Colombier double an,aw,bn,bw;
547dd7cddfSDavid du Colombier ARGBEGIN {
557dd7cddfSDavid du Colombier case 't':
567dd7cddfSDavid du Colombier track = 1;
577dd7cddfSDavid du Colombier break;
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier case 'i':
607dd7cddfSDavid du Colombier inv = 1;
617dd7cddfSDavid du Colombier break;
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier default:
647dd7cddfSDavid du Colombier exits("route: bad option");
657dd7cddfSDavid du Colombier } ARGEND;
667dd7cddfSDavid du Colombier if (argc<4) {
677dd7cddfSDavid du Colombier print("use route [-t] [-i] lat lon lat lon\n");
687dd7cddfSDavid du Colombier exits("arg count");
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier an = atof(argv[0]);
717dd7cddfSDavid du Colombier aw = atof(argv[1]);
727dd7cddfSDavid du Colombier bn = atof(argv[2]);
737dd7cddfSDavid du Colombier bw = atof(argv[3]);
747dd7cddfSDavid du Colombier doroute(inv*90.,an,aw,bn,bw);
757dd7cddfSDavid du Colombier return 0;
767dd7cddfSDavid du Colombier }
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier void
doroute(double dir,double an,double aw,double bn,double bw)797dd7cddfSDavid du Colombier doroute(double dir, double an, double aw, double bn, double bw)
807dd7cddfSDavid du Colombier {
817dd7cddfSDavid du Colombier double an1,aw1,bn1,bw1,pn,pw;
827dd7cddfSDavid du Colombier double theta;
837dd7cddfSDavid du Colombier double cn,cw,cn1,cw1;
847dd7cddfSDavid du Colombier int i,n;
857dd7cddfSDavid du Colombier orient(an,aw,0.);
867dd7cddfSDavid du Colombier rotate(bn,bw,&bn1,&bw1);
877dd7cddfSDavid du Colombier /* printf("b %f %f\n",bn1,bw1);*/
887dd7cddfSDavid du Colombier orient(an,aw,bw1);
897dd7cddfSDavid du Colombier rinvert(0.,dir,&pn,&pw);
907dd7cddfSDavid du Colombier /* printf("p %f %f\n",pn,pw);*/
917dd7cddfSDavid du Colombier orient(pn,pw,0.);
927dd7cddfSDavid du Colombier rotate(an,aw,&an1,&aw1);
937dd7cddfSDavid du Colombier rotate(bn,bw,&bn1,&bw1);
947dd7cddfSDavid du Colombier theta = (aw1+bw1)/2;
957dd7cddfSDavid du Colombier /* printf("a %f %f \n",an1,aw1);*/
967dd7cddfSDavid du Colombier orient(pn,pw,theta);
977dd7cddfSDavid du Colombier rotate(an,aw,&an1,&aw1);
987dd7cddfSDavid du Colombier rotate(bn,bw,&bn1,&bw1);
997dd7cddfSDavid du Colombier if(fabs(aw1-bw1)>180)
1007dd7cddfSDavid du Colombier if(theta<0.) theta+=180;
1017dd7cddfSDavid du Colombier else theta -= 180;
1027dd7cddfSDavid du Colombier orient(pn,pw,theta);
1037dd7cddfSDavid du Colombier rotate(an,aw,&an1,&aw1);
1047dd7cddfSDavid du Colombier rotate(bn,bw,&bn1,&bw1);
1057dd7cddfSDavid du Colombier if(!track) {
1067dd7cddfSDavid du Colombier double dlat, dlon, t;
1077dd7cddfSDavid du Colombier /* printf("A %.4f %.4f\n",an1,aw1); */
1087dd7cddfSDavid du Colombier /* printf("B %.4f %.4f\n",bn1,bw1); */
1097dd7cddfSDavid du Colombier cw1 = fabs(bw1-aw1); /* angular difference for map margins */
1107dd7cddfSDavid du Colombier /* while (aw<0.0)
1117dd7cddfSDavid du Colombier aw += 360.;
1127dd7cddfSDavid du Colombier while (bw<0.0)
1137dd7cddfSDavid du Colombier bw += 360.; */
1147dd7cddfSDavid du Colombier dlon = fabs(aw-bw);
1157dd7cddfSDavid du Colombier if (dlon>180)
1167dd7cddfSDavid du Colombier dlon = 360-dlon;
1177dd7cddfSDavid du Colombier dlat = fabs(an-bn);
1187dd7cddfSDavid du Colombier printf("-o %.4f %.4f %.4f -w %.2f %.2f %.2f %.2f \n",
1197dd7cddfSDavid du Colombier pn,pw,theta, -0.3*cw1, .3*cw1, -.6*cw1, .6*cw1);
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier } else {
1227dd7cddfSDavid du Colombier cn1 = 0;
1237dd7cddfSDavid du Colombier n = 1 + fabs(bw1-aw1)/.2;
1247dd7cddfSDavid du Colombier for(i=0;i<=n;i++) {
1257dd7cddfSDavid du Colombier cw1 = aw1 + i*(bw1-aw1)/n;
1267dd7cddfSDavid du Colombier rinvert(cn1,cw1,&cn,&cw);
1277dd7cddfSDavid du Colombier printf("%f %f\n",cn,cw);
1287dd7cddfSDavid du Colombier }
1297dd7cddfSDavid du Colombier printf("\"\n");
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier }
132