/libastro-3.7.5/jupmoon.c

https://bitbucket.org/brandon/pyephem/ · C · 368 lines · 269 code · 53 blank · 46 comment · 23 complexity · 3996c9e00c2f935f0692d6b64af6a88c MD5 · raw file

  1. /* jupiter moon info */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <math.h>
  7. #include "astro.h"
  8. #include "bdl.h"
  9. static int use_bdl (double jd, char *dir, MoonData md[J_NMOONS]);
  10. static void moonradec (double jupsize, MoonData md[J_NMOONS]);
  11. static void moonSVis (Obj *sop, Obj *jop, MoonData md[J_NMOONS]);
  12. static void moonEVis (MoonData md[J_NMOONS]);
  13. static void moonPShad (Obj *sop, Obj *jop, MoonData md[J_NMOONS]);
  14. static void moonTrans (MoonData md[J_NMOONS]);
  15. /* moon table and a few other goodies and when it was last computed */
  16. static double mdmjd = -123456;
  17. static MoonData jmd[J_NMOONS] = {
  18. {"Jupiter", NULL},
  19. {"Io", "I"},
  20. {"Europa", "II"},
  21. {"Ganymede", "III"},
  22. {"Callisto", "IV"}
  23. };
  24. static double sizemjd; /* size at last mjd */
  25. static double cmlImjd; /* central meridian long sys I, at last mjd */
  26. static double cmlIImjd; /* " II " */
  27. /* These values are from the Explanatory Supplement.
  28. * Precession degrades them gradually over time.
  29. */
  30. #define POLE_RA degrad(268.05) /* RA of Jupiter's north pole */
  31. #define POLE_DEC degrad(64.50) /* Dec of Jupiter's north pole */
  32. /* get jupiter info in md[0], moon info in md[1..J_NMOONS-1].
  33. * if !dir always use meeus model.
  34. * if !jop caller just wants md[] for names
  35. * N.B. we assume sop and jop are updated.
  36. */
  37. void
  38. jupiter_data (
  39. double Mjd, /* mjd */
  40. char dir[], /* dir in which to look for helper files */
  41. Obj *sop, /* Sun */
  42. Obj *jop, /* jupiter */
  43. double *sizep, /* jup angular diam, rads */
  44. double *cmlI, double *cmlII, /* central meridian longitude, rads */
  45. double *polera, double *poledec, /* pole location */
  46. MoonData md[J_NMOONS]) /* return info */
  47. {
  48. double JD;
  49. /* always copy back at least for name */
  50. memcpy (md, jmd, sizeof(jmd));
  51. /* pole */
  52. if (polera) *polera = POLE_RA;
  53. if (poledec) *poledec = POLE_DEC;
  54. /* nothing else if repeat call or just want names */
  55. if (Mjd == mdmjd || !jop) {
  56. if (jop) {
  57. *sizep = sizemjd;
  58. *cmlI = cmlImjd;
  59. *cmlII = cmlIImjd;
  60. }
  61. return;
  62. }
  63. JD = Mjd + MJD0;
  64. /* planet in [0] */
  65. md[0].ra = jop->s_ra;
  66. md[0].dec = jop->s_dec;
  67. md[0].mag = get_mag(jop);
  68. md[0].x = 0;
  69. md[0].y = 0;
  70. md[0].z = 0;
  71. md[0].evis = 1;
  72. md[0].svis = 1;
  73. /* size is straight from jop */
  74. *sizep = degrad(jop->s_size/3600.0);
  75. /* mags from JPL ephemeris */
  76. md[1].mag = 5.7;
  77. md[2].mag = 5.8;
  78. md[3].mag = 5.3;
  79. md[4].mag = 6.7;
  80. /* get moon data from BDL if possible, else Meeus' model.
  81. * always use Meeus for cml
  82. */
  83. if (use_bdl (JD, dir, md) == 0)
  84. meeus_jupiter (Mjd, cmlI, cmlII, NULL);
  85. else
  86. meeus_jupiter (Mjd, cmlI, cmlII, md);
  87. /* set visibilities */
  88. moonSVis (sop, jop, md);
  89. moonPShad (sop, jop, md);
  90. moonEVis (md);
  91. moonTrans (md);
  92. /* fill in moon ra and dec */
  93. moonradec (*sizep, md);
  94. /* save */
  95. mdmjd = Mjd;
  96. sizemjd = *sizep;
  97. cmlImjd = *cmlI;
  98. cmlIImjd = *cmlII;
  99. memcpy (jmd, md, sizeof(jmd));
  100. }
  101. /* hunt for BDL file in dir[] and use if possible
  102. * return 0 if ok, else -1
  103. */
  104. static int
  105. use_bdl (
  106. double JD, /* julian date */
  107. char dir[], /* directory */
  108. MoonData md[J_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */
  109. {
  110. #define JUPRAU .0004769108 /* jupiter radius, AU */
  111. double x[J_NMOONS], y[J_NMOONS], z[J_NMOONS];
  112. BDL_Dataset *dataset;
  113. int i;
  114. /* check ranges and appropriate data file */
  115. if (JD < 2451179.50000) /* Jan 1 1999 UTC */
  116. return (-1);
  117. if (JD < 2455562.5) /* Jan 1 2011 UTC */
  118. dataset = & jupiter_9910;
  119. else if (JD < 2459215.5) /* Jan 1 2021 UTC */
  120. dataset = & jupiter_1020;
  121. else
  122. return (-1);
  123. /* use it */
  124. do_bdl(dataset, JD, x, y, z);
  125. /* copy into md[1..NM-1] with our scale and sign conventions */
  126. for (i = 1; i < J_NMOONS; i++) {
  127. md[i].x = x[i-1]/JUPRAU; /* we want jup radii +E */
  128. md[i].y = -y[i-1]/JUPRAU; /* we want jup radii +S */
  129. md[i].z = -z[i-1]/JUPRAU; /* we want jup radii +front */
  130. }
  131. /* ok */
  132. return (0);
  133. }
  134. /* compute location of GRS and Galilean moons.
  135. * if md == NULL, just to cml.
  136. * from "Astronomical Formulae for Calculators", 2nd ed, by Jean Meeus,
  137. * Willmann-Bell, Richmond, Va., U.S.A. (c) 1982, chapters 35 and 36.
  138. */
  139. void
  140. meeus_jupiter(
  141. double d,
  142. double *cmlI, double *cmlII, /* central meridian longitude, rads */
  143. MoonData md[J_NMOONS]) /* fill in md[1..NM-1].x/y/z for each moon.
  144. * N.B. md[0].ra/dec must already be set
  145. */
  146. {
  147. #define dsin(x) sin(degrad(x))
  148. #define dcos(x) cos(degrad(x))
  149. double A, B, Del, J, K, M, N, R, V;
  150. double cor_u1, cor_u2, cor_u3, cor_u4;
  151. double solc, tmp, G, H, psi, r, r1, r2, r3, r4;
  152. double u1, u2, u3, u4;
  153. double lam, Ds;
  154. double z1, z2, z3, z4;
  155. double De, dsinDe;
  156. double theta, phi;
  157. double tvc, pvc;
  158. double salpha, calpha;
  159. int i;
  160. V = 134.63 + 0.00111587 * d;
  161. M = (358.47583 + 0.98560003*d);
  162. N = (225.32833 + 0.0830853*d) + 0.33 * dsin (V);
  163. J = 221.647 + 0.9025179*d - 0.33 * dsin(V);
  164. A = 1.916*dsin(M) + 0.02*dsin(2*M);
  165. B = 5.552*dsin(N) + 0.167*dsin(2*N);
  166. K = (J+A-B);
  167. R = 1.00014 - 0.01672 * dcos(M) - 0.00014 * dcos(2*M);
  168. r = 5.20867 - 0.25192 * dcos(N) - 0.00610 * dcos(2*N);
  169. Del = sqrt (R*R + r*r - 2*R*r*dcos(K));
  170. psi = raddeg (asin (R/Del*dsin(K)));
  171. *cmlI = degrad(268.28 + 877.8169088*(d - Del/173) + psi - B);
  172. range (cmlI, 2*PI);
  173. *cmlII = degrad(290.28 + 870.1869088*(d - Del/173) + psi - B);
  174. range (cmlII, 2*PI);
  175. /* that's it if don't want moon info too */
  176. if (!md)
  177. return;
  178. solc = (d - Del/173.); /* speed of light correction */
  179. tmp = psi - B;
  180. u1 = 84.5506 + 203.4058630 * solc + tmp;
  181. u2 = 41.5015 + 101.2916323 * solc + tmp;
  182. u3 = 109.9770 + 50.2345169 * solc + tmp;
  183. u4 = 176.3586 + 21.4879802 * solc + tmp;
  184. G = 187.3 + 50.310674 * solc;
  185. H = 311.1 + 21.569229 * solc;
  186. cor_u1 = 0.472 * dsin (2*(u1-u2));
  187. cor_u2 = 1.073 * dsin (2*(u2-u3));
  188. cor_u3 = 0.174 * dsin (G);
  189. cor_u4 = 0.845 * dsin (H);
  190. r1 = 5.9061 - 0.0244 * dcos (2*(u1-u2));
  191. r2 = 9.3972 - 0.0889 * dcos (2*(u2-u3));
  192. r3 = 14.9894 - 0.0227 * dcos (G);
  193. r4 = 26.3649 - 0.1944 * dcos (H);
  194. md[1].x = -r1 * dsin (u1+cor_u1);
  195. md[2].x = -r2 * dsin (u2+cor_u2);
  196. md[3].x = -r3 * dsin (u3+cor_u3);
  197. md[4].x = -r4 * dsin (u4+cor_u4);
  198. lam = 238.05 + 0.083091*d + 0.33*dsin(V) + B;
  199. Ds = 3.07*dsin(lam + 44.5);
  200. De = Ds - 2.15*dsin(psi)*dcos(lam+24.)
  201. - 1.31*(r-Del)/Del*dsin(lam-99.4);
  202. dsinDe = dsin(De);
  203. z1 = r1 * dcos(u1+cor_u1);
  204. z2 = r2 * dcos(u2+cor_u2);
  205. z3 = r3 * dcos(u3+cor_u3);
  206. z4 = r4 * dcos(u4+cor_u4);
  207. md[1].y = z1*dsinDe;
  208. md[2].y = z2*dsinDe;
  209. md[3].y = z3*dsinDe;
  210. md[4].y = z4*dsinDe;
  211. /* compute sky transformation angle as triple vector product */
  212. tvc = PI/2.0 - md[0].dec;
  213. pvc = md[0].ra;
  214. theta = PI/2.0 - POLE_DEC;
  215. phi = POLE_RA;
  216. salpha = -sin(tvc)*sin(theta)*(cos(pvc)*sin(phi) - sin(pvc)*cos(phi));
  217. calpha = sqrt (1.0 - salpha*salpha);
  218. for (i = 0; i < J_NMOONS; i++) {
  219. double tx = md[i].x*calpha + md[i].y*salpha;
  220. double ty = -md[i].x*salpha + md[i].y*calpha;
  221. md[i].x = tx;
  222. md[i].y = ty;
  223. }
  224. md[1].z = z1;
  225. md[2].z = z2;
  226. md[3].z = z3;
  227. md[4].z = z4;
  228. }
  229. /* given jupiter loc in md[0].ra/dec and size, and location of each moon in
  230. * md[1..NM-1].x/y in jup radii, find ra/dec of each moon in md[1..NM-1].ra/dec.
  231. */
  232. static void
  233. moonradec (
  234. double jupsize, /* jup diameter, rads */
  235. MoonData md[J_NMOONS]) /* fill in RA and Dec */
  236. {
  237. double juprad = jupsize/2;
  238. double jupra = md[0].ra;
  239. double jupdec = md[0].dec;
  240. int i;
  241. for (i = 1; i < J_NMOONS; i++) {
  242. double dra = juprad * md[i].x;
  243. double ddec = juprad * md[i].y;
  244. md[i].ra = jupra + dra;
  245. md[i].dec = jupdec - ddec;
  246. }
  247. }
  248. /* set svis according to whether moon is in sun light */
  249. static void
  250. moonSVis(
  251. Obj *sop, /* SUN */
  252. Obj *jop, /* jupiter */
  253. MoonData md[J_NMOONS])
  254. {
  255. double esd = sop->s_edist;
  256. double eod = jop->s_edist;
  257. double sod = jop->s_sdist;
  258. double soa = degrad(jop->s_elong);
  259. double esa = asin(esd*sin(soa)/sod);
  260. double h = sod*jop->s_hlat;
  261. double nod = h*(1./eod - 1./sod);
  262. double sca = cos(esa), ssa = sin(esa);
  263. int i;
  264. for (i = 1; i < J_NMOONS; i++) {
  265. MoonData *mdp = &md[i];
  266. double xp = sca*mdp->x + ssa*mdp->z;
  267. double yp = mdp->y;
  268. double zp = -ssa*mdp->x + sca*mdp->z;
  269. double ca = cos(nod), sa = sin(nod);
  270. double xpp = xp;
  271. double ypp = ca*yp - sa*zp;
  272. double zpp = sa*yp + ca*zp;
  273. int outside = xpp*xpp + ypp*ypp > 1.0;
  274. int infront = zpp > 0.0;
  275. mdp->svis = outside || infront;
  276. }
  277. }
  278. /* set evis according to whether moon is geometrically visible from earth */
  279. static void
  280. moonEVis (MoonData md[J_NMOONS])
  281. {
  282. int i;
  283. for (i = 1; i < J_NMOONS; i++) {
  284. MoonData *mdp = &md[i];
  285. int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0;
  286. int infront = mdp->z > 0.0;
  287. mdp->evis = outside || infront;
  288. }
  289. }
  290. /* set pshad and sx,sy shadow info */
  291. static void
  292. moonPShad(
  293. Obj *sop, /* SUN */
  294. Obj *jop, /* jupiter */
  295. MoonData md[J_NMOONS])
  296. {
  297. int i;
  298. for (i = 1; i < J_NMOONS; i++) {
  299. MoonData *mdp = &md[i];
  300. mdp->pshad = !plshadow (jop, sop, POLE_RA, POLE_DEC, mdp->x,
  301. mdp->y, mdp->z, &mdp->sx, &mdp->sy);
  302. }
  303. }
  304. /* set whether moons are transiting */
  305. static void
  306. moonTrans (MoonData md[J_NMOONS])
  307. {
  308. int i;
  309. for (i = 1; i < J_NMOONS; i++) {
  310. MoonData *mdp = &md[i];
  311. mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1;
  312. }
  313. }
  314. /* For RCS Only -- Do Not Edit */
  315. static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: jupmoon.c,v $ $Date: 2006/08/29 03:16:47 $ $Revision: 1.7 $ $Name: $"};