route.c 3.1 KB

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