Example #1
0
    /* -----------------------------------------------------------------------------
    *
    *                           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