void main( int argc, char **argv) { double ecc = atof( argv[1]); double mean_anom = atof( argv[2]); printf( "E=%lf\n", kepler( ecc, mean_anom)); }
void OrbitToXYZ( const OrbitData& orbit, long when, float* x, float* y, float* z ) { float true_anomaly; float inclination = orbit.OrbitalInclination(when) * deg2rad; float ascnode = orbit.LongitudeOfAscendingNode(when) * deg2rad; float peri = orbit.ArgumentOfPeriapsis(when) * deg2rad; float mean_anomaly = orbit.MeanAnomaly(when) * deg2rad; float semimajor = orbit.SemiMajorAxis(when); float eccentricity = orbit.Eccentricity(when); mean_anomaly = NormalizeRadians(mean_anomaly); float eccentric_anomaly = kepler(eccentricity, mean_anomaly); eccentric_anomaly = NormalizeRadians(eccentric_anomaly); true_anomaly = 2*atan2f(sqrtf((1+eccentricity)/(1-eccentricity)),1.0/tanf(eccentric_anomaly*0.5)); float radius_orbit = semimajor * (1 - eccentricity * eccentricity) / (1 + eccentricity * cosf(true_anomaly)); *x = radius_orbit * (cosf(ascnode) * cosf(peri+true_anomaly) - sinf(ascnode) * cosf(inclination) * sinf(peri+true_anomaly)); *y = radius_orbit * (sinf(ascnode) * cosf(peri+true_anomaly) + cosf(ascnode) * cosf(inclination) * sinf(peri+true_anomaly)); *z = radius_orbit * sinf(inclination) * sinf(peri+true_anomaly); }
void main(void) { int i; double p, pi, fpi, fppi; printf("n,x,y\n"); // Iterate through N steps for (i = 0; i < N; i++) { double x = X0 + STEP_SIZE * i; pi = x; while(1) { fpi = kepler(x, pi); fppi = keplerPrime(pi); p = pi - (fpi/fppi); if (abs(p - pi) < TOL && abs(fpi) < TOL) break; pi = p; } printf("%d,%.8f,%.8f\n", i, x, p); } }
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; } }
void sunpos(double jd, int apparent, double *ra, double *dec, double *rv, double* slong) { double t, t2, t3, l, m, e, ea, v, theta, omega, eps; // Time, in Julian centuries of 36525 ephemeris days, // measured from the epoch 1900 January 0.5 ET. t = (jd - 2415020.0) / 36525.0; t2 = t * t; t3 = t2 * t; // Geometric mean longitude of the Sun, referred to the // mean equinox of the date. l = fixangle(279.69668 + 36000.76892 * t + 0.0003025 * t2); // Sun's mean anomaly. m = fixangle(358.47583 + 35999.04975*t - 0.000150*t2 - 0.0000033*t3); // Eccentricity of the Earth's orbit. e = 0.01675104 - 0.0000418 * t - 0.000000126 * t2; // Eccentric anomaly. ea = kepler(m, e); // True anomaly v = fixangle(2 * rtd(atan(sqrt((1 + e) / (1 - e)) * tan(ea / 2)))); // Sun's true longitude. theta = l + v - m; // Obliquity of the ecliptic. eps = 23.452294 - 0.0130125 * t - 0.00000164 * t2 + 0.000000503 * t3; // Corrections for Sun's apparent longitude, if desired. if (apparent) { omega = fixangle(259.18 - 1934.142 * t); theta = theta - 0.00569 - 0.00479 * sin(dtr(omega)); eps += 0.00256 * cos(dtr(omega)); } // Return Sun's longitude and radius vector *slong = theta; *rv = (1.0000002 * (1 - e * e)) / (1 + e * cos(dtr(v))); // Determine solar co-ordinates. *ra = fixangle(rtd(atan2(cos(dtr(eps)) * sin(dtr(theta)), cos(dtr(theta))))); *dec = rtd(asin(sin(dtr(eps)) * sin(dtr(theta)))); }
static double phase( double pdate, double *pphase, /* Illuminated fraction */ double *mage, /* Age of moon in days */ double *dist, /* Distance in kilometres */ double *angdia, /* Angular diameter in degrees */ double *sudist, /* Distance to Sun */ double *suangdia ) /* Sun's angular diameter */ { double Day, N, M, Ec, Lambdasun, ml, MM, MN, Ev, Ae, A3, MmP, mEc, A4, lP, V, lPP, NP, y, x, Lambdamoon, MoonAge, MoonPhase, MoonDist, MoonDFrac, MoonAng, F, SunDist, SunAng; /* Calculation of the Sun's position */ Day = pdate - epoch; /* Date within epoch */ N = fixangle((360.0 / 365.2422) * Day); /* Mean anomaly of the Sun */ M = fixangle(N + elonge - elongp); /* Convert from perigee co-ordinates to epoch 1980.0 */ Ec = kepler(M, eccent); /* Solve equation of Kepler */ Ec = sqrt((1.0 + eccent) / (1.0 - eccent)) * tan(Ec / 2.0); Ec = 2.0 * todeg(atan(Ec)); /* True anomaly */ Lambdasun = fixangle(Ec + elongp); /* Sun's geocentric ecliptic longitude */ /* Orbital distance factor */ F = ((1.0 + eccent * cos(torad(Ec))) / (1.0 - eccent * eccent)); SunDist = sunsmax / F; /* Distance to Sun in km */ SunAng = F * sunangsiz; /* Sun's angular size in degrees */ /* Calculation of the Moon's position */ /* Moon's mean longitude */ ml = fixangle(13.1763966 * Day + mmlong); /* Moon's mean anomaly */ MM = fixangle(ml - 0.1114041 * Day - mmlongp); /* Moon's ascending node mean longitude */ MN = fixangle(mlnode - 0.0529539 * Day); /* Evection */ Ev = 1.2739 * sin(torad(2.0 * (ml - Lambdasun) - MM)); /* Annual equation */ Ae = 0.1858 * sin(torad(M)); /* Correction term */ A3 = 0.37 * sin(torad(M)); /* Corrected anomaly */ MmP = MM + Ev - Ae - A3; /* Correction for the equation of the centre */ mEc = 6.2886 * sin(torad(MmP)); /* Another correction term */ A4 = 0.214 * sin(torad(2.0 * MmP)); /* Corrected longitude */ lP = ml + Ev + mEc - Ae + A4; /* Variation */ V = 0.6583 * sin(torad(2.0 * (lP - Lambdasun))); /* True longitude */ lPP = lP + V; /* Corrected longitude of the node */ NP = MN - 0.16 * sin(torad(M)); /* Y inclination coordinate */ y = sin(torad(lPP - NP)) * cos(torad(minc)); /* X inclination coordinate */ x = cos(torad(lPP - NP)); /* Ecliptic longitude */ Lambdamoon = todeg(atan2(y, x)); Lambdamoon += NP; #if 0 /* Ecliptic latitude */ (void)todeg(asin(sin(torad(lPP - NP)) * sin(torad(minc)))); #endif /* Calculation of the phase of the Moon */ /* Age of the Moon in degrees */ MoonAge = lPP - Lambdasun; /* Phase of the Moon */ MoonPhase = (1.0 - cos(torad(MoonAge))) / 2.0; /* Calculate distance of moon from the centre of the Earth */ MoonDist = (msmax * (1.0 - mecc * mecc)) / (1.0 + mecc * cos(torad(MmP + mEc))); /* Calculate Moon's angular diameter */ MoonDFrac = MoonDist / msmax; MoonAng = mangsiz / MoonDFrac; #if 0 /* Calculate Moon's parallax */ MoonPar = mparallax / MoonDFrac; #endif *pphase = MoonPhase; *mage = synmonth * (fixangle(MoonAge) / 360.0); *dist = MoonDist; *angdia = MoonAng; *sudist = SunDist; *suangdia = SunAng; return fixangle(MoonAge) / 360.0; }
/* * Calculate Kepler position and velocity for given timestep _dt_ * for particle no. _pos_. * _xp_ and _vp_ will be updated. */ void step_kepler_1(struct particle parts[], int pcount, int pos, double dt, double *out_a, double *out_a_, double *out_a_2, double *out_a_3, double *curr_a, double *curr_e) { _enter_function(_UL_KEPLER, _UL_KEPLER_STEP_KEPLER_1); int i; struct particle *p0 = parts, *p1 = parts + pos; double r_[3], v_[3], j_[3], ecc_[3], a_[3], b_[3], _1_r2, afact, v_r_, v_v_, r_a_, v_a_, r_a__; double ecc, a, r, v, b, omega, e, mean, cosp, sinp; double m_c=p0->m, _cosp_ecc, e2, _1_ecc, _cosp_1, de_dt;//+p1->m; // get relative position / motion for(i = 0; i < 3; i++) { r_[i] = p1->xp[i] - p0->xp[i]; v_[i] = p1->vp[i] - p0->vp[i]; } // calculate ellipse constants get_constants(r_, v_, m_c, j_, ecc_, &a, &omega); //printf("# [%d]:\t%e\t%e\t%e\n", pos, v_abs(ecc_), a, omega); ecc = v_abs(ecc_); // b_ = a * sqrt(|1-e²|) * (j_ x e_) / |j_ x e_| vec_prod(j_, ecc_, b_); b = a * sqrt(fabs(1-ecc*ecc)) / v_abs(b_); for(i = 0; i < 3; i++) { a_[i] = a*ecc_[i]/ecc; // semi major vector b_[i] *= b; // semi minor vector } if(curr_a != NULL) *curr_a = a; if(curr_e != NULL) *curr_e = ecc; if(ecc < 1) // elliptical orbit { if(!p1->is_elliptical) { fprintf(get_file(FILE_WARNING), "#### [t=%1.12e] Particle #%d captured onto elliptical orbit with e=%e ####\n", t_total(p1->t), pos, ecc); p1->is_elliptical = 1; } // calculate eccentric anomaly e at t+dt e = (a - v_abs(r_)) / (ecc * a); if(e >= 1.0) e = .0; else if(e <= -1.0) e = M_PI; else e = acos(e); if(scal_prod(r_, b_) < 0) e = 2*M_PI - e; mean = (e - ecc*sin(e)) + dt * omega; while(mean >= 2. * M_PI) mean -= 2. * M_PI; e = solve_kepler(mean, ecc); cosp = cos(e); sinp = sin(e); _cosp_ecc = cosp - ecc; de_dt = omega / (1. - ecc * cosp); if(ecc > .99) { e2 = (e > 2. * M_PI - 1e-3) ? e - 2. * M_PI : e; if(e2 < 1e-3) { e2 *= e2; _1_ecc = scal_prod(j_, j_)/(p0->m*a*(1+ecc)); _cosp_1 = - .5 * e2 * (1 - e2 / 12. * (1 - e2 / 30.)); _cosp_ecc = _1_ecc + _cosp_1; de_dt = omega / (_1_ecc - ecc * _cosp_1); } } for(i = 0; i < DIMENSIONS; i++) { r_[i] = a_[i] * _cosp_ecc + b_[i] * sinp ; // new location v_[i] = (-a_[i] * sinp + b_[i] * cosp) * de_dt; // direction of v only } } else // hyperbolic orbit // parabolic? { if(p1->is_elliptical) { fprintf(get_file(FILE_WARNING), "#### [t=%1.12e+%1.12e] Particle #%d thrown onto hyperbolic orbit with e=%e (E=%e, a=%e) ####\n", t_total(p1->t), convert_time(dt, 0), pos, ecc, p1->energy, convert_length(a, 0)); p1->is_elliptical = 0; } if(ecc == 1) fprintf(get_file(FILE_WARNING), "# # # %e\tParabolic orbit of m%d treated as hyperbolic: e=%e\t(x=%e)\n", t_total(p1->t), pos, ecc, convert_length(v_abs(p1->xp), 0)); // calculate eccentric anomaly e at t+dt e = (a + v_abs(r_)) / (ecc * a); if(e < 1.0) e = .0; else if(scal_prod(r_, v_) < 0) e = -acosh(e); else e = acosh(e); e = kepler(ecc, ecc * sinh(e) - e + dt * omega); cosp = cosh(e); sinp = sinh(e); de_dt = omega / (ecc * cosp - 1.); for(i = 0; i < DIMENSIONS; i++) { r_[i] = a_[i] * (ecc - cosp) + b_[i] * sinp; // new location v_[i] = (-a_[i] * sinp + b_[i] * cosp) * de_dt; // direction of v only } } // get |v_| from j_ = r_ x v_ v = v_abs(v_); r = v_abs(r_); v = v_abs(j_) / (r * v * sin(acos(scal_prod(r_, v_)/ (r * v)))); for(i = 0; i < DIMENSIONS; i++) { //v_[i] *= v; // total motion relative to fix central mass p1->xp[i] = p0->xp[i] + r_[i]; p1->vp[i] = p0->vp[i] + v_[i]; } if(out_a != NULL) { _1_r2 = 1. / scal_prod(r_, r_); afact = - m_c * _1_r2 * sqrt(_1_r2); //printf("4 %e %e %e\n", *(out_a), *(out_a+1), *(out_a+2)); for(i = 0; i < DIMENSIONS; i++) out_a[i] = afact * r_[i]; if(out_a_ != NULL) { v_r_ = scal_prod(v_, r_); for(i = 0; i < DIMENSIONS; i++) out_a_[i] = afact * (v_[i] - 3 * _1_r2 * v_r_ * r_[i]); if(out_a_2 != NULL) { v_v_ = scal_prod(v_, v_); r_a_ = scal_prod(r_, out_a); for(i = 0; i < DIMENSIONS; i++) out_a_2[i] = afact * (out_a[i] - 3. * _1_r2 * (v_r_ * (2. * v_[i] - 5. * v_r_ * r_[i] * _1_r2) + (v_v_ + r_a_) * r_[i])); if(out_a_3 != NULL) { v_a_ = scal_prod(v_, out_a); r_a__ = scal_prod(r_, out_a_); for(i = 0; i < DIMENSIONS; i++) out_a_3[i] = afact * (out_a_[i] - 3. * _1_r2 * (3. * v_r_ * out_a[i] + 3. * (v_v_ + r_a_) * (v_[i] - 5. * v_r_ * _1_r2 * r_[i]) + (3. * v_a_ + r_a__) * r_[i] + v_r_ * v_r_ * _1_r2 * (-15. * v_[i] + 35. * v_r_ * _1_r2 * r_[i]))); } } } } _exit_function(); }