zcoord.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <stdio.h>
  4. #include "map.h"
  5. static double cirmod(double);
  6. static struct place pole; /* map pole is tilted to here */
  7. static struct coord twist; /* then twisted this much */
  8. static struct place ipole; /* inverse transfrom */
  9. static struct coord itwist;
  10. void
  11. orient(double lat, double lon, double theta)
  12. {
  13. lat = cirmod(lat);
  14. if(lat>90.) {
  15. lat = 180. - lat;
  16. lon -= 180.;
  17. theta -= 180.;
  18. } else if(lat < -90.) {
  19. lat = -180. - lat;
  20. lon -= 180.;
  21. theta -= 180;
  22. }
  23. latlon(lat,lon,&pole);
  24. deg2rad(theta, &twist);
  25. latlon(lat,180.-theta,&ipole);
  26. deg2rad(180.-lon, &itwist);
  27. }
  28. void
  29. latlon(double lat, double lon, struct place *p)
  30. {
  31. lat = cirmod(lat);
  32. if(lat>90.) {
  33. lat = 180. - lat;
  34. lon -= 180.;
  35. } else if(lat < -90.) {
  36. lat = -180. - lat;
  37. lon -= 180.;
  38. }
  39. deg2rad(lat,&p->nlat);
  40. deg2rad(lon,&p->wlon);
  41. }
  42. void
  43. deg2rad(double theta, struct coord *coord)
  44. {
  45. theta = cirmod(theta);
  46. coord->l = theta*RAD;
  47. if(theta==90) {
  48. coord->s = 1;
  49. coord->c = 0;
  50. } else if(theta== -90) {
  51. coord->s = -1;
  52. coord->c = 0;
  53. } else
  54. sincos(coord);
  55. }
  56. static double
  57. cirmod(double theta)
  58. {
  59. while(theta >= 180.)
  60. theta -= 360;
  61. while(theta<-180.)
  62. theta += 360.;
  63. return(theta);
  64. }
  65. void
  66. sincos(struct coord *coord)
  67. {
  68. coord->s = sin(coord->l);
  69. coord->c = cos(coord->l);
  70. }
  71. void
  72. normalize(struct place *gg)
  73. {
  74. norm(gg,&pole,&twist);
  75. }
  76. void
  77. invert(struct place *g)
  78. {
  79. norm(g,&ipole,&itwist);
  80. }
  81. void
  82. norm(struct place *gg, struct place *pp, struct coord *tw)
  83. {
  84. register struct place *g; /*geographic coords */
  85. register struct place *p; /* new pole in old coords*/
  86. struct place m; /* standard map coords*/
  87. g = gg;
  88. p = pp;
  89. if(p->nlat.s == 1.) {
  90. if(p->wlon.l+tw->l == 0.)
  91. return;
  92. g->wlon.l -= p->wlon.l+tw->l;
  93. } else {
  94. if(p->wlon.l != 0) {
  95. g->wlon.l -= p->wlon.l;
  96. sincos(&g->wlon);
  97. }
  98. m.nlat.s = p->nlat.s * g->nlat.s
  99. + p->nlat.c * g->nlat.c * g->wlon.c;
  100. m.nlat.c = sqrt(1. - m.nlat.s * m.nlat.s);
  101. m.nlat.l = atan2(m.nlat.s, m.nlat.c);
  102. m.wlon.s = g->nlat.c * g->wlon.s;
  103. m.wlon.c = p->nlat.c * g->nlat.s
  104. - p->nlat.s * g->nlat.c * g->wlon.c;
  105. m.wlon.l = atan2(m.wlon.s, - m.wlon.c)
  106. - tw->l;
  107. *g = m;
  108. }
  109. sincos(&g->wlon);
  110. if(g->wlon.l>PI)
  111. g->wlon.l -= 2*PI;
  112. else if(g->wlon.l<-PI)
  113. g->wlon.l += 2*PI;
  114. }
  115. double
  116. tan(double x)
  117. {
  118. return(sin(x)/cos(x));
  119. }
  120. void
  121. printp(struct place *g)
  122. {
  123. printf("%.3f %.3f %.3f %.3f %.3f %.3f\n",
  124. g->nlat.l,g->nlat.s,g->nlat.c,g->wlon.l,g->wlon.s,g->wlon.c);
  125. }
  126. void
  127. copyplace(struct place *g1, struct place *g2)
  128. {
  129. *g2 = *g1;
  130. }