| [2551] | 1 | /* compute Obj fields for natural satellites. | 
|---|
|  | 2 | */ | 
|---|
|  | 3 |  | 
|---|
|  | 4 | #include <stdio.h> | 
|---|
|  | 5 | #include <string.h> | 
|---|
|  | 6 | #include <math.h> | 
|---|
|  | 7 |  | 
|---|
|  | 8 | #include "astro.h" | 
|---|
|  | 9 |  | 
|---|
|  | 10 | /* private cache of planet ephemerides and when they were computed | 
|---|
|  | 11 | * N.B. don't use ones in builtin[] -- they are the user's responsibility. | 
|---|
|  | 12 | */ | 
|---|
|  | 13 | static ObjPl plobj[NOBJ]; | 
|---|
|  | 14 | static Now plnow[NOBJ]; | 
|---|
|  | 15 |  | 
|---|
|  | 16 | /* public builtin storage | 
|---|
|  | 17 | */ | 
|---|
|  | 18 | static Obj builtin[NBUILTIN]; | 
|---|
|  | 19 |  | 
|---|
|  | 20 | static char *moondir; | 
|---|
|  | 21 |  | 
|---|
|  | 22 | static void setMoon (Now *np, Obj *moonop, Obj *planop, MoonData *mdp); | 
|---|
|  | 23 | static void init1BI (int idx, int pl, int moon, char *name); | 
|---|
|  | 24 | static void initPlobj(void); | 
|---|
|  | 25 | static void rotate (double a, double *x, double *y); | 
|---|
|  | 26 |  | 
|---|
|  | 27 | /* directory in which to look for auxil moon data files. | 
|---|
|  | 28 | * N.B. caller must supply persistent storage. | 
|---|
|  | 29 | */ | 
|---|
|  | 30 | void | 
|---|
|  | 31 | setMoonDir (char *dir) | 
|---|
|  | 32 | { | 
|---|
|  | 33 | moondir = dir; | 
|---|
|  | 34 | } | 
|---|
|  | 35 |  | 
|---|
|  | 36 | /* return set of builtin objects. | 
|---|
|  | 37 | * caller can use this storage but should never try to free anything. | 
|---|
|  | 38 | */ | 
|---|
|  | 39 | int | 
|---|
|  | 40 | getBuiltInObjs (Obj **opp) | 
|---|
|  | 41 | { | 
|---|
|  | 42 | if (!builtin[MERCURY].o_name[0]) { | 
|---|
|  | 43 | /* first time only */ | 
|---|
|  | 44 |  | 
|---|
|  | 45 | init1BI (MERCURY,   MERCURY, X_PLANET,    "Mercury"); | 
|---|
|  | 46 |  | 
|---|
|  | 47 | init1BI (VENUS,     VENUS,   X_PLANET,    "Venus"); | 
|---|
|  | 48 |  | 
|---|
|  | 49 | init1BI (MARS,      MARS,    X_PLANET,    "Mars"); | 
|---|
|  | 50 | init1BI (PHOBOS,    MARS,    M_PHOBOS,    "Phobos"); | 
|---|
|  | 51 | init1BI (DEIMOS,    MARS,    M_DEIMOS,    "Deimos"); | 
|---|
|  | 52 |  | 
|---|
|  | 53 | init1BI (JUPITER,   JUPITER, X_PLANET,    "Jupiter"); | 
|---|
|  | 54 | init1BI (IO,        JUPITER, J_IO,        "Io"); | 
|---|
|  | 55 | init1BI (EUROPA,    JUPITER, J_EUROPA,    "Europa"); | 
|---|
|  | 56 | init1BI (GANYMEDE,  JUPITER, J_GANYMEDE,  "Ganymede"); | 
|---|
|  | 57 | init1BI (CALLISTO,  JUPITER, J_CALLISTO,  "Callisto"); | 
|---|
|  | 58 |  | 
|---|
|  | 59 | init1BI (SATURN,    SATURN,  X_PLANET,    "Saturn"); | 
|---|
|  | 60 | init1BI (MIMAS,     SATURN,  S_MIMAS,     "Mimas"); | 
|---|
|  | 61 | init1BI (ENCELADUS, SATURN,  S_ENCELADUS, "Enceladus"); | 
|---|
|  | 62 | init1BI (TETHYS,    SATURN,  S_TETHYS,    "Tethys"); | 
|---|
|  | 63 | init1BI (DIONE,     SATURN,  S_DIONE,     "Dione"); | 
|---|
|  | 64 | init1BI (RHEA,      SATURN,  S_RHEA,      "Rhea"); | 
|---|
|  | 65 | init1BI (TITAN,     SATURN,  S_TITAN,     "Titan"); | 
|---|
|  | 66 | init1BI (HYPERION,  SATURN,  S_HYPERION,  "Hyperion"); | 
|---|
|  | 67 | init1BI (IAPETUS,   SATURN,  S_IAPETUS,   "Iapetus"); | 
|---|
|  | 68 |  | 
|---|
|  | 69 | init1BI (URANUS,    URANUS,  X_PLANET,    "Uranus"); | 
|---|
|  | 70 | init1BI (ARIEL,     URANUS,  U_ARIEL,     "Ariel"); | 
|---|
|  | 71 | init1BI (UMBRIEL,   URANUS,  U_UMBRIEL,   "Umbriel"); | 
|---|
|  | 72 | init1BI (TITANIA,   URANUS,  U_TITANIA,   "Titania"); | 
|---|
|  | 73 | init1BI (OBERON,    URANUS,  U_OBERON,    "Oberon"); | 
|---|
|  | 74 | init1BI (MIRANDA,   URANUS,  U_MIRANDA,   "Miranda"); | 
|---|
|  | 75 |  | 
|---|
|  | 76 | init1BI (NEPTUNE,   NEPTUNE, X_PLANET,    "Neptune"); | 
|---|
|  | 77 |  | 
|---|
|  | 78 | init1BI (PLUTO,     PLUTO,   X_PLANET,    "Pluto"); | 
|---|
|  | 79 |  | 
|---|
|  | 80 | init1BI (SUN,       SUN,     X_PLANET,    "Sun"); | 
|---|
|  | 81 |  | 
|---|
|  | 82 | init1BI (MOON,      MOON,    X_PLANET,    "Moon"); | 
|---|
|  | 83 | } | 
|---|
|  | 84 |  | 
|---|
|  | 85 | *opp = builtin; | 
|---|
|  | 86 | return (NBUILTIN); | 
|---|
|  | 87 | } | 
|---|
|  | 88 |  | 
|---|
|  | 89 | static void | 
|---|
|  | 90 | init1BI (int idx, int pl, int moon, char *name) | 
|---|
|  | 91 | { | 
|---|
|  | 92 | strcpy (builtin[idx].o_name, name); | 
|---|
|  | 93 | builtin[idx].o_type = PLANET; | 
|---|
|  | 94 | builtin[idx].pl_code = pl; | 
|---|
|  | 95 | builtin[idx].pl_moon = moon; | 
|---|
|  | 96 | } | 
|---|
|  | 97 |  | 
|---|
|  | 98 | /* find the circumstances for natural satellite object op at np. | 
|---|
|  | 99 | * TODO: distances and helio coords just copied from parent planet. | 
|---|
|  | 100 | */ | 
|---|
|  | 101 | int | 
|---|
|  | 102 | plmoon_cir (Now *np, Obj *moonop) | 
|---|
|  | 103 | { | 
|---|
|  | 104 | Obj *sunop = (Obj*)&plobj[SUN]; | 
|---|
|  | 105 | MoonData md[X_MAXNMOONS]; | 
|---|
|  | 106 | double sz, t1, t2; | 
|---|
| [2643] | 107 | double pra, pdec; | 
|---|
| [2551] | 108 | MoonData *mdp; | 
|---|
|  | 109 | Obj *planop; | 
|---|
|  | 110 |  | 
|---|
|  | 111 | /* init plobj[] */ | 
|---|
| [2818] | 112 | if (!((Obj *)&plobj[0])->o_type) | 
|---|
| [2551] | 113 | initPlobj(); | 
|---|
|  | 114 |  | 
|---|
|  | 115 | /* get sun @ np */ | 
|---|
|  | 116 | if (memcmp (&plnow[SUN], np, sizeof(Now))) { | 
|---|
|  | 117 | obj_cir (np, (Obj*)&plobj[SUN]); | 
|---|
|  | 118 | memcpy (&plnow[SUN], np, sizeof(Now)); | 
|---|
|  | 119 | } | 
|---|
|  | 120 |  | 
|---|
|  | 121 | /* get parent planet and moon info @ np */ | 
|---|
|  | 122 | switch (moonop->pl_code) { | 
|---|
|  | 123 |  | 
|---|
|  | 124 | case MARS: | 
|---|
|  | 125 | case PHOBOS: | 
|---|
|  | 126 | case DEIMOS: | 
|---|
|  | 127 |  | 
|---|
|  | 128 | planop = (Obj*)&plobj[MARS]; | 
|---|
|  | 129 |  | 
|---|
|  | 130 | if (memcmp (&plnow[MARS], np, sizeof(Now))) { | 
|---|
|  | 131 | obj_cir (np, planop); | 
|---|
|  | 132 | memcpy (&plnow[MARS], np, sizeof(Now)); | 
|---|
|  | 133 | } | 
|---|
|  | 134 |  | 
|---|
|  | 135 | /* don't worry, this already caches based on same mjd */ | 
|---|
| [2643] | 136 | marsm_data (mjd, moondir, sunop, planop, &sz, &pra, &pdec, md); | 
|---|
| [2551] | 137 | mdp = &md[moonop->pl_moon]; | 
|---|
|  | 138 | break; | 
|---|
|  | 139 |  | 
|---|
|  | 140 | case JUPITER: | 
|---|
|  | 141 | case IO: | 
|---|
|  | 142 | case EUROPA: | 
|---|
|  | 143 | case GANYMEDE: | 
|---|
|  | 144 | case CALLISTO: | 
|---|
|  | 145 |  | 
|---|
|  | 146 | planop = (Obj*)&plobj[JUPITER]; | 
|---|
|  | 147 |  | 
|---|
|  | 148 | if (memcmp (&plnow[JUPITER], np, sizeof(Now))) { | 
|---|
|  | 149 | obj_cir (np, planop); | 
|---|
|  | 150 | memcpy (&plnow[JUPITER], np, sizeof(Now)); | 
|---|
|  | 151 | } | 
|---|
|  | 152 |  | 
|---|
|  | 153 | /* don't worry, this already caches based on same mjd */ | 
|---|
| [2643] | 154 | jupiter_data (mjd,moondir,sunop,planop,&sz,&t1,&t2,&pra,&pdec,md); | 
|---|
| [2551] | 155 | mdp = &md[moonop->pl_moon]; | 
|---|
|  | 156 | moonop->pl_aux1 = t1; | 
|---|
|  | 157 | moonop->pl_aux2 = t2; | 
|---|
|  | 158 | break; | 
|---|
|  | 159 |  | 
|---|
|  | 160 | case SATURN: | 
|---|
|  | 161 | case MIMAS: | 
|---|
|  | 162 | case ENCELADUS: | 
|---|
|  | 163 | case TETHYS: | 
|---|
|  | 164 | case DIONE: | 
|---|
|  | 165 | case RHEA: | 
|---|
|  | 166 | case TITAN: | 
|---|
|  | 167 | case HYPERION: | 
|---|
|  | 168 | case IAPETUS: | 
|---|
|  | 169 |  | 
|---|
|  | 170 | planop = (Obj*)&plobj[SATURN]; | 
|---|
|  | 171 |  | 
|---|
|  | 172 | if (memcmp (&plnow[SATURN], np, sizeof(Now))) { | 
|---|
|  | 173 | obj_cir (np, planop); | 
|---|
|  | 174 | memcpy (&plnow[SATURN], np, sizeof(Now)); | 
|---|
|  | 175 | } | 
|---|
|  | 176 |  | 
|---|
|  | 177 | /* don't worry, this already caches based on same mjd */ | 
|---|
| [2643] | 178 | saturn_data (mjd,moondir,sunop,planop,&sz,&t1,&t2,&pra,&pdec,md); | 
|---|
| [2551] | 179 | mdp = &md[moonop->pl_moon]; | 
|---|
|  | 180 | moonop->pl_aux1 = t1; | 
|---|
|  | 181 | moonop->pl_aux2 = t2; | 
|---|
|  | 182 | break; | 
|---|
|  | 183 |  | 
|---|
|  | 184 | case URANUS: | 
|---|
|  | 185 | case ARIEL: | 
|---|
|  | 186 | case UMBRIEL: | 
|---|
|  | 187 | case TITANIA: | 
|---|
|  | 188 | case OBERON: | 
|---|
|  | 189 | case MIRANDA: | 
|---|
|  | 190 |  | 
|---|
|  | 191 | planop = (Obj*)&plobj[URANUS]; | 
|---|
|  | 192 |  | 
|---|
|  | 193 | if (memcmp (&plnow[URANUS], np, sizeof(Now))) { | 
|---|
|  | 194 | obj_cir (np, planop); | 
|---|
|  | 195 | memcpy (&plnow[URANUS], np, sizeof(Now)); | 
|---|
|  | 196 | } | 
|---|
|  | 197 |  | 
|---|
|  | 198 | /* don't worry, this already caches based on same mjd */ | 
|---|
| [2643] | 199 | uranus_data (mjd, moondir, sunop, planop, &sz, &pra, &pdec, md); | 
|---|
| [2551] | 200 | mdp = &md[moonop->pl_moon]; | 
|---|
|  | 201 | break; | 
|---|
|  | 202 |  | 
|---|
|  | 203 | default: | 
|---|
|  | 204 |  | 
|---|
|  | 205 | printf ("Called plmoon_cir with bad code: %d\n",moonop->pl_code); | 
|---|
|  | 206 | return (-1); | 
|---|
|  | 207 |  | 
|---|
|  | 208 | } | 
|---|
|  | 209 |  | 
|---|
|  | 210 | /* set moonop */ | 
|---|
|  | 211 | setMoon (np, moonop, planop, mdp); | 
|---|
|  | 212 |  | 
|---|
|  | 213 | return (0); | 
|---|
|  | 214 | } | 
|---|
|  | 215 |  | 
|---|
|  | 216 | static void | 
|---|
|  | 217 | initPlobj() | 
|---|
|  | 218 | { | 
|---|
|  | 219 | int i; | 
|---|
|  | 220 |  | 
|---|
|  | 221 | for (i = 0; i < NOBJ; i++) { | 
|---|
|  | 222 | ((Obj*)&plobj[i])->o_type = PLANET; | 
|---|
|  | 223 | ((Obj*)&plobj[i])->pl_code = i; | 
|---|
|  | 224 | } | 
|---|
|  | 225 | } | 
|---|
|  | 226 |  | 
|---|
|  | 227 | /* set moonop->s_* fields. | 
|---|
|  | 228 | * np is needed to get local parallactic angle. | 
|---|
|  | 229 | */ | 
|---|
|  | 230 | static void | 
|---|
|  | 231 | setMoon (Now *np, Obj *moonop, Obj *planop, MoonData *mdp) | 
|---|
|  | 232 | { | 
|---|
|  | 233 | double pa, dra, ddec; | 
|---|
|  | 234 |  | 
|---|
|  | 235 | /* just copy most fields from planet for now */ | 
|---|
|  | 236 | moonop->s_gaera = planop->s_gaera;      /* TODO */ | 
|---|
|  | 237 | moonop->s_gaedec = planop->s_gaedec;    /* TODO */ | 
|---|
|  | 238 | moonop->s_elong = planop->s_elong;      /* TODO */ | 
|---|
|  | 239 | moonop->s_size = 0;                     /* TODO */ | 
|---|
|  | 240 | moonop->s_sdist = planop->s_sdist;      /* TODO */ | 
|---|
|  | 241 | moonop->s_edist = planop->s_edist;      /* TODO */ | 
|---|
|  | 242 | moonop->s_hlat = planop->s_hlat;        /* TODO */ | 
|---|
|  | 243 | moonop->s_hlong = planop->s_hlong;      /* TODO */ | 
|---|
|  | 244 | moonop->s_phase = planop->s_phase;      /* TODO */ | 
|---|
|  | 245 |  | 
|---|
|  | 246 | /* new ra/dec directly from mdp */ | 
|---|
|  | 247 | moonop->s_ra = mdp->ra; | 
|---|
|  | 248 | moonop->s_dec = mdp->dec; | 
|---|
|  | 249 |  | 
|---|
|  | 250 | /* geoemtry info */ | 
|---|
|  | 251 | moonop->pl_x = mdp->x; | 
|---|
|  | 252 | moonop->pl_y = mdp->y; | 
|---|
|  | 253 | moonop->pl_z = mdp->z; | 
|---|
|  | 254 | moonop->pl_evis = mdp->evis; | 
|---|
|  | 255 | moonop->pl_svis = mdp->svis; | 
|---|
|  | 256 |  | 
|---|
|  | 257 | /* tweak alt/az by change in ra/dec rotated by pa */ | 
|---|
|  | 258 | pa = parallacticLDA (lat, planop->s_dec, planop->s_alt); | 
|---|
|  | 259 | if (planop->s_az < PI) | 
|---|
|  | 260 | pa = -pa;                   /* rotation radec to altaz */ | 
|---|
|  | 261 | dra = (moonop->s_ra - planop->s_ra)*cos(planop->s_dec); | 
|---|
|  | 262 | ddec = moonop->s_dec - planop->s_dec; | 
|---|
|  | 263 | rotate (pa, &dra, &ddec); | 
|---|
|  | 264 | moonop->s_alt = planop->s_alt + ddec; | 
|---|
|  | 265 | moonop->s_az = planop->s_az - dra/cos(planop->s_alt); | 
|---|
|  | 266 |  | 
|---|
|  | 267 | /* new mag directly from mdp */ | 
|---|
|  | 268 | set_smag (moonop, mdp->mag); | 
|---|
|  | 269 |  | 
|---|
|  | 270 | /* name */ | 
|---|
|  | 271 | strcpy (moonop->o_name, mdp->full); | 
|---|
|  | 272 | } | 
|---|
|  | 273 |  | 
|---|
|  | 274 | /* rotate ccw by a */ | 
|---|
|  | 275 | static void | 
|---|
|  | 276 | rotate (double a, double *x, double *y) | 
|---|
|  | 277 | { | 
|---|
|  | 278 | double sa = sin(a); | 
|---|
|  | 279 | double ca = cos(a); | 
|---|
|  | 280 | double xp = (*x)*ca - (*y)*sa; | 
|---|
|  | 281 | double yp = (*x)*sa + (*y)*ca; | 
|---|
|  | 282 | *x = xp; | 
|---|
|  | 283 | *y = yp; | 
|---|
|  | 284 | } | 
|---|