Ejemplo n.º 1
0
static float
kepler(const float ecc, float mean_anom)
{
	float curr, err, thresh;
	int is_negative = 0, n_iter = 0;

	if( !mean_anom) {
		return( 0.);
	}

	if( ecc < .3) {   /* low-eccentricity formula from Meeus,  p. 195 */
		curr = atan2f( sinf( mean_anom), cosf( mean_anom) - ecc);
			/* one correction step,  and we're done */
		err = curr - ecc * sinf( curr) - mean_anom;
		curr -= err / (1. - ecc * cosf( curr));
	} else {
	    curr = mean_anom;
	}

	if( mean_anom < 0.) {
		mean_anom = -mean_anom;
		curr = - curr;
		is_negative = 1;
	}

	thresh = THRESH * fabsf( 1. - ecc);
	if( ecc > .8 && mean_anom < PI / 3. || ecc > 1.)    /* up to 60 degrees */ {
		float trial = mean_anom / fabsf( 1. - ecc);

		if( trial * trial > 6. * fabsf(1. - ecc))   /* cubic term is dominant */ {
			if( mean_anom < PI) {
				trial = CUBE_ROOT( 6. * mean_anom);
			} else {      /* hyperbolic w/ 5th & higher-order terms predominant */
				trial = asinhf( mean_anom / ecc);
			}
		}
		curr = trial;
	}

	if( ecc < 1.) {
		err = curr - ecc * sinf( curr) - mean_anom;
		while( fabsf( err) > thresh) {
			n_iter++;
			curr -= err / (1. - ecc * cosf( curr));
			err = curr - ecc * sinf( curr) - mean_anom;
		}
	} else {
		err = ecc * sinhf( curr) - curr - mean_anom;
		while( fabsf( err) > thresh) {
			n_iter++;
			curr -= err / (ecc * coshf( curr) - 1.);
			err = ecc * sinhf( curr) - curr - mean_anom;
		}
	}
	return( is_negative ? -curr : curr);
}
Ejemplo n.º 2
0
void comet_posn_part_ii( const ELEMENTS DLLPTR *elem, const double t,
                                    double DLLPTR *loc, double DLLPTR *vel)
{
   double true_anom, r, x, y, r0;

   if( elem->ecc == 1.)    /* parabolic */
      {
      double g = elem->w0 * t * .5;

      y = CUBE_ROOT( g + sqrt( g * g + 1.));
      true_anom = 2. * atan( y - 1. / y);
      }
   else           /* got the mean anomaly;  compute eccentric,  then true */
      {
      double ecc_anom;

      ecc_anom = kepler( elem->ecc, elem->mean_anomaly);
      if( elem->ecc > 1.)     /* hyperbolic case */
         {
         x = (elem->ecc - cosh( ecc_anom));
         y = sinh( ecc_anom);
         }
      else           /* elliptical case */
         {
         x = (cos( ecc_anom) - elem->ecc);
         y =  sin( ecc_anom);
         }
      y *= elem->minor_to_major;
      true_anom = atan2( y, x);
      }

   r0 = elem->q * (1. + elem->ecc);
   r = r0 / (1. + elem->ecc * cos( true_anom));
   x = r * cos( true_anom);
   y = r * sin( true_anom);
   loc[0] = elem->perih_vec[0] * x + elem->sideways[0] * y;
   loc[1] = elem->perih_vec[1] * x + elem->sideways[1] * y;
   loc[2] = elem->perih_vec[2] * x + elem->sideways[2] * y;
   loc[3] = r;
   if( vel && (elem->angular_momentum != 0.))
      {
      double angular_component = elem->angular_momentum / (r * r);
      double radial_component = elem->ecc * sin( true_anom) *
                                elem->angular_momentum / (r * r0);
      double x1 = x * radial_component - y * angular_component;
      double y1 = y * radial_component + x * angular_component;
      unsigned i;

      for( i = 0; i < 3; i++)
         vel[i] = elem->perih_vec[i] * x1 + elem->sideways[i] * y1;
      }
}
Ejemplo n.º 3
0
static double kepler( const double ecc, double mean_anom)
{
   double curr, err, thresh, offset = 0., delta_curr = 1.;
   int is_negative = 0, n_iter = 0;

   if( !mean_anom)
      return( 0.);

   if( ecc < .3)     /* low-eccentricity formula from Meeus,  p. 195 */
      {
      curr = atan2( sin( mean_anom), cos( mean_anom) - ecc);
            /* two correction steps,  and we're done */
      for( n_iter = 2; n_iter; n_iter--)
         {
         err = curr - ecc * sin( curr) - mean_anom;
         curr -= err / (1. - ecc * cos( curr));
         }
      return( curr);
      }

   if( ecc < 1.)
      if( mean_anom < -PI || mean_anom > PI)
         {
         double tmod = fmod( mean_anom, PI * 2.);

         if( tmod > PI)             /* bring mean anom within -pi to +pi */
            tmod -= 2. * PI;
         else if( tmod < -PI)
            tmod += 2. * PI;
         offset = mean_anom - tmod;
         mean_anom = tmod;
         }

   if( mean_anom < 0.)
      {
      mean_anom = -mean_anom;
      is_negative = 1;
      }

   curr = mean_anom;
   thresh = THRESH * fabs( 1. - ecc);
   if( thresh < 1e-15)
      thresh = 1e-15;
   if( ecc > .8 && mean_anom < PI / 3. || ecc > 1.)    /* up to 60 degrees */
      {
      double trial = mean_anom / fabs( 1. - ecc);

      if( trial * trial > 6. * fabs(1. - ecc))   /* cubic term is dominant */
         {
         if( mean_anom < PI)
            trial = CUBE_ROOT( 6. * mean_anom);
         else        /* hyperbolic w/ 5th & higher-order terms predominant */
            trial = asinh( mean_anom / ecc);
         }
      curr = trial;
      }
   if( ecc > 1. && mean_anom > 4.)    /* hyperbolic, large-mean-anomaly case */
      curr = log( mean_anom);

   if( ecc < 1.)
      while( fabs( delta_curr) > thresh)
         {
         if( n_iter++ > MAX_ITERATIONS)
            err = near_parabolic( curr, ecc) - mean_anom;
         else
            err = curr - ecc * sin( curr) - mean_anom;
         delta_curr = -err / (1. - ecc * cos( curr));
         curr += delta_curr;
         printf( "Iter %d: %.16lf %.16lf %.16lf\n",
                           n_iter, curr, err, delta_curr);
         }
   else
      while( fabs( delta_curr) > thresh)
         {
         if( n_iter++ > MAX_ITERATIONS)
            err = -near_parabolic( curr, ecc) - mean_anom;
         else
            err = ecc * sinh( curr) - curr - mean_anom;
         delta_curr = -err / (ecc * cosh( curr) - 1.);
         curr += delta_curr;
         printf( "Iter %d: %.16lf %.16lf %.16lf\n",
                           n_iter, curr, err, delta_curr);
         }
   return( is_negative ? offset - curr : offset + curr);
}
Ejemplo n.º 4
0
double kepler(double ecc, double mean_anom)
{
  double curr, err, thresh;
  int is_negative = 0, n_iter = 0;

  if (!mean_anom)
    return (0.);

  if (ecc < .3) /* low-eccentricity formula from Meeus,  p. 195 */
  {
    curr = atan2(sin(mean_anom), cos(mean_anom) - ecc);
    /* one correction step,  and we're done */
    err = curr - ecc * sin(curr) - mean_anom;
    curr -= err / (1. - ecc * cos(curr));
    return (curr);
  }

  if (mean_anom < 0.)
  {
    mean_anom = -mean_anom;
    is_negative = 1;
  }

  curr = mean_anom;
  thresh = THRESH * fabs(1. - ecc);
  if (ecc > .8 && mean_anom < M_PI / 3. || ecc > 1.) /* up to 60 degrees */
  {
    double trial = mean_anom / fabs(1. - ecc);

    if (trial * trial > 6. * fabs(1. - ecc)) /* cubic term is dominant */
    {
      if (mean_anom < M_PI)
        trial = CUBE_ROOT(6. * mean_anom);
      else /* hyperbolic w/ 5th & higher-order terms predominant */
        trial = asinh(mean_anom / ecc);
    }
    curr = trial;
  }

  if (ecc < 1.)
  {
    err = curr - ecc * sin(curr) - mean_anom;
    while (fabs(err) > thresh)
    {
      n_iter++;
      curr -= err / (1. - ecc * cos(curr));
      err = curr - ecc * sin(curr) - mean_anom;
    }
  }
  else
  {
    err = ecc * sinh(curr) - curr - mean_anom;
    while (fabs(err) > thresh)
    {
      n_iter++;
      curr -= err / (ecc * cosh(curr) - 1.);
      err = ecc * sinh(curr) - curr - mean_anom;
    }
  }
  return (is_negative ? -curr : curr);
}
Ejemplo n.º 5
0
static double kepler( const double ecc, double mean_anom)
{
   double curr, err, thresh, offset = 0.;
   double delta_curr = 1.;
   bool is_negative = false;
   unsigned n_iter = 0;

   if( !mean_anom)
      return( 0.);

   if( ecc < 1.)
      {
      if( mean_anom < -PI || mean_anom > PI)
         {
         double tmod = fmod( mean_anom, PI * 2.);

         if( tmod > PI)             /* bring mean anom within -pi to +pi */
            tmod -= 2. * PI;
         else if( tmod < -PI)
            tmod += 2. * PI;
         offset = mean_anom - tmod;
         mean_anom = tmod;
         }

      if( ecc < .9)     /* low-eccentricity formula from Meeus,  p. 195 */
         {
         curr = atan2( sin( mean_anom), cos( mean_anom) - ecc);
         do
            {
            err = (curr - ecc * sin( curr) - mean_anom) / (1. - ecc * cos( curr));
            curr -= err;
            }
            while( fabs( err) > THRESH);
         return( curr + offset);
         }
      }


   if( mean_anom < 0.)
      {
      mean_anom = -mean_anom;
      is_negative = true;
      }

   curr = mean_anom;
   thresh = THRESH * fabs( 1. - ecc);
               /* Due to roundoff error,  there's no way we can hope to */
               /* get below a certain minimum threshhold anyway:        */
   if( thresh < MIN_THRESH)
      thresh = MIN_THRESH;
   if( (ecc > .8 && mean_anom < PI / 3.) || ecc > 1.)    /* up to 60 degrees */
      {
      double trial = mean_anom / fabs( 1. - ecc);

      if( trial * trial > 6. * fabs(1. - ecc))   /* cubic term is dominant */
         {
         if( mean_anom < PI)
            trial = CUBE_ROOT( 6. * mean_anom);
         else        /* hyperbolic w/ 5th & higher-order terms predominant */
            trial = asinh( mean_anom / ecc);
         }
      curr = trial;
      if( thresh > THRESH)       /* happens if e > 2. */
         thresh = THRESH;
      }

   if( ecc < 1.)
      while( fabs( delta_curr) > thresh)
         {
         if( n_iter++ > MAX_ITERATIONS)
            err = near_parabolic( curr, ecc) - mean_anom;
         else
            err = curr - ecc * sin( curr) - mean_anom;
         delta_curr = -err / (1. - ecc * cos( curr));
         curr += delta_curr;
         }
   else
      while( fabs( delta_curr) > thresh)
         {
         if( n_iter++ > MAX_ITERATIONS)
            err = -near_parabolic( curr, ecc) - mean_anom;
         else
            err = ecc * sinh( curr) - curr - mean_anom;
         delta_curr = -err / (ecc * cosh( curr) - 1.);
         curr += delta_curr;
         }
   return( is_negative ? offset - curr : offset + curr);
}