home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Education
/
collectionofeducationcarat1997.iso
/
SCIENCE
/
EPHEM421.ZIP
/
PLANS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-13
|
18KB
|
601 lines
#include <stdio.h>
#include <math.h>
#include "astro.h"
#define TWOPI (2*PI)
#define mod2PI(x) ((x) - (long)((x)/TWOPI)*TWOPI)
/* given a modified Julian date, mjd, and a planet, p, find:
* lpd0: heliocentric longitude,
* psi0: heliocentric latitude,
* rp0: distance from the sun to the planet,
* rho0: distance from the Earth to the planet,
* none corrected for light time, ie, they are the true values for the
* given instant.
* lam: geocentric ecliptic longitude,
* bet: geocentric ecliptic latitude,
* each corrected for light time, ie, they are the apparent values as
* seen from the center of the Earth for the given instant.
* dia: angular diameter in arcsec at 1 AU,
* mag: visual magnitude when 1 AU from sun and earth at 0 phase angle.
*
* all angles are in radians, all distances in AU.
* the mean orbital elements are found by calling pelement(), then mutual
* perturbation corrections are applied as necessary.
*
* corrections for nutation and abberation must be made by the caller. The RA
* and DEC calculated from the fully-corrected ecliptic coordinates are then
* the apparent geocentric coordinates. Further corrections can be made, if
* required, for atmospheric refraction and geocentric parallax although the
* intrinsic error herein of about 10 arcseconds is usually the dominant
* error at this stage.
* TODO: combine the several intermediate expressions when get a good compiler.
*/
plans (mjd, p, lpd0, psi0, rp0, rho0, lam, bet, dia, mag)
double mjd;
int p;
double *lpd0, *psi0, *rp0, *rho0, *lam, *bet, *dia, *mag;
{
static double plan[8][9];
static double lastmjd = -10000;
double dl; /* perturbation correction for longitude */
double dr; /* " orbital radius */
double dml; /* " mean longitude */
double ds; /* " eccentricity */
double dm; /* " mean anomaly */
double da; /* " semi-major axis */
double dhl; /* " heliocentric longitude */
double lsn, rsn;/* true geocentric longitude of sun and sun-earth rad */
double mas; /* mean anomaly of the sun */
double re; /* radius of earth's orbit */
double lg; /* longitude of earth */
double map[8]; /* array of mean anomalies for each planet */
double lpd, psi, rp, rho;
double ll, sll, cll;
double t;
double dt;
int pass;
int j;
double s, ma;
double nu, ea;
double lp, om;
double lo, slo, clo;
double inc, y;
double spsi, cpsi;
double rpd;
/* only need to fill in plan[] once for a given mjd */
if (mjd != lastmjd) {
pelement (mjd, plan);
lastmjd = mjd;
}
dt = 0;
t = mjd/36525.;
sunpos (mjd, &lsn, &rsn);
masun (mjd, &mas);
re = rsn;
lg = lsn+PI;
/* first find the true position of the planet at mjd.
* then repeat a second time for a slightly different time based
* on the position found in the first pass to account for light-travel
* time.
*/
for (pass = 0; pass < 2; pass++) {
for (j = 0; j < 8; j++)
map[j] = degrad(plan[j][0]-plan[j][2]-dt*plan[j][1]);
/* set initial corrections to 0.
* then modify as necessary for the planet of interest.
*/
dl = 0;
dr = 0;
dml = 0;
ds = 0;
dm = 0;
da = 0;
dhl = 0;
switch (p) {
case MERCURY:
p_mercury (map, &dl, &dr);
break;
case VENUS:
p_venus (t, mas, map, &dl, &dr, &dml, &dm);
break;
case MARS:
p_mars (mas, map, &dl, &dr, &dml, &dm);
break;
case JUPITER:
p_jupiter (t, plan[p][3], &dml, &ds, &dm, &da);
break;
case SATURN:
p_saturn (t, plan[p][3], &dml, &ds, &dm, &da, &dhl);
break;
case URANUS:
p_uranus (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
break;
case NEPTUNE:
p_neptune (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
break;
case PLUTO:
/* no perturbation theory for pluto */
break;
}
s = plan[p][3]+ds;
ma = map[p]+dm;
anomaly (ma, s, &nu, &ea);
rp = (plan[p][6]+da)*(1-s*s)/(1+s*cos(nu));
lp = raddeg(nu)+plan[p][2]+raddeg(dml-dm);
lp = degrad(lp);
om = degrad(plan[p][5]);
lo = lp-om;
slo = sin(lo);
clo = cos(lo);
inc = degrad(plan[p][4]);
rp = rp+dr;
spsi = slo*sin(inc);
y = slo*cos(inc);
psi = asin(spsi)+dhl;
spsi = sin(psi);
lpd = atan(y/clo)+om+degrad(dl);
if (clo<0) lpd += PI;
range (&lpd, TWOPI);
cpsi = cos(psi);
rpd = rp*cpsi;
ll = lpd-lg;
rho = sqrt(re*re+rp*rp-2*re*rp*cpsi*cos(ll));
/* when we view a planet we see it in the position it occupied
* dt days ago, where rho is the distance between it and earth,
* in AU. use this as the new time for the next pass.
*/
dt = rho*5.775518e-3;
if (pass == 0) {
/* save heliocentric coordinates after first pass since, being
* true, they are NOT to be corrected for light-travel time.
*/
*lpd0 = lpd;
range (lpd0, TWOPI);
*psi0 = psi;
*rp0 = rp;
*rho0 = rho;
}
}
sll = sin(ll);
cll = cos(ll);
if (p < MARS)
*lam = atan(-1*rpd*sll/(re-rpd*cll))+lg+PI;
else
*lam = atan(re*sll/(rpd-re*cll))+lpd;
range (lam, TWOPI);
*bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*re*sll));
*dia = plan[p][7];
*mag = plan[p][8];
}
/* set auxilliary variables used for jupiter, saturn, uranus, and neptune */
static
aux_jsun (t, x1, x2, x3, x4, x5, x6)
double t;
double *x1, *x2, *x3, *x4, *x5, *x6;
{
*x1 = t/5+0.1;
*x2 = mod2PI(4.14473+5.29691e1*t);
*x3 = mod2PI(4.641118+2.132991e1*t);
*x4 = mod2PI(4.250177+7.478172*t);
*x5 = 5 * *x3 - 2 * *x2;
*x6 = 2 * *x2 - 6 * *x3 + 3 * *x4;
}
/* find the mean anomaly of the sun at mjd.
* this is the same as that used in sun() but when it was converted to C it
* was not known it would be required outside that routine.
* TODO: add an argument to sun() to return mas and eliminate this routine.
*/
static
masun (mjd, mas)
double mjd;
double *mas;
{
double t, t2;
double a, b;
t = mjd/36525;
t2 = t*t;
a = 9.999736042e1*t;
b = 360.*(a-(long)a);
*mas = degrad (3.5847583e2-(1.5e-4+3.3e-6*t)*t2+b);
}
/* perturbations for mercury */
static
p_mercury (map, dl, dr)
double map[];
double *dl, *dr;
{
*dl = 2.04e-3*cos(5*map[2-1]-2*map[1-1]+2.1328e-1)+
1.03e-3*cos(2*map[2-1]-map[1-1]-2.8046)+
9.1e-4*cos(2*map[3]-map[1-1]-6.4582e-1)+
7.8e-4*cos(5*map[2-1]-3*map[1-1]+1.7692e-1);
*dr = 7.525e-6*cos(2*map[3]-map[1-1]+9.25251e-1)+
6.802e-6*cos(5*map[2-1]-3*map[1-1]-4.53642)+
5.457e-6*cos(2*map[2-1]-2*map[1-1]-1.24246)+
3.569e-6*cos(5*map[2-1]-map[1-1]-1.35699);
}
/* ....venus */
static
p_venus (t, mas, map, dl, dr, dml, dm)
double t, mas, map[];
double *dl, *dr, *dml, *dm;
{
*dml = degrad (7.7e-4*sin(4.1406+t*2.6227));
*dm = *dml;
*dl = 3.13e-3*cos(2*mas-2*map[2-1]-2.587)+
1.98e-3*cos(3*mas-3*map[2-1]+4.4768e-2)+
1.36e-3*cos(mas-map[2-1]-2.0788)+
9.6e-4*cos(3*mas-2*map[2-1]-2.3721)+
8.2e-4*cos(map[3]-map[2-1]-3.6318);
*dr = 2.2501e-5*cos(2*mas-2*map[2-1]-1.01592)+
1.9045e-5*cos(3*mas-3*map[2-1]+1.61577)+
6.887e-6*cos(map[3]-map[2-1]-2.06106)+
5.172e-6*cos(mas-map[2-1]-5.08065e-1)+
3.62e-6*cos(5*mas-4*map[2-1]-1.81877)+
3.283e-6*cos(4*mas-4*map[2-1]+1.10851)+
3.074e-6*cos(2*map[3]-2*map[2-1]-9.62846e-1);
}
/* ....mars */
static
p_mars (mas, map, dl, dr, dml, dm)
double mas, map[];
double *dl, *dr, *dml, *dm;
{
double a;
a = 3*map[3]-8*map[2]+4*mas;
*dml = degrad (-1*(1.133e-2*sin(a)+9.33e-3*cos(a)));
*dm = *dml;
*dl = 7.05e-3*cos(map[3]-map[2]-8.5448e-1)+
6.07e-3*cos(2*map[3]-map[2]-3.2873)+
4.45e-3*cos(2*map[3]-2*map[2]-3.3492)+
3.88e-3*cos(mas-2*map[2]+3.5771e-1)+
2.38e-3*cos(mas-map[2]+6.1256e-1)+
2.04e-3*cos(2*mas-3*map[2]+2.7688)+
1.77e-3*cos(3*map[2]-map[2-1]-1.0053)+
1.36e-3*cos(2*mas-4*map[2]+2.689