source: Sophya/trunk/SophyaExt/XephemAstroLib/marsmoon.c@ 3995

Last change on this file since 3995 was 3654, checked in by cmv, 16 years ago

mise a niveau Xephem 3.7.4, cmv 16/07/2009

File size: 6.3 KB
RevLine 
[2551]1/* mars moon info */
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
[3111]6#include <errno.h>
[2551]7#include <math.h>
8
9#include "astro.h"
10#include "bdl.h"
11
12static int use_bdl (double JD, char *dir, MoonData md[M_NMOONS]);
13static void moonradec (double msize, MoonData md[M_NMOONS]);
[2643]14static void moonSVis (Obj *sop, Obj *mop, MoonData md[M_NMOONS]);
[2551]15static void moonEVis (MoonData md[M_NMOONS]);
[2643]16static void moonPShad (Obj *sop, Obj *mop, MoonData md[M_NMOONS]);
17static void moonTrans (MoonData md[M_NMOONS]);
[2551]18
19/* moon table and a few other goodies and when it was last computed */
20static double mdmjd = -123456;
21static MoonData mmd[M_NMOONS] = {
22 {"Mars", NULL},
23 {"Phobos", "I"},
24 {"Deimos", "II"},
25};
26static double sizemjd;
27
[2643]28/* These values are from the Explanatory Supplement.
29 * Precession degrades them gradually over time.
30 */
31#define POLE_RA degrad(317.61)
32#define POLE_DEC degrad(52.85)
33
34
[2551]35/* get mars info in md[0], moon info in md[1..M_NMOONS-1].
36 * if !dir always use bruton model.
37 * if !mop caller just wants md[] for names
[2643]38 * N.B. we assume sop and mop are updated.
[2551]39 */
40void
41marsm_data (
42double Mjd, /* mjd */
43char dir[], /* dir in which to look for helper files */
[2643]44Obj *sop, /* Sun */
[2551]45Obj *mop, /* mars */
46double *sizep, /* mars's angular diam, rads */
[2643]47double *polera, double *poledec,/* pole location */
[2551]48MoonData md[M_NMOONS]) /* return info */
49{
50 double JD, dmag;
51
52 /* always copy back at least for name */
53 memcpy (md, mmd, sizeof(mmd));
54
[2643]55 /* pole */
56 if (polera) *polera = POLE_RA;
57 if (poledec) *poledec = POLE_DEC;
58
[2551]59 /* nothing else if repeat call or just want names */
60 if (Mjd == mdmjd || !mop) {
61 if (mop) {
62 *sizep = sizemjd;
63 }
64 return;
65 }
66 JD = Mjd + MJD0;
67
68 /* planet in [0] */
69 md[0].ra = mop->s_ra;
70 md[0].dec = mop->s_dec;
71 md[0].mag = get_mag(mop);
72 md[0].x = 0;
73 md[0].y = 0;
74 md[0].z = 0;
75 md[0].evis = 1;
76 md[0].svis = 1;
77
78 /* size is straight from mop */
79 *sizep = degrad(mop->s_size/3600.0);
80
81 /* from Pasachoff/Menzel: brightest @ .6 AU */
82 dmag = 5.0*log10(mop->s_edist + 0.4);
83 md[1].mag = 11.8 + dmag;
84 md[2].mag = 12.9 + dmag;
85
86 /* get moon x,y,z from BDL if possible */
[3111]87 if (!dir || use_bdl (JD, dir, md) < 0) {
[2551]88 int i;
89 for (i = 1; i < M_NMOONS; i++)
90 md[i].x = md[i].y = md[i].z = 0.0;
91 fprintf (stderr, "No mars model available\n");
92 }
93
94 /* set visibilities */
[2643]95 moonSVis (sop, mop, md);
96 moonPShad (sop, mop, md);
[2551]97 moonEVis (md);
[2643]98 moonTrans (md);
[2551]99
100 /* fill in moon ra and dec */
101 moonradec (*sizep, md);
102
103 /* save */
104 mdmjd = Mjd;
105 sizemjd = *sizep;
106 memcpy (mmd, md, sizeof(mmd));
107}
108
109/* hunt for BDL file in dir[] and use if possible.
110 * return 0 if ok, else -1
111 */
112static int
113use_bdl (
114double JD, /* julian date */
115char dir[], /* directory */
116MoonData md[M_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */
117{
118#define MRAU .00002269 /* Mars radius, AU */
119 double x[M_NMOONS], y[M_NMOONS], z[M_NMOONS];
120 char buf[1024];
121 FILE *fp;
[3111]122 char *fn;
[2551]123 int i;
124
[3111]125 /* check ranges and appropriate data file */
126 if (JD < 2451179.50000) /* Jan 1 1999 UTC */
[2551]127 return (-1);
[3111]128 if (JD < 2455562.5) /* Jan 1 2011 UTC */
129 fn = "mars.9910";
130 else if (JD < 2459215.5) /* Jan 1 2021 UTC */
131 fn = "mars.1020";
132 else
133 return (-1);
[2551]134
135 /* open */
[3111]136 (void) sprintf (buf, "%s/%s", dir, fn);
[2551]137 fp = fopen (buf, "r");
[3111]138 if (!fp) {
139 fprintf (stderr, "%s: %s\n", fn, strerror(errno));
[2551]140 return (-1);
[3111]141 }
[2551]142
143 /* use it */
144 if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) {
[3111]145 fprintf (stderr, "%s: %s\n", fn, buf);
[2551]146 fclose (fp);
147 return (-1);
148 }
149 if (i != M_NMOONS-1) {
[3111]150 fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn,
[2551]151 i, M_NMOONS-1);
152 fclose (fp);
153 return (-1);
154 }
155
156 /* copy into md[1..NM-1] with our scale and sign conventions */
157 for (i = 1; i < M_NMOONS; i++) {
158 md[i].x = x[i-1]/MRAU; /* we want mars radii +E */
159 md[i].y = -y[i-1]/MRAU; /* we want mars radii +S */
160 md[i].z = -z[i-1]/MRAU; /* we want mars radii +front */
161 }
162
163 /* ok */
164 fclose (fp);
165 return (0);
166}
167
168/* given mars loc in md[0].ra/dec and size, and location of each moon in
169 * md[1..NM-1].x/y in mars radii,find ra/dec of each moon in md[1..NM-1].ra/dec.
170 */
171static void
172moonradec (
173double msize, /* mars diameter, rads */
174MoonData md[M_NMOONS]) /* fill in RA and Dec */
175{
176 double mrad = msize/2;
177 double mra = md[0].ra;
178 double mdec = md[0].dec;
179 int i;
180
181 for (i = 1; i < M_NMOONS; i++) {
182 double dra = mrad * md[i].x;
183 double ddec = mrad * md[i].y;
184 md[i].ra = mra + dra;
185 md[i].dec = mdec - ddec;
186 }
187}
188
189/* set svis according to whether moon is in sun light */
190static void
191moonSVis(
[2643]192Obj *sop, /* SUN */
[2551]193Obj *mop, /* mars */
194MoonData md[M_NMOONS])
195{
[2643]196 double esd = sop->s_edist;
[2551]197 double eod = mop->s_edist;
198 double sod = mop->s_sdist;
199 double soa = degrad(mop->s_elong);
200 double esa = asin(esd*sin(soa)/sod);
201 double h = sod*mop->s_hlat;
202 double nod = h*(1./eod - 1./sod);
203 double sca = cos(esa), ssa = sin(esa);
204 int i;
205
206 for (i = 1; i < M_NMOONS; i++) {
207 MoonData *mdp = &md[i];
208 double xp = sca*mdp->x + ssa*mdp->z;
209 double yp = mdp->y;
210 double zp = -ssa*mdp->x + sca*mdp->z;
211 double ca = cos(nod), sa = sin(nod);
212 double xpp = xp;
213 double ypp = ca*yp - sa*zp;
214 double zpp = sa*yp + ca*zp;
215 int outside = xpp*xpp + ypp*ypp > 1.0;
216 int infront = zpp > 0.0;
217 mdp->svis = outside || infront;
218 }
219}
220
221/* set evis according to whether moon is geometrically visible from earth */
222static void
223moonEVis (MoonData md[M_NMOONS])
224{
225 int i;
226
227 for (i = 1; i < M_NMOONS; i++) {
228 MoonData *mdp = &md[i];
229 int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0;
230 int infront = mdp->z > 0.0;
231 mdp->evis = outside || infront;
232 }
233}
234
[2643]235/* set pshad and sx,sy shadow info */
236static void
237moonPShad(
238Obj *sop, /* SUN */
239Obj *mop, /* mars */
240MoonData md[M_NMOONS])
241{
242 int i;
243
244 for (i = 1; i < M_NMOONS; i++) {
245 MoonData *mdp = &md[i];
246 mdp->pshad = !plshadow (mop, sop, POLE_RA, POLE_DEC, mdp->x,
247 mdp->y, mdp->z, &mdp->sx, &mdp->sy);
248 }
249}
250
251/* set whether moons are transiting */
252static void
253moonTrans (MoonData md[M_NMOONS])
254{
255 int i;
256
257 for (i = 1; i < M_NMOONS; i++) {
258 MoonData *mdp = &md[i];
259 mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1;
260 }
261}
262
263
[2551]264/* For RCS Only -- Do Not Edit */
[3654]265static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: marsmoon.c,v $ $Date: 2009-07-16 10:34:37 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Note: See TracBrowser for help on using the repository browser.