| 1 | /* rewritten for Bureau des Longitude theories by Bretagnon and Chapront | 
|---|
| 2 | * Michael Sternberg <sternberg@physik.tu-chemnitz.de> | 
|---|
| 3 | */ | 
|---|
| 4 | #include <stdio.h> | 
|---|
| 5 | #include <math.h> | 
|---|
| 6 |  | 
|---|
| 7 | #include "P_.h" | 
|---|
| 8 | #include "astro.h" | 
|---|
| 9 | #include "vsop87.h" | 
|---|
| 10 | #include "chap95.h" | 
|---|
| 11 |  | 
|---|
| 12 | static void pluto_ell P_((double mjd, double *ret)); | 
|---|
| 13 | static void chap_trans P_((double mjd, double *ret)); | 
|---|
| 14 | static void planpos P_((double mjd, int obj, double prec, double *ret)); | 
|---|
| 15 |  | 
|---|
| 16 | /* coordinate transformation | 
|---|
| 17 | * from: | 
|---|
| 18 | *      J2000.0 rectangular equatoreal                  ret[{0,1,2}] = {x,y,z} | 
|---|
| 19 | * to: | 
|---|
| 20 | *      mean equinox of date spherical ecliptical       ret[{0,1,2}] = {l,b,r} | 
|---|
| 21 | */ | 
|---|
| 22 | static void | 
|---|
| 23 | chap_trans (mjd, ret) | 
|---|
| 24 | double mjd;     /* destination epoch */ | 
|---|
| 25 | double *ret;    /* vector to be transformed _IN PLACE_ */ | 
|---|
| 26 | { | 
|---|
| 27 | double ra, dec, r, eps; | 
|---|
| 28 | double sr, cr, sd, cd, se, ce; | 
|---|
| 29 |  | 
|---|
| 30 | cartsph(ret[0], ret[1], ret[2], &ra, &dec, &r); | 
|---|
| 31 | precess(J2000, mjd, &ra, &dec); | 
|---|
| 32 | obliquity(mjd, &eps); | 
|---|
| 33 | sr = sin(ra); cr = cos(ra); | 
|---|
| 34 | sd = sin(dec); cd = cos(dec); | 
|---|
| 35 | se = sin(eps); ce = cos(eps); | 
|---|
| 36 | ret[0] = atan2( sr * ce + sd/cd * se, cr);      /* long */ | 
|---|
| 37 | ret[1] = asin( sd * ce - cd * se * sr);         /* lat */ | 
|---|
| 38 | ret[2] = r;                                     /* radius */ | 
|---|
| 39 | } | 
|---|
| 40 |  | 
|---|
| 41 | /* low precision ecliptic coordinates of Pluto from mean orbit. | 
|---|
| 42 | * Only for sake of completeness outside available perturbation theories. | 
|---|
| 43 | */ | 
|---|
| 44 | static void | 
|---|
| 45 | pluto_ell (mjd, ret) | 
|---|
| 46 | double mjd;     /* epoch */ | 
|---|
| 47 | double *ret;    /* ecliptic coordinates {l,b,r} at equinox of date */ | 
|---|
| 48 | { | 
|---|
| 49 | /* mean orbital elements of Pluto. | 
|---|
| 50 | * The origin of these is somewhat obscure. | 
|---|
| 51 | */ | 
|---|
| 52 | double  a = 39.543,                     /* semimajor axis, au */ | 
|---|
| 53 | e = 0.2490,                     /* excentricity */ | 
|---|
| 54 | inc0 = 17.140,                  /* inclination, deg */ | 
|---|
| 55 | Om0 = 110.307,                  /* long asc node, deg */ | 
|---|
| 56 | omeg0 = 113.768,                /* arg of perihel, deg */ | 
|---|
| 57 | mjdp = 2448045.539 - MJD0,      /* epoch of perihel */ | 
|---|
| 58 | mjdeq = J2000,                  /* equinox of elements */ | 
|---|
| 59 | n = 144.9600/36525.;            /* daily motion, deg */ | 
|---|
| 60 |  | 
|---|
| 61 | double inc, Om, omeg;   /* orbital elements at epoch of date */ | 
|---|
| 62 | double ma, ea, nu;      /* mean, excentric and true anomaly */ | 
|---|
| 63 | double lo, slo, clo;    /* longitude in orbit from asc node */ | 
|---|
| 64 |  | 
|---|
| 65 | reduce_elements(mjdeq, mjd, degrad(inc0), degrad(omeg0), degrad(Om0), | 
|---|
| 66 | &inc, &omeg, &Om); | 
|---|
| 67 | ma = degrad((mjd - mjdp) * n); | 
|---|
| 68 | anomaly(ma, e, &nu, &ea); | 
|---|
| 69 | ret[2] = a * (1.0 - e*cos(ea));                 /* r */ | 
|---|
| 70 | lo = omeg + nu; | 
|---|
| 71 | slo = sin(lo); | 
|---|
| 72 | clo = cos(lo); | 
|---|
| 73 | ret[1] = asin(slo * sin(inc));                  /* b */ | 
|---|
| 74 | ret[0] = atan2(slo * cos(inc), clo) + Om;       /* l */ | 
|---|
| 75 | } | 
|---|
| 76 |  | 
|---|
| 77 | /*************************************************************/ | 
|---|
| 78 |  | 
|---|
| 79 | /* geometric heliocentric position of planet, mean ecliptic of date | 
|---|
| 80 | * (not corrected for light-time) | 
|---|
| 81 | */ | 
|---|
| 82 | static void | 
|---|
| 83 | planpos (mjd, obj, prec, ret) | 
|---|
| 84 | double mjd; | 
|---|
| 85 | int obj; | 
|---|
| 86 | double prec; | 
|---|
| 87 | double *ret; | 
|---|
| 88 | { | 
|---|
| 89 | if (mjd >= CHAP_BEGIN && mjd <= CHAP_END) { | 
|---|
| 90 | if (obj >= JUPITER) {               /* prefer Chapront */ | 
|---|
| 91 | chap95(mjd, obj, prec, ret); | 
|---|
| 92 | chap_trans (mjd, ret); | 
|---|
| 93 | } else {                            /* VSOP for inner planets */ | 
|---|
| 94 | vsop87(mjd, obj, prec, ret); | 
|---|
| 95 | } | 
|---|
| 96 | } else {                                /* outside Chapront time: */ | 
|---|
| 97 | if (obj != PLUTO) {                 /* VSOP for all but Pluto */ | 
|---|
| 98 | vsop87(mjd, obj, prec, ret); | 
|---|
| 99 | } else {                            /* Pluto mean elliptic orbit */ | 
|---|
| 100 | pluto_ell(mjd, ret); | 
|---|
| 101 | } | 
|---|
| 102 | } | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | /*************************************************************/ | 
|---|
| 106 |  | 
|---|
| 107 | /* visual elements of planets | 
|---|
| 108 | * [planet][0] = angular size at 1 AU | 
|---|
| 109 | * [planet][1] = magnitude at 1 AU from sun and earth and 0 deg phase angle | 
|---|
| 110 | */ | 
|---|
| 111 | static double vis_elements[8][2] = { | 
|---|
| 112 | /* Mercury */   { 6.74, -0.42, }, | 
|---|
| 113 | /* Venus */     { 16.92, -4.34, }, | 
|---|
| 114 | /* Mars */      { 9.36, -1.20, }, | 
|---|
| 115 | /* Jupiter */   { 196.74, -9.4, }, | 
|---|
| 116 | /* Saturn */    { 165.6, -8.88, }, | 
|---|
| 117 | /* Uranus */    { 65.8, -7.19, }, | 
|---|
| 118 | /* Neptune */   { 62.2, -6.87, }, | 
|---|
| 119 | /* Pluto */     { 8.2, -1.0, } | 
|---|
| 120 | }; | 
|---|
| 121 |  | 
|---|
| 122 | /* given a modified Julian date, mjd, and a planet, p, find: | 
|---|
| 123 | *   lpd0: heliocentric longitude, | 
|---|
| 124 | *   psi0: heliocentric latitude, | 
|---|
| 125 | *   rp0:  distance from the sun to the planet, | 
|---|
| 126 | *   rho0: distance from the Earth to the planet, | 
|---|
| 127 | *         none corrected for light time, ie, they are the true values for the | 
|---|
| 128 | *         given instant. | 
|---|
| 129 | *   lam:  geocentric ecliptic longitude, | 
|---|
| 130 | *   bet:  geocentric ecliptic latitude, | 
|---|
| 131 | *         each corrected for light time, ie, they are the apparent values as | 
|---|
| 132 | *         seen from the center of the Earth for the given instant. | 
|---|
| 133 | *   dia:  angular diameter in arcsec at 1 AU, | 
|---|
| 134 | *   mag:  visual magnitude when 1 AU from sun and earth at 0 phase angle. | 
|---|
| 135 | * | 
|---|
| 136 | * all angles are in radians, all distances in AU. | 
|---|
| 137 | * | 
|---|
| 138 | * corrections for nutation and abberation must be made by the caller. The RA | 
|---|
| 139 | *   and DEC calculated from the fully-corrected ecliptic coordinates are then | 
|---|
| 140 | *   the apparent geocentric coordinates. Further corrections can be made, if | 
|---|
| 141 | *   required, for atmospheric refraction and geocentric parallax. | 
|---|
| 142 | */ | 
|---|
| 143 | void | 
|---|
| 144 | plans (mjd, p, lpd0, psi0, rp0, rho0, lam, bet, dia, mag) | 
|---|
| 145 | double mjd; | 
|---|
| 146 | int p; | 
|---|
| 147 | double *lpd0, *psi0, *rp0, *rho0, *lam, *bet, *dia, *mag; | 
|---|
| 148 | { | 
|---|
| 149 | static double lastmjd = -10000; | 
|---|
| 150 | static double lsn, bsn, rsn;    /* geometric geocentric coords of sun */ | 
|---|
| 151 | static double xsn, ysn, zsn; | 
|---|
| 152 | double lp, bp, rp;              /* heliocentric coords of planet */ | 
|---|
| 153 | double xp, yp, zp, rho;         /* rect. coords and geocentric dist. */ | 
|---|
| 154 | double dt;                      /* light time */ | 
|---|
| 155 | int pass; | 
|---|
| 156 |  | 
|---|
| 157 | /* get sun cartesian; needed only once at mjd */ | 
|---|
| 158 | if (mjd != lastmjd) { | 
|---|
| 159 | sunpos (mjd, &lsn, &rsn, &bsn); | 
|---|
| 160 | sphcart (lsn, bsn, rsn, &xsn, &ysn, &zsn); | 
|---|
| 161 | lastmjd = mjd; | 
|---|
| 162 | } | 
|---|
| 163 |  | 
|---|
| 164 | /* first find the true position of the planet at mjd. | 
|---|
| 165 | * then repeat a second time for a slightly different time based | 
|---|
| 166 | * on the position found in the first pass to account for light-travel | 
|---|
| 167 | * time. | 
|---|
| 168 | */ | 
|---|
| 169 | dt = 0.0; | 
|---|
| 170 | for (pass = 0; pass < 2; pass++) { | 
|---|
| 171 | double ret[6]; | 
|---|
| 172 |  | 
|---|
| 173 | /* get spherical coordinates of planet from precision routines, | 
|---|
| 174 | * retarded for light time in second pass; | 
|---|
| 175 | * alternative option:  vsop allows calculating rates. | 
|---|
| 176 | */ | 
|---|
| 177 | planpos(mjd - dt, p, 0.0, ret); | 
|---|
| 178 |  | 
|---|
| 179 | lp = ret[0]; | 
|---|
| 180 | bp = ret[1]; | 
|---|
| 181 | rp = ret[2]; | 
|---|
| 182 |  | 
|---|
| 183 | sphcart (lp, bp, rp, &xp, &yp, &zp); | 
|---|
| 184 | cartsph (xp + xsn, yp + ysn, zp + zsn, lam, bet, &rho); | 
|---|
| 185 |  | 
|---|
| 186 | if (pass == 0) { | 
|---|
| 187 | /* save heliocentric coordinates at first pass since, being | 
|---|
| 188 | * true, they are NOT to be corrected for light-travel time. | 
|---|
| 189 | */ | 
|---|
| 190 | *lpd0 = lp; | 
|---|
| 191 | range (lpd0, 2.*PI); | 
|---|
| 192 | *psi0 = bp; | 
|---|
| 193 | *rp0 = rp; | 
|---|
| 194 | *rho0 = rho; | 
|---|
| 195 | } | 
|---|
| 196 |  | 
|---|
| 197 | /* when we view a planet we see it in the position it occupied | 
|---|
| 198 | * dt days ago, where rho is the distance between it and earth, | 
|---|
| 199 | * in AU. use this as the new time for the next pass. | 
|---|
| 200 | */ | 
|---|
| 201 | dt = rho * 5.7755183e-3; | 
|---|
| 202 | } | 
|---|
| 203 |  | 
|---|
| 204 | *dia = vis_elements[p][0]; | 
|---|
| 205 | *mag = vis_elements[p][1]; | 
|---|
| 206 | } | 
|---|
| 207 |  | 
|---|
| 208 | /* For RCS Only -- Do Not Edit */ | 
|---|
| 209 | static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: plans.c,v $ $Date: 2001-04-10 14:40:47 $ $Revision: 1.1.1.1 $ $Name: not supported by cvs2svn $"}; | 
|---|