moon.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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 "astro.h"
  10. double k1, k2, k3, k4;
  11. double mnom, msun, noded, dmoon;
  12. void
  13. moon(void)
  14. {
  15. Moontab *mp;
  16. double dlong, lsun, psun;
  17. double eccm, eccs, chp, cpe;
  18. double v0, t0, m0, j0;
  19. double arg1, arg2, arg3, arg4, arg5, arg6, arg7;
  20. double arg8, arg9, arg10;
  21. double dgamma, k5, k6;
  22. double lterms, sterms, cterms, nterms, pterms, spterms;
  23. double gamma1, gamma2, gamma3, arglat;
  24. double xmp, ymp, zmp;
  25. double obl2;
  26. /*
  27. * the fundamental elements - all referred to the epoch of
  28. * Jan 0.5, 1900 and to the mean equinox of date.
  29. */
  30. dlong = 270.434164 + 13.1763965268*eday - .001133*capt2
  31. + 2.e-6*capt3;
  32. argp = 334.329556 + .1114040803*eday - .010325*capt2
  33. - 12.e-6*capt3;
  34. node = 259.183275 - .0529539222*eday + .002078*capt2
  35. + 2.e-6*capt3;
  36. lsun = 279.696678 + .9856473354*eday + .000303*capt2;
  37. psun = 281.220833 + .0000470684*eday + .000453*capt2
  38. + 3.e-6*capt3;
  39. dlong = fmod(dlong, 360.);
  40. argp = fmod(argp, 360.);
  41. node = fmod(node, 360.);
  42. lsun = fmod(lsun, 360.);
  43. psun = fmod(psun, 360.);
  44. eccm = 22639.550;
  45. eccs = .01675104 - .00004180*capt;
  46. incl = 18461.400;
  47. cpe = 124.986;
  48. chp = 3422.451;
  49. /*
  50. * some subsidiary elements - they are all longitudes
  51. * and they are referred to the epoch 1/0.5 1900 and
  52. * to the fixed mean equinox of 1850.0.
  53. */
  54. v0 = 342.069128 + 1.6021304820*eday;
  55. t0 = 98.998753 + 0.9856091138*eday;
  56. m0 = 293.049675 + 0.5240329445*eday;
  57. j0 = 237.352319 + 0.0830912295*eday;
  58. /*
  59. * the following are periodic corrections to the
  60. * fundamental elements and constants.
  61. * arg3 is the "Great Venus Inequality".
  62. */
  63. arg1 = 41.1 + 20.2*(capt+.5);
  64. arg2 = dlong - argp + 33. + 3.*t0 - 10.*v0 - 2.6*(capt+.5);
  65. arg3 = dlong - argp + 151.1 + 16.*t0 - 18.*v0 - (capt+.5);
  66. arg4 = node;
  67. arg5 = node + 276.2 - 2.3*(capt+.5);
  68. arg6 = 313.9 + 13.*t0 - 8.*v0;
  69. arg7 = dlong - argp + 112.0 + 29.*t0 - 26.*v0;
  70. arg8 = dlong + argp - 2.*lsun + 273. + 21.*t0 - 20.*v0;
  71. arg9 = node + 290.1 - 0.9*(capt+.5);
  72. arg10 = 115. + 38.5*(capt+.5);
  73. arg1 *= radian;
  74. arg2 *= radian;
  75. arg3 *= radian;
  76. arg4 *= radian;
  77. arg5 *= radian;
  78. arg6 *= radian;
  79. arg7 *= radian;
  80. arg8 *= radian;
  81. arg9 *= radian;
  82. arg10 *= radian;
  83. dlong +=
  84. (0.84 *sin(arg1)
  85. + 0.31 *sin(arg2)
  86. + 14.27 *sin(arg3)
  87. + 7.261*sin(arg4)
  88. + 0.282*sin(arg5)
  89. + 0.237*sin(arg6)
  90. + 0.108*sin(arg7)
  91. + 0.126*sin(arg8))/3600.;
  92. argp +=
  93. (- 2.10 *sin(arg1)
  94. - 0.118*sin(arg3)
  95. - 2.076*sin(arg4)
  96. - 0.840*sin(arg5)
  97. - 0.593*sin(arg6))/3600.;
  98. node +=
  99. (0.63*sin(arg1)
  100. + 0.17*sin(arg3)
  101. + 95.96*sin(arg4)
  102. + 15.58*sin(arg5)
  103. + 1.86*sin(arg9))/3600.;
  104. t0 +=
  105. (- 6.40*sin(arg1)
  106. - 1.89*sin(arg6))/3600.;
  107. psun +=
  108. (6.40*sin(arg1)
  109. + 1.89*sin(arg6))/3600.;
  110. dgamma = - 4.318*cos(arg4)
  111. - 0.698*cos(arg5)
  112. - 0.083*cos(arg9);
  113. j0 +=
  114. 0.33*sin(arg10);
  115. /*
  116. * the following factors account for the fact that the
  117. * eccentricity, solar eccentricity, inclination and
  118. * parallax used by Brown to make up his coefficients
  119. * are both wrong and out of date. Brown did the same
  120. * thing in a different way.
  121. */
  122. k1 = eccm/22639.500;
  123. k2 = eccs/.01675104;
  124. k3 = 1. + 2.708e-6 + .000108008*dgamma;
  125. k4 = cpe/125.154;
  126. k5 = chp/3422.700;
  127. /*
  128. * the principal arguments that are used to compute
  129. * perturbations are the following differences of the
  130. * fundamental elements.
  131. */
  132. mnom = dlong - argp;
  133. msun = lsun - psun;
  134. noded = dlong - node;
  135. dmoon = dlong - lsun;
  136. /*
  137. * solar terms in longitude
  138. */
  139. lterms = 0.0;
  140. mp = moontab;
  141. for(;;) {
  142. if(mp->f == 0.0)
  143. break;
  144. lterms += sinx(mp->f,
  145. mp->c[0], mp->c[1],
  146. mp->c[2], mp->c[3], 0.0);
  147. mp++;
  148. }
  149. mp++;
  150. /*
  151. * planetary terms in longitude
  152. */
  153. lterms += sinx(0.822, 0,0,0,0, t0-v0);
  154. lterms += sinx(0.307, 0,0,0,0, 2.*t0-2.*v0+179.8);
  155. lterms += sinx(0.348, 0,0,0,0, 3.*t0-2.*v0+272.9);
  156. lterms += sinx(0.176, 0,0,0,0, 4.*t0-3.*v0+271.7);
  157. lterms += sinx(0.092, 0,0,0,0, 5.*t0-3.*v0+199.);
  158. lterms += sinx(0.129, 1,0,0,0, -t0+v0+180.);
  159. lterms += sinx(0.152, 1,0,0,0, t0-v0);
  160. lterms += sinx(0.127, 1,0,0,0, 3.*t0-3.*v0+180.);
  161. lterms += sinx(0.099, 0,0,0,2, t0-v0);
  162. lterms += sinx(0.136, 0,0,0,2, 2.*t0-2.*v0+179.5);
  163. lterms += sinx(0.083, -1,0,0,2, -4.*t0+4.*v0+180.);
  164. lterms += sinx(0.662, -1,0,0,2, -3.*t0+3.*v0+180.0);
  165. lterms += sinx(0.137, -1,0,0,2, -2.*t0+2.*v0);
  166. lterms += sinx(0.133, -1,0,0,2, t0-v0);
  167. lterms += sinx(0.157, -1,0,0,2, 2.*t0-2.*v0+179.6);
  168. lterms += sinx(0.079, -1,0,0,2, -8.*t0+6.*v0+162.6);
  169. lterms += sinx(0.073, 2,0,0,-2, 3.*t0-3.*v0+180.);
  170. lterms += sinx(0.643, 0,0,0,0, -t0+j0+178.8);
  171. lterms += sinx(0.187, 0,0,0,0, -2.*t0+2.*j0+359.6);
  172. lterms += sinx(0.087, 0,0,0,0, j0+289.9);
  173. lterms += sinx(0.165, 0,0,0,0, -t0+2.*j0+241.5);
  174. lterms += sinx(0.144, 1,0,0,0, t0-j0+1.0);
  175. lterms += sinx(0.158, 1,0,0,0, -t0+j0+179.0);
  176. lterms += sinx(0.190, 1,0,0,0, -2.*t0+2.*j0+180.0);
  177. lterms += sinx(0.096, 1,0,0,0, -2.*t0+3.*j0+352.5);
  178. lterms += sinx(0.070, 0,0,0,2, 2.*t0-2.*j0+180.);
  179. lterms += sinx(0.167, 0,0,0,2, -t0+j0+178.5);
  180. lterms += sinx(0.085, 0,0,0,2, -2.*t0+2.*j0+359.2);
  181. lterms += sinx(1.137, -1,0,0,2, 2.*t0-2.*j0+180.3);
  182. lterms += sinx(0.211, -1,0,0,2, -t0+j0+178.4);
  183. lterms += sinx(0.089, -1,0,0,2, -2.*t0+2.*j0+359.2);
  184. lterms += sinx(0.436, -1,0,0,2, 2.*t0-3.*j0+7.5);
  185. lterms += sinx(0.240, 2,0,0,-2, -2.*t0+2.*j0+179.9);
  186. lterms += sinx(0.284, 2,0,0,-2, -2.*t0+3.*j0+172.5);
  187. lterms += sinx(0.195, 0,0,0,0, -2.*t0+2.*m0+180.2);
  188. lterms += sinx(0.327, 0,0,0,0, -t0+2.*m0+224.4);
  189. lterms += sinx(0.093, 0,0,0,0, -2.*t0+4.*m0+244.8);
  190. lterms += sinx(0.073, 1,0,0,0, -t0+2.*m0+223.3);
  191. lterms += sinx(0.074, 1,0,0,0, t0-2.*m0+306.3);
  192. lterms += sinx(0.189, 0,0,0,0, node+180.);
  193. /*
  194. * solar terms in latitude
  195. */
  196. sterms = 0;
  197. for(;;) {
  198. if(mp->f == 0)
  199. break;
  200. sterms += sinx(mp->f,
  201. mp->c[0], mp->c[1],
  202. mp->c[2], mp->c[3], 0);
  203. mp++;
  204. }
  205. mp++;
  206. cterms = 0;
  207. for(;;) {
  208. if(mp->f == 0)
  209. break;
  210. cterms += cosx(mp->f,
  211. mp->c[0], mp->c[1],
  212. mp->c[2], mp->c[3], 0);
  213. mp++;
  214. }
  215. mp++;
  216. nterms = 0;
  217. for(;;) {
  218. if(mp->f == 0)
  219. break;
  220. nterms += sinx(mp->f,
  221. mp->c[0], mp->c[1],
  222. mp->c[2], mp->c[3], 0);
  223. mp++;
  224. }
  225. mp++;
  226. /*
  227. * planetary terms in latitude
  228. */
  229. pterms =
  230. sinx(0.215, 0,0,0,0, dlong);
  231. /*
  232. * solar terms in parallax
  233. */
  234. spterms = 3422.700;
  235. for(;;) {
  236. if(mp->f == 0)
  237. break;
  238. spterms += cosx(mp->f,
  239. mp->c[0], mp->c[1],
  240. mp->c[2], mp->c[3], 0);
  241. mp++;
  242. }
  243. /*
  244. * planetary terms in parallax
  245. */
  246. // Commenting this self assignment rather than deleting, as it might be
  247. // considered a note.
  248. //spterms = spterms;
  249. /*
  250. * computation of longitude
  251. */
  252. lambda = (dlong + lterms/3600.)*radian;
  253. /*
  254. * computation of latitude
  255. */
  256. arglat = (noded + sterms/3600.)*radian;
  257. gamma1 = 18519.700 * k3;
  258. gamma2 = -6.241 * k3*k3*k3;
  259. gamma3 = 0.004 * k3*k3*k3*k3*k3;
  260. k6 = (gamma1 + cterms) / gamma1;
  261. beta = k6 * (gamma1*sin(arglat) + gamma2*sin(3.*arglat)
  262. + gamma3*sin(5.*arglat) + nterms)
  263. + pterms;
  264. if(flags['o'])
  265. beta -= 0.6;
  266. beta *= radsec;
  267. /*
  268. * computation of parallax
  269. */
  270. spterms = k5 * spterms *radsec;
  271. hp = spterms + (spterms*spterms*spterms)/6.;
  272. rad = hp/radsec;
  273. rp = 1.;
  274. semi = .0799 + .272453*(hp/radsec);
  275. if(dmoon < 0.)
  276. dmoon += 360.;
  277. mag = dmoon/360.;
  278. /*
  279. * change to equatorial coordinates
  280. */
  281. lambda += phi;
  282. obl2 = obliq + eps;
  283. xmp = rp*cos(lambda)*cos(beta);
  284. ymp = rp*(sin(lambda)*cos(beta)*cos(obl2) - sin(obl2)*sin(beta));
  285. zmp = rp*(sin(lambda)*cos(beta)*sin(obl2) + cos(obl2)*sin(beta));
  286. alpha = atan2(ymp, xmp);
  287. delta = atan2(zmp, sqrt(xmp*xmp+ymp*ymp));
  288. meday = eday;
  289. mhp = hp;
  290. geo();
  291. }
  292. double
  293. sinx(double coef, int i, int j, int k, int m, double angle)
  294. {
  295. double x;
  296. x = i*mnom + j*msun + k*noded + m*dmoon + angle;
  297. x = coef*sin(x*radian);
  298. if(i < 0)
  299. i = -i;
  300. for(; i>0; i--)
  301. x *= k1;
  302. if(j < 0)
  303. j = -j;
  304. for(; j>0; j--)
  305. x *= k2;
  306. if(k < 0)
  307. k = -k;
  308. for(; k>0; k--)
  309. x *= k3;
  310. if(m & 1)
  311. x *= k4;
  312. return x;
  313. }
  314. double
  315. cosx(double coef, int i, int j, int k, int m, double angle)
  316. {
  317. double x;
  318. x = i*mnom + j*msun + k*noded + m*dmoon + angle;
  319. x = coef*cos(x*radian);
  320. if(i < 0)
  321. i = -i;
  322. for(; i>0; i--)
  323. x *= k1;
  324. if(j < 0)
  325. j = -j;
  326. for(; j>0; j--)
  327. x *= k2;
  328. if(k < 0)
  329. k = -k;
  330. for(; k>0; k--)
  331. x *= k3;
  332. if(m & 1)
  333. x *= k4;
  334. return x;
  335. }