/// <summary>
        /// <see cref="UnityEngine.Debug.Log(object)"/> the OrbitData.
        /// </summary>
        /// <param name="inDegrees">If set to <c>true</c>, logs the angles in degrees; default (false) in radians.</param>
        public void Log(bool inDegrees = false)
        {
            double _i  = i;
            double _Om = Om;
            double _w  = w;
            double _M  = M;
            double _nu = nu;
            double _E  = E;

            if (inDegrees)
            {
                _i  *= OrbitUtils.Rad2Deg;
                _Om *= OrbitUtils.Rad2Deg;
                _w  *= OrbitUtils.Rad2Deg;
                _M  *= OrbitUtils.Rad2Deg;
                _nu *= OrbitUtils.Rad2Deg;
                _E  *= OrbitUtils.Rad2Deg;
            }

            Debug.LogFormat("EPOCH {0:F5}, Date {1}", epoch, OrbitUtils.JDN2CalendarString(epoch));
            Debug.LogFormat(" A = {0:E5}, EC = {1:E5}", a, ecc);
            Debug.LogFormat("IN = {0:E5}, OM = {1:E5}, W = {2:E5}", _i, _Om, _w);
            Debug.LogFormat("MA = {0:E5}, TA = {1:E5}, E = {2:E5}", _M, _nu, _E);
            Debug.LogFormat("r = ({0:E15}, {1:E15}, {2:E15}), v = ({3:E15}, {4:E5}, {5:E5})",
                            pos.x, pos.y, pos.z, vel.x, vel.y, vel.z);
        }
        static Vector3 GetVertexOfOrbitEllipse(double a, double ecc, double nu, double[,] T)
        {
            double E  = OrbitUtils.TrueAnom2EccentricAnom(nu, ecc);
            double rx = a * (Math.Cos(E) - ecc);
            double ry = a * Math.Sqrt(1 - ecc * ecc) * Math.Sin(E);

            return((Vector3)OrbitUtils.ApplyTransform(rx, ry, T));
        }
        /// <summary>
        /// Updates the position and velocity of the body in its orbit based on
        /// the current anomaly. Reference plane is the ecliptic plane (J2000).
        /// </summary>
        void UpdatePositionAndVelocity()
        {
            // Heliocentric coordinates in its orbital plane r'.
            double rx = a * (Math.Cos(E) - ecc);
            double ry = a * Math.Sqrt(1 - ecc * ecc) * Math.Sin(E);

            // Heliocentric velocity in its orbital plane v'.
            double cosE = Math.Cos(E);
            double r    = a * (1 - ecc * cosE);
            double k    = Math.Sqrt(mu * a) / r;
            double vx   = k * -Math.Sin(E);
            double vy   = k * Math.Sqrt(1 - ecc * ecc) * cosE;

            double[,] T = OrbitUtils.GetTransformToEcliptic(i, Om, w);
            pos         = OrbitUtils.ApplyTransform(rx, ry, T);
            vel         = OrbitUtils.ApplyTransform(vx, vy, T);
        }
        /// <summary>
        /// Steps the orbit by <paramref name="deltaTime"/>.
        /// Recalculates the anomalies for the new deltaTime, then updates the
        /// position and velocity at the new anomalies.
        /// </summary>
        /// <param name="deltaTime">Delta time [days].</param>
        public void Step(double deltaTime)
        {
            // Recalculate anomalies M, E, ν (nu) for time t = t0 + deltaTime.
            //M = M + (deltaTime * OrbitUtils.DAY2SEC) * Math.Sqrt(mu / (a * a * a));
            M = M + (deltaTime * OrbitUtils.DAY2SEC) * N;
            M = OrbitUtils.NormalizeAngle(M, 0.0, OrbitUtils.TwoPI);

            E = OrbitUtils.SolveKeplerEqForEccentricAnom(ecc, M, 1e-10, 20);

            nu = 2 * Math.Atan2(Math.Sqrt(1 + ecc) * Math.Sin(E / 2),
                                Math.Sqrt(1 - ecc) * Math.Cos(E / 2));

            // Calculate the position and velocity for the new epoch.
            UpdateStateFromElems();

            // Update epoch to reflect the timestep.
            epoch = epoch + deltaTime;
        }
        /// <summary>
        /// Returns the a position
        /// </summary>
        /// <returns>The to ecliptic.</returns>
        /// <param name="MA">The mean anomaly [rad].</param>
        public Vector3d GetPositionFromMeanAnom(double MA)
        {
            double EA = OrbitUtils.MeanAnom2EccentricAnom(ecc, MA);
            double xv = a * (Math.Cos(EA) - ecc);
            double yv = a * Math.Sqrt(1.0 - ecc * ecc) * Math.Sin(EA);

            double v = Math.Atan2(yv, xv);           // True anomaly, nu
            double r = Math.Sqrt(xv * xv + yv * yv); // Radius

            // Precalculate and store trig terms
            double sinOm  = Math.Sin(Om);
            double cosOm  = Math.Cos(Om);
            double sinNuW = Math.Sin(nu + w);
            double cosNuW = Math.Cos(nu + w);
            double cosI   = Math.Cos(i);

            double xh = cosOm * cosNuW - sinOm * sinNuW * cosI;
            double yh = sinOm * cosNuW + cosOm * sinNuW * cosI;
            double zh = sinNuW * Math.Sin(i);

            return(new Vector3d(r * xh, r * yh, r * zh));
        }
        /// <summary>
        /// Gets the points on orbit ellipse.
        /// </summary>
        /// <param name="vertices">Reference array storing the vertices of the ellipse.</param>
        /// <param name="resolution">Number of vertices to draw ellipse.</param>
        public void GetEllipseFromTrueAnom(ref Vector3[] vertices, int resolution)
        {
            if (resolution < 2)
            {
                vertices = new Vector3[0];
                return;
            }

            //if (ecc < 1 && ecc >= 0)
            if (vertices == null || vertices.Length != resolution)
            {
                vertices = new Vector3[resolution];
            }

            // Resolution as the angular distance (nu) between each vertex.
            double nuResolution = OrbitUtils.TwoPI / resolution;

            double[,] T = OrbitUtils.GetTransformToEcliptic(i, Om, w);
            for (int i = 0; i < resolution; i++)
            {
                vertices[i] = GetVertexOfOrbitEllipse(a, ecc, i * nuResolution, T);
            }
        }