route.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include <u.h>
  2. #include <libc.h>
  3. #include "map.h"
  4. /* Given two lat-lon pairs, find an orientation for the
  5. -o option of "map" that will place those two points
  6. on the equator of a standard projection, equally spaced
  7. about the prime meridian.
  8. -w and -l options are suggested also.
  9. Option -t prints out a series of
  10. coordinates that follows the (great circle) track
  11. in the original coordinate system,
  12. followed by ".
  13. This data is just right for map -t.
  14. Option -i inverts the map top-to-bottom.
  15. */
  16. struct place pole;
  17. struct coord twist;
  18. int track;
  19. int inv = -1;
  20. extern void doroute(double, double, double, double, double);
  21. void
  22. dorot(double a, double b, double *x, double *y, void (*f)(struct place *))
  23. {
  24. struct place g;
  25. deg2rad(a,&g.nlat);
  26. deg2rad(b,&g.wlon);
  27. (*f)(&g);
  28. *x = g.nlat.l/RAD;
  29. *y = g.wlon.l/RAD;
  30. }
  31. void
  32. rotate(double a, double b, double *x, double *y)
  33. {
  34. dorot(a,b,x,y,normalize);
  35. }
  36. void
  37. rinvert(double a, double b, double *x, double *y)
  38. {
  39. dorot(a,b,x,y,invert);
  40. }
  41. main(int argc, char **argv)
  42. {
  43. #pragma ref argv
  44. double an,aw,bn,bw;
  45. ARGBEGIN {
  46. case 't':
  47. track = 1;
  48. break;
  49. case 'i':
  50. inv = 1;
  51. break;
  52. default:
  53. exits("route: bad option");
  54. } ARGEND;
  55. if (argc<4) {
  56. print("use route [-t] [-i] lat lon lat lon\n");
  57. exits("arg count");
  58. }
  59. an = atof(argv[0]);
  60. aw = atof(argv[1]);
  61. bn = atof(argv[2]);
  62. bw = atof(argv[3]);
  63. doroute(inv*90.,an,aw,bn,bw);
  64. return 0;
  65. }
  66. void
  67. doroute(double dir, double an, double aw, double bn, double bw)
  68. {
  69. double an1,aw1,bn1,bw1,pn,pw;
  70. double theta;
  71. double cn,cw,cn1,cw1;
  72. int i,n;
  73. orient(an,aw,0.);
  74. rotate(bn,bw,&bn1,&bw1);
  75. /* printf("b %f %f\n",bn1,bw1);*/
  76. orient(an,aw,bw1);
  77. rinvert(0.,dir,&pn,&pw);
  78. /* printf("p %f %f\n",pn,pw);*/
  79. orient(pn,pw,0.);
  80. rotate(an,aw,&an1,&aw1);
  81. rotate(bn,bw,&bn1,&bw1);
  82. theta = (aw1+bw1)/2;
  83. /* printf("a %f %f \n",an1,aw1);*/
  84. orient(pn,pw,theta);
  85. rotate(an,aw,&an1,&aw1);
  86. rotate(bn,bw,&bn1,&bw1);
  87. if(fabs(aw1-bw1)>180)
  88. if(theta<0.) theta+=180;
  89. else theta -= 180;
  90. orient(pn,pw,theta);
  91. rotate(an,aw,&an1,&aw1);
  92. rotate(bn,bw,&bn1,&bw1);
  93. if(!track) {
  94. double dlat, dlon, t;
  95. /* printf("A %.4f %.4f\n",an1,aw1); */
  96. /* printf("B %.4f %.4f\n",bn1,bw1); */
  97. cw1 = fabs(bw1-aw1); /* angular difference for map margins */
  98. /* while (aw<0.0)
  99. aw += 360.;
  100. while (bw<0.0)
  101. bw += 360.; */
  102. dlon = fabs(aw-bw);
  103. if (dlon>180)
  104. dlon = 360-dlon;
  105. dlat = fabs(an-bn);
  106. printf("-o %.4f %.4f %.4f -w %.2f %.2f %.2f %.2f \n",
  107. pn,pw,theta, -0.3*cw1, .3*cw1, -.6*cw1, .6*cw1);
  108. } else {
  109. cn1 = 0;
  110. n = 1 + fabs(bw1-aw1)/.2;
  111. for(i=0;i<=n;i++) {
  112. cw1 = aw1 + i*(bw1-aw1)/n;
  113. rinvert(cn1,cw1,&cn,&cw);
  114. printf("%f %f\n",cn,cw);
  115. }
  116. printf("\"\n");
  117. }
  118. }