/* mean lunar node * J julian day * pol return array for position and velocity * (polar coordinates of ecliptic of date) */ int swi_mean_node(double J, double *pol, char *serr) { #if 0 double a, b, c; #endif char s[AS_MAXCH]; T = (J-J2000)/36525.0; T2 = T*T; #ifndef NO_MOSHIER T3 = T*T2; T4 = T2*T2; #endif /* NO_MOSHIER */ /* 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 node range %.2f .. %.2f ", J, MOSHNDEPH_START, MOSHNDEPH_END); if (strlen(serr) + strlen(s) < AS_MAXCH) strcat(serr, s); } return ERR; } mean_elements(); /* longitude */ pol[0] = swi_mod2PI((LP - NF) * STR); /* latitude */ pol[1] = 0.0; /* distance */ pol[2] = MOON_MEAN_DIST / AUNIT; /* or should it be derived from mean * orbital ellipse? */ #if 0 a = pol[0]; /* Chapront, according to Meeus, German, p. 339 */ pol[0] = 125.0445550 - 1934.1361849 * T + 0.0020762 * T2 + T3 / 467410 - T4 / 60616000; pol[0] = swi_mod2PI(pol[0] * DEGTORAD); c = pol[0]; printf ("mean node\n"); printf ("moshier de404 - chapront %f\"\n", (a-c) * RADTODEG * 3600); #endif return OK; }
/* 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; }
int swe_sx_nod_aps(double tjd_et, int ind, int iflag, int method, double *xnasc, double *xndsc, double *xperi, double *xaphe, char *serr) { int ij, i, j,ipl,fEquatorT,fUseJ2000T; int32 iplx; int32 ipli; int istart, iend; int32 iflJ2000; double plm; double t = (tjd_et - J2000) / 36525, dt; double x[6], xx[24], *xp, xobs[6], x2000[6]; double xpos[3][6], xnorm[6]; double xposm[6]; double xn[3][6], xs[3][6]; double xq[3][6], xa[3][6]; double xobs2[6], x2[6]; double *xna, *xnd, *xpe, *xap; double incl, sema, ecce, parg, ea, vincl, vsema, vecce, pargx, eax; struct plan_data *pedp = &swed.pldat[SEI_EARTH]; struct plan_data *psbdp = &swed.pldat[SEI_SUNBARY]; struct plan_data pldat; double *xsun = psbdp->x; double *xear = pedp->x; double *ep; double Gmsm, dzmin; double rxy, rxyz, fac, sgn; double sinnode, cosnode, sinincl, cosincl, sinu, cosu, sinE, cosE, cosE2; double uu, ny, ny2, c2, v2, pp, ro, ro2, rn, rn2; struct epsilon *oe; AS_BOOL is_true_nodaps = FALSE; AS_BOOL do_aberr = !(iflag & (SEFLG_TRUEPOS | SEFLG_NOABERR)); AS_BOOL do_defl = !(iflag & SEFLG_TRUEPOS) && !(iflag & SEFLG_NOGDEFL); AS_BOOL do_focal_point = method & SE_NODBIT_FOPOINT; AS_BOOL ellipse_is_bary = FALSE; int32 iflg0; /* function calls for Pluto with asteroid number 134340 * are treated as calls for Pluto as main body SE_PLUTO */ ipl = AlToSweObj(ind); if (ipl == SE_WHITE_MOON) ipl = SE_AST_OFFSET+MaxNumberedAsteroid; if (ipl == SE_AST_OFFSET + 134340) ipl = SE_PLUTO; xna = xx; xnd = xx+6; xpe = xx+12; xap = xx+18; xpos[0][0] = 0; /* to shut up mint */ /* to get control over the save area: */ swi_force_app_pos_etc(); method %= SE_NODBIT_FOPOINT; ipli = ipl; if (ipl == SE_SUN) ipli = SE_EARTH; if (ipl == SE_MOON) { do_defl = FALSE; if (!(iflag & SEFLG_HELCTR)) do_aberr = FALSE; } iflg0 = (iflag & (SEFLG_EPHMASK|SEFLG_NONUT)) | SEFLG_SPEED | SEFLG_TRUEPOS; if (ipli != SE_MOON) iflg0 |= SEFLG_HELCTR; if (ipl == SE_MEAN_NODE || ipl == SE_TRUE_NODE || ipl == SE_MEAN_APOG || ipl == SE_OSCU_APOG || ipl < 0 || (ipl >= SE_NPLANETS && ipl <= SE_AST_OFFSET)) { /*(ipl >= SE_FICT_OFFSET && ipl - SE_FICT_OFFSET < SE_NFICT_ELEM)) */ if (serr != NULL) sprintf(serr, "nodes/apsides for planet %5.0f are not implemented", (double) ipl); if (xnasc != NULL) for (i = 0; i <= 5; i++) xnasc[i] = 0; if (xndsc != NULL) for (i = 0; i <= 5; i++) xndsc[i] = 0; if (xaphe != NULL) for (i = 0; i <= 5; i++) xaphe[i] = 0; if (xperi != NULL) for (i = 0; i <= 5; i++) xperi[i] = 0; return ERR; } for (i = 0; i < 24; i++) xx[i] = 0; /*************************************** * mean nodes and apsides ***************************************/ /* mean points only for Sun - Neptune */ if ((method == 0 || (method & SE_NODBIT_MEAN)) && ((ipl >= SE_SUN && ipl <= SE_NEPTUNE) || ipl == SE_EARTH)) { if (ipl == SE_MOON) { swi_mean_lunar_elements(tjd_et, &xna[0], &xna[3], &xpe[0], &xpe[3]); incl = MOON_MEAN_INCL; vincl = 0; ecce = MOON_MEAN_ECC; vecce = 0; sema = MOON_MEAN_DIST / AUNIT; vsema = 0; } else { iplx = ipl_to_elem[ipl]; ep = el_incl[iplx]; incl = ep[0] + ep[1] * t + ep[2] * t * t + ep[3] * t * t * t; vincl = ep[1] / 36525; ep = el_sema[iplx]; sema = ep[0] + ep[1] * t + ep[2] * t * t + ep[3] * t * t * t; vsema = ep[1] / 36525; ep = el_ecce[iplx]; ecce = ep[0] + ep[1] * t + ep[2] * t * t + ep[3] * t * t * t; vecce = ep[1] / 36525; ep = el_node[iplx]; /* ascending node */ xna[0] = ep[0] + ep[1] * t + ep[2] * t * t + ep[3] * t * t * t; xna[3] = ep[1] / 36525; /* perihelion */ ep = el_peri[iplx]; xpe[0] = ep[0] + ep[1] * t + ep[2] * t * t + ep[3] * t * t * t; xpe[3] = ep[1] / 36525; } /* descending node */ xnd[0] = swe_degnorm(xna[0] + 180); xnd[3] = xna[3]; /* angular distance of perihelion from node */ parg = xpe[0] = swe_degnorm(xpe[0] - xna[0]); pargx = xpe[3] = swe_degnorm(xpe[0] + xpe[3] - xna[3]); /* transform from orbital plane to mean ecliptic of date */ swe_cotrans(xpe, xpe, -incl); /* xpe+3 is aux. position, not speed!!! */ swe_cotrans(xpe+3, xpe+3, -incl-vincl); /* add node again */ xpe[0] = swe_degnorm(xpe[0] + xna[0]); /* xpe+3 is aux. position, not speed!!! */ xpe[3] = swe_degnorm(xpe[3] + xna[0] + xna[3]); /* speed */ xpe[3] = swe_degnorm(xpe[3] - xpe[0]); /* heliocentric distance of perihelion and aphelion */ xpe[2] = sema * (1 - ecce); xpe[5] = (sema + vsema) * (1 - ecce - vecce) - xpe[2]; /* aphelion */ xap[0] = swe_degnorm(xpe[0] + 180); xap[1] = -xpe[1]; xap[3] = xpe[3]; xap[4] = -xpe[4]; if (do_focal_point) { xap[2] = sema * ecce * 2; xap[5] = (sema + vsema) * (ecce + vecce) * 2 - xap[2]; } else { xap[2] = sema * (1 + ecce); xap[5] = (sema + vsema) * (1 + ecce + vecce) - xap[2]; } /* heliocentric distance of nodes */ ea = atan(tan(-parg * DEGTORAD / 2) * sqrt((1-ecce)/(1+ecce))) * 2; eax = atan(tan(-pargx * DEGTORAD / 2) * sqrt((1-ecce-vecce)/(1+ecce+vecce))) * 2; xna[2] = sema * (cos(ea) - ecce) / cos(parg * DEGTORAD); xna[5] = (sema+vsema) * (cos(eax) - ecce - vecce) / cos(pargx * DEGTORAD); xna[5] -= xna[2]; ea = atan(tan((180 - parg) * DEGTORAD / 2) * sqrt((1-ecce)/(1+ecce))) * 2; eax = atan(tan((180 - pargx) * DEGTORAD / 2) * sqrt((1-ecce-vecce)/(1+ecce+vecce))) * 2; xnd[2] = sema * (cos(ea) - ecce) / cos((180 - parg) * DEGTORAD); xnd[5] = (sema+vsema) * (cos(eax) - ecce - vecce) / cos((180 - pargx) * DEGTORAD); xnd[5] -= xnd[2]; /* no light-time correction because speed is extremely small */ for (i = 0, xp = xx; i < 4; i++, xp += 6) { /* to cartesian coordinates */ xp[0] *= DEGTORAD; xp[1] *= DEGTORAD; xp[3] *= DEGTORAD; xp[4] *= DEGTORAD; swi_polcart_sp(xp, xp); } /*************************************** * "true" or osculating nodes and apsides ***************************************/ } else { /* first, we need a heliocentric distance of the planet */ if (swe_calc(tjd_et, ipli, iflg0, x, serr) == ERR) { if (FRiyalNumbered(tjd_et,ind,fTrue)) { x[0]=planet[ind]; x[1]=planetalt[ind]; x[2]=planetdis[ind]; x[3]=ret[ind]; x[4]=altret[ind]; x[5]=disret[ind]; } else return ERR; } iflJ2000 = (iflag & SEFLG_EPHMASK)|SEFLG_J2000|SEFLG_EQUATORIAL|SEFLG_XYZ|SEFLG_TRUEPOS|SEFLG_NONUT|SEFLG_SPEED; ellipse_is_bary = FALSE; if (ipli != SE_MOON) { if ((method & SE_NODBIT_OSCU_BAR) && x[2] > 6) { iflJ2000 |= SEFLG_BARYCTR; /* only planets beyond Jupiter */ ellipse_is_bary = TRUE; } else { iflJ2000 |= SEFLG_HELCTR; } } /* we need three positions and three speeds * for three nodes/apsides. from the three node positions, * the speed of the node will be computed. */ if (ipli == SE_MOON) { dt = NODE_CALC_INTV; dzmin = 1e-15; Gmsm = GEOGCONST * (1 + 1 / EARTH_MOON_MRAT) /AUNIT/AUNIT/AUNIT*86400.0*86400.0; } else { if ((ipli >= SE_MERCURY && ipli <= SE_PLUTO) || ipli == SE_EARTH) plm = 1 / plmass[ipl_to_elem[ipl]]; else plm = 0; dt = NODE_CALC_INTV * 10 * x[2]; dzmin = 1e-15 * dt / NODE_CALC_INTV; Gmsm = HELGRAVCONST * (1 + plm) /AUNIT/AUNIT/AUNIT*86400.0*86400.0; } if (iflag & SEFLG_SPEED) { istart = 0; iend = 2; } else { istart = iend = 0; dt = 0; } for (i = istart, t = tjd_et - dt; i <= iend; i++, t += dt) { if (istart == iend) t = tjd_et; if (swe_calc(t, ipli, iflJ2000, xpos[i], serr) == ERR) { fUseJ2000T=fUseJ2000; fEquatorT=us.fEquator; fUseJ2000=fTrue; us.fEquator=fTrue; if (FRiyalNumbered(t,ind,fTrue)) { xpos[i][0]=spacex[ind]; xpos[i][1]=spacey[ind]; xpos[i][2]=spacez[ind]; xpos[i][3]=spacedx[ind]; xpos[i][4]=spacedy[ind]; xpos[i][5]=spacedz[ind]; fUseJ2000=fUseJ2000T; us.fEquator=fEquatorT; } else return ERR; } /* the EMB is used instead of the earth */ if (ipli == SE_EARTH) { if (swe_calc(t, SE_MOON, iflJ2000 & ~(SEFLG_BARYCTR|SEFLG_HELCTR), xposm, serr) == ERR) return ERR; for (j = 0; j <= 2; j++) xpos[i][j] += xposm[j] / (EARTH_MOON_MRAT + 1.0); } swi_plan_for_osc_elem(iflg0, t, xpos[i]); } for (i = istart; i <= iend; i++) { if (fabs(xpos[i][5]) < dzmin) xpos[i][5] = dzmin; fac = xpos[i][2] / xpos[i][5]; sgn = xpos[i][5] / fabs(xpos[i][5]); for (j = 0; j <= 2; j++) { xn[i][j] = (xpos[i][j] - fac * xpos[i][j+3]) * sgn; xs[i][j] = -xn[i][j]; } } for (i = istart; i <= iend; i++) { /* node */ rxy = sqrt(xn[i][0] * xn[i][0] + xn[i][1] * xn[i][1]); cosnode = xn[i][0] / rxy; sinnode = xn[i][1] / rxy; /* inclination */ swi_cross_prod(xpos[i], xpos[i]+3, xnorm); rxy = xnorm[0] * xnorm[0] + xnorm[1] * xnorm[1]; c2 = (rxy + xnorm[2] * xnorm[2]); rxyz = sqrt(c2); rxy = sqrt(rxy); sinincl = rxy / rxyz; cosincl = sqrt(1 - sinincl * sinincl); if (xnorm[2] < 0) cosincl = -cosincl; /* retrograde asteroid, e.g. 20461 Dioretsa */ /* argument of latitude */ cosu = xpos[i][0] * cosnode + xpos[i][1] * sinnode; sinu = xpos[i][2] / sinincl; uu = atan2(sinu, cosu); /* semi-axis */ rxyz = sqrt(square_sum(xpos[i])); v2 = square_sum((xpos[i]+3)); sema = 1 / (2 / rxyz - v2 / Gmsm); /* eccentricity */ pp = c2 / Gmsm; ecce = sqrt(1 - pp / sema); /* eccentric anomaly */ cosE = 1 / ecce * (1 - rxyz / sema); sinE = 1 / ecce / sqrt(sema * Gmsm) * dot_prod(xpos[i], (xpos[i]+3)); /* true anomaly */ ny = 2 * atan(sqrt((1+ecce)/(1-ecce)) * sinE / (1 + cosE)); /* distance of perihelion from ascending node */ xq[i][0] = swi_mod2PI(uu - ny); xq[i][1] = 0; /* latitude */ xq[i][2] = sema * (1 - ecce); /* distance of perihelion */ /* transformation to ecliptic coordinates */ swi_polcart(xq[i], xq[i]); swi_coortrf2(xq[i], xq[i], -sinincl, cosincl); swi_cartpol(xq[i], xq[i]); /* adding node, we get perihelion in ecl. coord. */ xq[i][0] += atan2(sinnode, cosnode); xa[i][0] = swi_mod2PI(xq[i][0] + PI); xa[i][1] = -xq[i][1]; if (do_focal_point) { xa[i][2] = sema * ecce * 2; /* distance of aphelion */ } else { xa[i][2] = sema * (1 + ecce); /* distance of aphelion */ } swi_polcart(xq[i], xq[i]); swi_polcart(xa[i], xa[i]); /* new distance of node from orbital ellipse: * true anomaly of node: */ ny = swi_mod2PI(ny - uu); ny2 = swi_mod2PI(ny + PI); /* eccentric anomaly */ cosE = cos(2 * atan(tan(ny / 2) / sqrt((1+ecce) / (1-ecce)))); cosE2 = cos(2 * atan(tan(ny2 / 2) / sqrt((1+ecce) / (1-ecce)))); /* new distance */ rn = sema * (1 - ecce * cosE); rn2 = sema * (1 - ecce * cosE2); /* old node distance */ ro = sqrt(square_sum(xn[i])); ro2 = sqrt(square_sum(xs[i])); /* correct length of position vector */ for (j = 0; j <= 2; j++) { xn[i][j] *= rn / ro; xs[i][j] *= rn2 / ro2; } } for (i = 0; i <= 2; i++) { if (iflag & SEFLG_SPEED) { xpe[i] = xq[1][i]; xpe[i+3] = (xq[2][i] - xq[0][i]) / dt / 2; xap[i] = xa[1][i]; xap[i+3] = (xa[2][i] - xa[0][i]) / dt / 2; xna[i] = xn[1][i]; xna[i+3] = (xn[2][i] - xn[0][i]) / dt / 2; xnd[i] = xs[1][i]; xnd[i+3] = (xs[2][i] - xs[0][i]) / dt / 2; } else { xpe[i] = xq[0][i]; xpe[i+3] = 0; xap[i] = xa[0][i]; xap[i+3] = 0; xna[i] = xn[0][i]; xna[i+3] = 0; xnd[i] = xs[0][i]; xnd[i+3] = 0; } } is_true_nodaps = TRUE; } /* to set the variables required in the save area, * i.e. ecliptic, nutation, barycentric sun, earth * we compute the planet */ if (ipli == SE_MOON && (iflag & (SEFLG_HELCTR | SEFLG_BARYCTR))) { swi_force_app_pos_etc(); if (swe_calc(tjd_et, SE_SUN, iflg0, x, serr) == ERR) return ERR; } else { if (swe_calc(tjd_et, ipli, iflg0 | (iflag & SEFLG_TOPOCTR), x, serr) == ERR) { if (FRiyalNumbered(tjd_et,ind,iflg0 && SEFLG_HELCTR)) { x[0]=planet[ind]; x[1]=planetalt[ind]; x[2]=planetdis[ind]; x[3]=ret[ind]; x[4]=altret[ind]; x[5]=disret[ind]; } else return ERR; } } /*********************** * position of observer ***********************/ if (iflag & SEFLG_TOPOCTR) { /* geocentric position of observer */ if (swi_get_observer(tjd_et, iflag, FALSE, xobs, serr) != OK) return ERR; /*for (i = 0; i <= 5; i++) xobs[i] = swed.topd.xobs[i];*/ } else { for (i = 0; i <= 5; i++) xobs[i] = 0; } if (iflag & (SEFLG_HELCTR | SEFLG_BARYCTR)) { if ((iflag & SEFLG_HELCTR) && !(iflag & SEFLG_MOSEPH)) for (i = 0; i <= 5; i++) xobs[i] = xsun[i]; } else if (ipl == SE_SUN && !(iflag & SEFLG_MOSEPH)) { for (i = 0; i <= 5; i++) xobs[i] = xsun[i]; } else { /* barycentric position of observer */ for (i = 0; i <= 5; i++) xobs[i] += xear[i]; } /* ecliptic obliqity */ if (iflag & SEFLG_J2000) oe = &swed.oec2000; else oe = &swed.oec; /************************************************* * conversions shared by mean and osculating points *************************************************/ for (ij = 0, xp = xx; ij < 4; ij++, xp += 6) { /* no nodes for earth */ if (ipli == SE_EARTH && ij <= 1) { for (i = 0; i <= 5; i++) xp[i] = 0; continue; } /********************* * to equator *********************/ if (is_true_nodaps && !(iflag & SEFLG_NONUT)) { swi_coortrf2(xp, xp, -swed.nut.snut, swed.nut.cnut); if (iflag & SEFLG_SPEED) swi_coortrf2(xp+3, xp+3, -swed.nut.snut, swed.nut.cnut); } swi_coortrf2(xp, xp, -oe->seps, oe->ceps); swi_coortrf2(xp+3, xp+3, -oe->seps, oe->ceps); if (is_true_nodaps) { /**************************** * to mean ecliptic of date ****************************/ if (!(iflag & SEFLG_NONUT)) swi_nutate(xp, iflag, TRUE); } /********************* * to J2000 *********************/ swi_precess(xp, tjd_et, J_TO_J2000); if (iflag & SEFLG_SPEED) swi_precess_speed(xp, tjd_et, J_TO_J2000); /********************* * to barycenter *********************/ if (ipli == SE_MOON) { for (i = 0; i <= 5; i++) xp[i] += xear[i]; } else { if (!(iflag & SEFLG_MOSEPH) && !ellipse_is_bary) for (j = 0; j <= 5; j++) xp[j] += xsun[j]; } /********************* * to correct center *********************/ for (j = 0; j <= 5; j++) xp[j] -= xobs[j]; /* geocentric perigee/apogee of sun */ if (ipl == SE_SUN && !(iflag & (SEFLG_HELCTR | SEFLG_BARYCTR))) for (j = 0; j <= 5; j++) xp[j] = -xp[j]; /********************* * light deflection *********************/ dt = sqrt(square_sum(xp)) * AUNIT / CLIGHT / 86400.0; if (do_defl) swi_deflect_light(xp, dt, iflag); /********************* * aberration *********************/ if (do_aberr) { swi_aberr_light(xp, xobs, iflag); /* * Apparent speed is also influenced by * the difference of speed of the earth between t and t-dt. * Neglecting this would result in an error of several 0.1" */ if (iflag & SEFLG_SPEED) { /* get barycentric sun and earth for t-dt into save area */ if (swe_calc(tjd_et - dt, ipli, iflg0 | (iflag & SEFLG_TOPOCTR), x2, serr) == ERR) { if (FRiyalNumbered(tjd_et-dt,ind,iflg0 && SEFLG_HELCTR)) { x2[0]=planet[ind]; x2[1]=planetalt[ind]; x2[2]=planetdis[ind]; x2[3]=ret[ind]; x2[4]=altret[ind]; x2[5]=disret[ind]; } else return ERR; } if (iflag & SEFLG_TOPOCTR) { /* geocentric position of observer */ /* if (swi_get_observer(tjd_et - dt, iflag, FALSE, xobs, serr) != OK) return ERR;*/ for (i = 0; i <= 5; i++) xobs2[i] = swed.topd.xobs[i]; } else { for (i = 0; i <= 5; i++) xobs2[i] = 0; } if (iflag & (SEFLG_HELCTR | SEFLG_BARYCTR)) { if ((iflag & SEFLG_HELCTR) && !(iflag & SEFLG_MOSEPH)) for (i = 0; i <= 5; i++) xobs2[i] = xsun[i]; } else if (ipl == SE_SUN && !(iflag & SEFLG_MOSEPH)) { for (i = 0; i <= 5; i++) xobs2[i] = xsun[i]; } else { /* barycentric position of observer */ for (i = 0; i <= 5; i++) xobs2[i] += xear[i]; } for (i = 3; i <= 5; i++) xp[i] += xobs[i] - xobs2[i]; /* The above call of swe_calc() has destroyed the * parts of the save area * (i.e. bary sun, earth nutation matrix!). * to restore it: */ if (swe_calc(tjd_et, SE_SUN, iflg0 | (iflag & SEFLG_TOPOCTR), x2, serr) == ERR) return ERR; } } /********************* * precession *********************/ /* save J2000 coordinates; required for sidereal positions */ for (j = 0; j <= 5; j++) x2000[j] = xp[j]; if (!(iflag & SEFLG_J2000)) { swi_precess(xp, tjd_et, J2000_TO_J); if (iflag & SEFLG_SPEED) swi_precess_speed(xp, tjd_et, J2000_TO_J); } /********************* * nutation *********************/ if (!(iflag & SEFLG_NONUT)) swi_nutate(xp, iflag, FALSE); /* now we have equatorial cartesian coordinates; keep them */ for (j = 0; j <= 5; j++) pldat.xreturn[18+j] = xp[j]; /************************************************ * transformation to ecliptic. * * with sidereal calc. this will be overwritten * * afterwards. * ************************************************/ swi_coortrf2(xp, xp, oe->seps, oe->ceps); if (iflag & SEFLG_SPEED) swi_coortrf2(xp+3, xp+3, oe->seps, oe->ceps); if (!(iflag & SEFLG_NONUT)) { swi_coortrf2(xp, xp, swed.nut.snut, swed.nut.cnut); if (iflag & SEFLG_SPEED) swi_coortrf2(xp+3, xp+3, swed.nut.snut, swed.nut.cnut); } /* now we have ecliptic cartesian coordinates */ for (j = 0; j <= 5; j++) pldat.xreturn[6+j] = xp[j]; /************************************ * sidereal positions * ************************************/ if (iflag & SEFLG_SIDEREAL) { /* project onto ecliptic t0 */ if (swed.sidd.sid_mode & SE_SIDBIT_ECL_T0) { if (swi_trop_ra2sid_lon(x2000, pldat.xreturn+6, pldat.xreturn+18, iflag, serr) != OK) return ERR; /* project onto solar system equator */ } else if (swed.sidd.sid_mode & SE_SIDBIT_SSY_PLANE) { if (swi_trop_ra2sid_lon_sosy(x2000, pldat.xreturn+6, pldat.xreturn+18, iflag, serr) != OK) return ERR; } else { /* traditional algorithm */ swi_cartpol_sp(pldat.xreturn+6, pldat.xreturn); pldat.xreturn[0] -= swe_get_ayanamsa(tjd_et) * DEGTORAD; swi_polcart_sp(pldat.xreturn, pldat.xreturn+6); } } if ((iflag & SEFLG_XYZ) && (iflag & SEFLG_EQUATORIAL)) { for (j = 0; j <= 5; j++) xp[j] = pldat.xreturn[18+j]; continue; } if (iflag & SEFLG_XYZ) { for (j = 0; j <= 5; j++) xp[j] = pldat.xreturn[6+j]; continue; } /************************************************ * transformation to polar coordinates * ************************************************/ swi_cartpol_sp(pldat.xreturn+18, pldat.xreturn+12); swi_cartpol_sp(pldat.xreturn+6, pldat.xreturn); /********************** * radians to degrees * **********************/ for (j = 0; j < 2; j++) { pldat.xreturn[j] *= RADTODEG; /* ecliptic */ pldat.xreturn[j+3] *= RADTODEG; pldat.xreturn[j+12] *= RADTODEG; /* equator */ pldat.xreturn[j+15] *= RADTODEG; } if (iflag & SEFLG_EQUATORIAL) { for (j = 0; j <= 5; j++) xp[j] = pldat.xreturn[12+j]; continue; } else { for (j = 0; j <= 5; j++) xp[j] = pldat.xreturn[j]; continue; } } for (i = 0; i <= 5; i++) { if (i > 2 && !(iflag & SEFLG_SPEED)) xna[i] = xnd[i] = xpe[i] = xap[i] = 0; if (xnasc != NULL) xnasc[i] = xna[i]; if (xndsc != NULL) xndsc[i] = xnd[i]; if (xperi != NULL) xperi[i] = xpe[i]; if (xaphe != NULL) xaphe[i] = xap[i]; } 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; }