Ejemplo n.º 1
0
/* converts from polar coordinates of ecliptic of date
 *          to   cartesian coordinates of equator 2000
 * tjd		date
 * x 		array of position
 */
static void ecldat_equ2000(double tjd, double *xpm) {
  /* cartesian */
  swi_polcart(xpm, xpm);
  /* equatorial */
  swi_coortrf2(xpm, xpm, -swed.oec.seps, swed.oec.ceps);
  /* j2000 */
  swi_precess(xpm, tjd, J_TO_J2000);/**/
}
Ejemplo n.º 2
0
/* Adjust position from Earth-Moon barycenter to Earth
 *
 * J = Julian day number
 * xemb = rectangular equatorial coordinates of Earth
 */
static void embofs_mosh(double tjd, double *xemb) 
{
  double T, M, a, L, B, p;
  double smp, cmp, s2mp, c2mp, s2d, c2d, sf, cf;
  double s2f, sx, cx, xyz[6];
  double seps = swed.oec.seps;
  double ceps = swed.oec.ceps;
  int i;
  /* Short series for position of the Moon
   */
  T = (tjd-J1900)/36525.0;
  /* Mean anomaly of moon (MP) */
  a = swe_degnorm(((1.44e-5*T + 0.009192)*T + 477198.8491)*T + 296.104608);
  a *= DEGTORAD;
  smp = sin(a);
  cmp = cos(a);
  s2mp = 2.0*smp*cmp;		/* sin(2MP) */
  c2mp = cmp*cmp - smp*smp;	/* cos(2MP) */
  /* Mean elongation of moon (D) */
  a = swe_degnorm(((1.9e-6*T - 0.001436)*T + 445267.1142)*T + 350.737486);
  a  = 2.0 * DEGTORAD * a;
  s2d = sin(a);
  c2d = cos(a);
  /* Mean distance of moon from its ascending node (F) */
  a = swe_degnorm((( -3.e-7*T - 0.003211)*T + 483202.0251)*T + 11.250889);
  a  *= DEGTORAD;
  sf = sin(a);
  cf = cos(a);
  s2f = 2.0*sf*cf;	/* sin(2F) */
  sx = s2d*cmp - c2d*smp;	/* sin(2D - MP) */
  cx = c2d*cmp + s2d*smp;	/* cos(2D - MP) */
  /* Mean longitude of moon (LP) */
  L = ((1.9e-6*T - 0.001133)*T + 481267.8831)*T + 270.434164;
  /* Mean anomaly of sun (M) */
  M = swe_degnorm((( -3.3e-6*T - 1.50e-4)*T + 35999.0498)*T + 358.475833);
  /* Ecliptic longitude of the moon */
  L =	L
	+ 6.288750*smp
	+ 1.274018*sx
	+ 0.658309*s2d
	+ 0.213616*s2mp
	- 0.185596*sin( DEGTORAD * M )
	- 0.114336*s2f;
  /* Ecliptic latitude of the moon */
  a = smp*cf;
  sx = cmp*sf;
  B =	  5.128189*sf
	+ 0.280606*(a+sx)		/* sin(MP+F) */
	+ 0.277693*(a-sx)		/* sin(MP-F) */
	+ 0.173238*(s2d*cf - c2d*sf);	/* sin(2D-F) */
  B *= DEGTORAD;
  /* Parallax of the moon */
  p =	 0.950724
	+0.051818*cmp
	+0.009531*cx
	+0.007843*c2d
	+0.002824*c2mp;
  p *= DEGTORAD;
  /* Elongation of Moon from Sun
   */
  L = swe_degnorm(L);
  L *= DEGTORAD;
  /* Distance in au */
  a = 4.263523e-5/sin(p);
  /* Convert to rectangular ecliptic coordinates */
  xyz[0] = L;
  xyz[1] = B;
  xyz[2] = a;
  swi_polcart(xyz, xyz);
  /* Convert to equatorial */
  swi_coortrf2(xyz, xyz, -seps, ceps);
  /* Precess to equinox of J2000.0 */
  swi_precess(xyz, tjd, J_TO_J2000);/**/
  /* now emb -> earth */
  for (i = 0; i <= 2; i++)
    xemb[i] -= xyz[i] / (EARTH_MOON_MRAT + 1.0);
}
Ejemplo n.º 3
0
/* Moshier ephemeris.
 * computes heliocentric cartesian equatorial coordinates of
 * equinox 2000
 * for earth and a planet
 * tjd		julian day
 * ipli		internal SWEPH planet number
 * xp		array of 6 doubles for planet's position and speed
 * xe		                       earth's
 * serr		error string
 */
int swi_moshplan(double tjd, int ipli, AS_BOOL do_save, double *xpret, double *xeret, char *serr) 
{
  int i;
  int do_earth = FALSE;
  double dx[3], x2[3], xxe[6], xxp[6];
  double *xp, *xe;
  double dt; 
  char s[AS_MAXCH];
  int iplm = pnoint2msh[ipli];
  struct plan_data *pdp = &swed.pldat[ipli];
  struct plan_data *pedp = &swed.pldat[SEI_EARTH];
  double seps2000 = swed.oec2000.seps;
  double ceps2000 = swed.oec2000.ceps;
  if (do_save) {
    xp = pdp->x;
    xe = pedp->x;
  } else {
    xp = xxp;
    xe = xxe;
  }
  if (do_save || ipli == SEI_EARTH || xeret != NULL) 
    do_earth = TRUE;
  /* tjd beyond ephemeris limits, give some margin for spped at edge */
  if (tjd < MOSHPLEPH_START - 0.3 || tjd > MOSHPLEPH_END + 0.3) {
    if (serr != NULL) {
      sprintf(s, "jd %f outside Moshier planet range %.2f .. %.2f ",
		    tjd, MOSHPLEPH_START, MOSHPLEPH_END);
      if (strlen(serr) + strlen(s) < AS_MAXCH)
	strcat(serr, s);
    }
    return(ERR);
  }  
  /* earth, for geocentric position */
  if (do_earth) {
    if (tjd == pedp->teval
	  && pedp->iephe == SEFLG_MOSEPH) {
      xe = pedp->x;
    } else {
      /* emb */
      swi_moshplan2(tjd, pnoint2msh[SEI_EMB], xe); /* emb hel. ecl. 2000 polar */ 
      swi_polcart(xe, xe);			  /* to cartesian */
      swi_coortrf2(xe, xe, -seps2000, ceps2000);/* and equator 2000 */
      embofs_mosh(tjd, xe);		  /* emb -> earth */
      if (do_save) {
	pedp->teval = tjd;		  
	pedp->xflgs = -1;
	pedp->iephe = SEFLG_MOSEPH;
      }
      /* one more position for speed. */
      swi_moshplan2(tjd - PLAN_SPEED_INTV, pnoint2msh[SEI_EMB], x2); 
      swi_polcart(x2, x2);
      swi_coortrf2(x2, x2, -seps2000, ceps2000);
      embofs_mosh(tjd - PLAN_SPEED_INTV, x2);/**/
      for (i = 0; i <= 2; i++) 
	dx[i] = (xe[i] - x2[i]) / PLAN_SPEED_INTV;
      /* store speed */
      for (i = 0; i <= 2; i++) {
	xe[i+3] = dx[i];
      }
    }
    if (xeret != NULL)
      for (i = 0; i <= 5; i++) 
	xeret[i] = xe[i];
  }
  /* earth is the planet wanted */
  if (ipli == SEI_EARTH) {
    xp = xe;
  } else {
    /* other planet */
    /* if planet has already been computed, return */
    if (tjd == pdp->teval && pdp->iephe == SEFLG_MOSEPH) {
      xp = pdp->x;
    } else { 
      swi_moshplan2(tjd, iplm, xp); 
      swi_polcart(xp, xp);
      swi_coortrf2(xp, xp, -seps2000, ceps2000);
      if (do_save) {
	pdp->teval = tjd;/**/
	pdp->xflgs = -1;
	pdp->iephe = SEFLG_MOSEPH;
      }
      /* one more position for speed. 
       * the following dt gives good speed for light-time correction
       */
    #if 0
      for (i = 0; i <= 2; i++) 
	dx[i] = xp[i] - pedp->x[i];
      dt = LIGHTTIME_AUNIT * sqrt(square_sum(dx));   
    #endif
      dt = PLAN_SPEED_INTV;
      swi_moshplan2(tjd - dt, iplm, x2); 
      swi_polcart(x2, x2);
      swi_coortrf2(x2, x2, -seps2000, ceps2000);
      for (i = 0; i <= 2; i++) 
	dx[i] = (xp[i] - x2[i]) / dt;
      /* store speed */
      for (i = 0; i <= 2; i++) {
	xp[i+3] = dx[i];
      }
    }
    if (xpret != NULL)
      for (i = 0; i <= 5; i++)
	xpret[i] = xp[i];
  }
  return(OK);
}
Ejemplo n.º 4
0
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;
        }
Ejemplo n.º 5
0
/* 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;
}