source: Sophya/trunk/SophyaExt/XephemAstroLib/jupmoon.c@ 3072

Last change on this file since 3072 was 2818, checked in by cmv, 20 years ago

Update de Xephem 3.7 cmv 21/08/2005

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