/* ----------------------------------------------------------------------------- * * function newtonnu * * this function solves keplers equation when the true anomaly is known. * the mean and eccentric, parabolic, or hyperbolic anomaly is also found. * the parabolic limit at 168ΓΈ is arbitrary. the hyperbolic anomaly is also * limited. the hyperbolic sine is used because it's not double valued. * * author : david vallado 719-573-2600 27 may 2002 * * revisions * vallado - fix small 24 sep 2002 * * inputs description range / units * ecc - eccentricity 0.0 to * nu - true anomaly -2pi to 2pi rad * * outputs : * e0 - eccentric anomaly 0.0 to 2pi rad 153.02 deg * m - mean anomaly 0.0 to 2pi rad 151.7425 deg * * locals : * e1 - eccentric anomaly, next value rad * sine - sine of e * cose - cosine of e * ktr - index * * coupling : * arcsinh - arc hyperbolic sine * sinh - hyperbolic sine * * references : * vallado 2013, 77, alg 5 * --------------------------------------------------------------------------- */ private static void NewtonNu(OrbitElements oe) { double small, sine, cose, cosnu, temp; double ecc = oe.ecc; double nu = oe.nu; double e0, m; // --------------------- implementation --------------------- e0 = 999999.9; m = 999999.9; small = 0.00000001; // --------------------------- circular ------------------------ if (Mathd.Abs(ecc) < small) { m = nu; e0 = nu; } else // ---------------------- elliptical ----------------------- if (ecc < 1.0 - small) { cosnu = Mathd.Cos(nu); temp = 1.0 / (1.0 + ecc * cosnu); sine = (Mathd.Sqrt(1.0 - ecc * ecc) * Mathd.Sin(nu)) * temp; cose = (ecc + cosnu) * temp; e0 = Mathd.Atan2(sine, cose); m = e0 - ecc * Mathd.Sin(e0); } else // -------------------- hyperbolic -------------------- if (ecc > 1.0 + small) { if ((ecc > 1.0) && (Mathd.Abs(nu) + 0.00001 < Mathd.PI - Mathd.Acos(Mathd.Clamp(1.0 / ecc, -1.0, 1.0)))) { sine = (Mathd.Sqrt(ecc * ecc - 1.0) * Mathd.Sin(nu)) / (1.0 + ecc * Mathd.Cos(nu)); e0 = GEMath.Asinh(sine); m = ecc * GEMath.Sinh(e0) - e0; } } else // ----------------- parabolic --------------------- if (Mathd.Acos(Mathd.Clamp(nu, -1.0, 1.0)) < 168.0 * Mathd.PI / 180.0) { e0 = Mathd.Tan(nu * 0.5); m = e0 + (e0 * e0 * e0) / 3.0; } if (ecc < 1.0) { m = System.Math.Truncate(m / (2.0 * Mathd.PI)); if (m < 0.0) { m = m + 2.0 * Mathd.PI; } e0 = System.Math.Truncate(e0 / (2.0 * Mathd.PI)); } oe.m = m; oe.eccanom = e0; } // newtonnu