/* computes a planet from osculating elements * * tjd julian day * ipl body number * ipli body number in planetary data structure * iflag flags */ int swi_osc_el_plan(double tjd, double *xp, int ipl, int ipli, double *xearth, double *xsun, char *serr) { double pqr[9], x[6]; double eps, K, fac, rho, cose, sine; double alpha, beta, zeta, sigma, M2, Msgn, M_180_or_0; double tjd0, tequ, mano, sema, ecce, parg, node, incl, dmot; double cosnode, sinnode, cosincl, sinincl, cosparg, sinparg; double M, E; struct plan_data *pedp = &swed.pldat[SEI_EARTH]; struct plan_data *pdp = &swed.pldat[ipli]; int32 fict_ifl = 0; int i; /* orbital elements, either from file or, if file not found, * from above built-in set */ if (read_elements_file(ipl, tjd, &tjd0, &tequ, &mano, &sema, &ecce, &parg, &node, &incl, NULL, &fict_ifl, serr) == ERR) return ERR; dmot = 0.9856076686 * DEGTORAD / sema / sqrt(sema); /* daily motion */ if (fict_ifl & FICT_GEO) dmot /= sqrt(SUN_EARTH_MRAT); cosnode = cos(node); sinnode = sin(node); cosincl = cos(incl); sinincl = sin(incl); cosparg = cos(parg); sinparg = sin(parg); /* Gaussian vector */ pqr[0] = cosparg * cosnode - sinparg * cosincl * sinnode; pqr[1] = -sinparg * cosnode - cosparg * cosincl * sinnode; pqr[2] = sinincl * sinnode; pqr[3] = cosparg * sinnode + sinparg * cosincl * cosnode; pqr[4] = -sinparg * sinnode + cosparg * cosincl * cosnode; pqr[5] = -sinincl * cosnode; pqr[6] = sinparg * sinincl; pqr[7] = cosparg * sinincl; pqr[8] = cosincl; /* Kepler problem */ E = M = swi_mod2PI(mano + (tjd - tjd0) * dmot); /* mean anomaly of date */ /* better E for very high eccentricity and small M */ if (ecce > 0.975) { M2 = M * RADTODEG; if (M2 > 150 && M2 < 210) { M2 -= 180; M_180_or_0 = 180; } else M_180_or_0 = 0; if (M2 > 330) M2 -= 360; if (M2 < 0) { M2 = -M2; Msgn = -1; } else Msgn = 1; if (M2 < 30) { M2 *= DEGTORAD; alpha = (1 - ecce) / (4 * ecce + 0.5); beta = M2 / (8 * ecce + 1); zeta = pow(beta + sqrt(beta * beta + alpha * alpha), 1/3); sigma = zeta - alpha / 2; sigma = sigma - 0.078 * sigma * sigma * sigma * sigma * sigma / (1 + ecce); E = Msgn * (M2 + ecce * (3 * sigma - 4 * sigma * sigma * sigma)) + M_180_or_0; } } E = swi_kepler(E, M, ecce); /* position and speed, referred to orbital plane */ if (fict_ifl & FICT_GEO) K = KGAUSS_GEO / sqrt(sema); else K = KGAUSS / sqrt(sema); cose = cos(E); sine = sin(E); fac = sqrt((1 - ecce) * (1 + ecce)); rho = 1 - ecce * cose; x[0] = sema * (cose - ecce); x[1] = sema * fac * sine; x[3] = -K * sine / rho; x[4] = K * fac * cose / rho; /* transformation to ecliptic */ xp[0] = pqr[0] * x[0] + pqr[1] * x[1]; xp[1] = pqr[3] * x[0] + pqr[4] * x[1]; xp[2] = pqr[6] * x[0] + pqr[7] * x[1]; xp[3] = pqr[0] * x[3] + pqr[1] * x[4]; xp[4] = pqr[3] * x[3] + pqr[4] * x[4]; xp[5] = pqr[6] * x[3] + pqr[7] * x[4]; /* transformation to equator */ eps = swi_epsiln(tequ); swi_coortrf(xp, xp, -eps); swi_coortrf(xp+3, xp+3, -eps); /* precess to J2000 */ if (tequ != J2000) { swi_precess(xp, tequ, J_TO_J2000); swi_precess(xp+3, tequ, J_TO_J2000); } /* to solar system barycentre */ if (fict_ifl & FICT_GEO) { for (i = 0; i <= 5; i++) { xp[i] += xearth[i]; } } else { for (i = 0; i <= 5; i++) { xp[i] += xsun[i]; } } if (pdp->x == xp) { pdp->teval = tjd; /* for precession! */ pdp->iephe = pedp->iephe; } return OK; }
/* mean lunar apogee ('dark moon', 'lilith') * J julian day * pol return array for position * (polar coordinates of ecliptic of date) * serr error return string */ int swi_mean_apog(double J, double *pol, char *serr) { #if 0 int i; double a, b; double x[3]; #endif double node; char s[AS_MAXCH]; T = (J-J2000)/36525.0; T2 = T*T; #ifndef NO_MOSHIER T3 = T*T2; T4 = T2*T2; #endif /* with elements from swi_moshmoon2(), which are fitted to jpl-ephemeris */ if (J < MOSHNDEPH_START || J > MOSHNDEPH_END) { if (serr != NULL) { sprintf(s, "jd %f outside mean apogee range %.2f .. %.2f ", J, MOSHNDEPH_START, MOSHNDEPH_END); if (strlen(serr) + strlen(s) < AS_MAXCH) strcat(serr, s); } return(ERR); } mean_elements(); pol[0] = swi_mod2PI((LP - MP) * STR + PI); #if 0 a = pol[0]; /* Chapront, according to Meeus, German, p. 339 */ pol[0] = 83.3532430 + 4069.0137111 * T - 0.0103238 * T2 - T3 / 80053 + T4 / 18999000; pol[0] = swi_mod2PI(pol[0] * DEGTORAD + PI); b = pol[0]; printf ("mean apogee\n"); printf ("moshier de404 - chapront %f\"\n", (a-b) * RADTODEG * 3600); #endif pol[1] = 0; pol[2] = MOON_MEAN_DIST * (1 + MOON_MEAN_ECC) / AUNIT; /* apogee */ #if 0 pol[2] = 2 * MOON_MEAN_ECC * MOON_MEAN_DIST / AUNIT; /* 2nd focus */ #endif /* Lilith or Dark Moon is either the empty focal point of the mean * lunar ellipse or, for some people, its apogee ("aphelion"). * This is 180 degrees from the perigee. * * Since the lunar orbit is not in the ecliptic, the apogee must be * projected onto the ecliptic. * Joelle de Gravelaine has in her book "Lilith der schwarze Mond" * (Astrodata, 1990) an ephemeris which gives noon (12.00) positions * but does not project them onto the ecliptic. * This results in a mistake of several arc minutes. * * There is also another problem. The other focal point doesn't * coincide with the geocenter but with the barycenter of the * earth-moon-system. The difference is about 4700 km. If one * took this into account, it would result in an oscillation * of the Black Moon. If defined as the apogee, this oscillation * would be about +/- 40 arcmin. * If defined as the second focus, the effect is very large: * +/- 6 deg! * We neglect this influence. */ /* apogee is now projected onto ecliptic */ node = (LP - NF) * STR; pol[0] = swi_mod2PI(pol[0] - node); swi_polcart(pol, pol); swi_coortrf(pol, pol, -MOON_MEAN_INCL * DEGTORAD); swi_cartpol(pol, pol); pol[0] = swi_mod2PI(pol[0] + node); #if 0 /* speed */ mean_elements(T-PLAN_SPEED_INTV, &LP, &MP, &NF, &M, &D); pol[3] = swi_mod2PI((LP - MP) * STR + PI); pol[4] = 0; pol[5] = MOON_MEAN_DIST * (1 + MOON_MEAN_ECC) / AUNIT; /* apogee */ #if 0 pol[2] = 2 * MOON_MEAN_ECC * MOON_MEAN_DIST / AUNIT; /* 2nd focus */ #endif node = (LP - NF) * STR; pol[3] = swi_mod2PI(pol[3] - node); swi_polcart(pol+3, pol+3); swi_coortrf(pol+3, pol+3, -MOON_MEAN_INCL * DEGTORAD); swi_cartpol(pol+3, pol+3); pol[3] = swi_mod2PI(pol[3] + node); for (i = 0; i <= 2; i++) pol[3+i] = pol[i] - pol[3+i]; pol[3] = swi_mod2PI(pol[3]); #endif return OK; }