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); }
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; } }
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); }
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); }
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); }