public LambertBattin(OrbitData _fromOrbit, OrbitData _toOrbit) : base(_fromOrbit, _toOrbit)
    {
        name = "LambertBattin";
        // Fundamentals of Astrodynamics and Applications, Vallado, 4th Ed., Algorithm 56 p475
        // Take r0, r => a_min, e_min, t_min, v0

        GravityEngine ge = GravityEngine.Instance();

        // If Nbody is available get position directly. If not (target marker) then
        // use orbit phase to compute position

        center3d = ge.GetPositionDoubleV3(_fromOrbit.centralMass);

        if (fromOrbit.nbody != null)
        {
            r1        = ge.GetPositionDoubleV3(fromOrbit.nbody);
            r1crossv1 = _fromOrbit.GetAxis();
        }
        else
        {
            r1 = new Vector3d(toOrbit.GetPhysicsPositionforEllipse(fromOrbit.phase));
            Debug.LogError("Code incomplete need to get v1");
        }

        if (toOrbit.nbody != null)
        {
            r2 = ge.GetPositionDoubleV3(toOrbit.nbody);
        }
        else
        {
            r2 = new Vector3d(toOrbit.GetPhysicsPositionforEllipse(toOrbit.phase));
        }

        r1 = r1 - center3d;
        r2 = r2 - center3d;

        if (fromOrbit.a < toOrbit.a)
        {
            innerOrbit   = fromOrbit;
            outerOrbit   = toOrbit;
            innerToOuter = true;
        }
        else
        {
            innerOrbit   = toOrbit;
            outerOrbit   = fromOrbit;
            innerToOuter = false;
        }
        fromNBody = fromOrbit.nbody;
        mu        = ge.GetPhysicsMass(fromOrbit.centralMass);
    }
    public LambertBattin(NBody fromBody, NBody centerNBody, Vector3d r_from, Vector3d r_to, Vector3d fromAxis) : base()
    {
        name = "LambertBattin";

        fromNBody = fromBody;
        GravityEngine ge = GravityEngine.Instance();

        centerBody = centerNBody;

        center3d = ge.GetPositionDoubleV3(centerNBody);
        mu       = ge.GetPhysicsMass(centerNBody);

        r1        = r_from - center3d;
        r1crossv1 = fromAxis;
        r2        = r_to - center3d;

        innerOrbit   = fromOrbit;
        innerToOuter = true;
    }
    /// <summary>
    /// Create a Lambert transfer from a given NBody orbit to a position in physics space.
    ///
    /// The constructor will compute the minimum energy transfer to the point taking the shortest
    /// path setting into account. The time for the transfer can then be retreived.
    /// </summary>
    /// <param name="_fromOrbit"></param>
    /// <param name="r_from"></param>
    /// <param name="r_to"></param>
    /// <param name="shortPath"></param>
    public LambertUniversal(OrbitData _fromOrbit, Vector3d r_from, Vector3d r_to, bool shortPath) : base(_fromOrbit)
    {
        name = "LambertUniversal";

        GravityEngine ge = GravityEngine.Instance();

        center3d = ge.GetPositionDoubleV3(centerBody);
        r1       = r_from - center3d;
        r2       = r_to - center3d;

        fromOrbit    = _fromOrbit;
        innerOrbit   = fromOrbit;
        innerToOuter = true;
        mu           = ge.GetPhysicsMass(fromOrbit.centralMass);
        // determine t_min.
        double[] r0 = new double[] { r1.x, r1.y, r1.z };
        double[] r  = new double[] { r2.x, r2.y, r2.z };
        ComputeMinTime(ref r0, ref r, _fromOrbit.centralMass, shortPath);
    }
    /// <summary>
    /// Setup for Lambert Universal construction. Calculation is done via ComputeXfer and may be
    /// done more than once for different transit times.
    ///
    /// Initial conditions are passed in when created.
    ///
    /// The transfer assumes there is an active NBody at the fromOrbit to be maneuvered to the
    /// orbit specified by the toOrbit. One of the from/to orbit data elements must have a
    /// centerNBody.
    ///
    /// </summary>
    /// <param name="fromOrbit"></param>
    /// <param name="toOrbit"></param>
    /// <param name="shortPath">Take shortest path along the ellipse (if xfer is an ellipse)</param>

    public LambertUniversal(OrbitData _fromOrbit, OrbitData _toOrbit, bool shortPath) : base(_fromOrbit, _toOrbit)
    {
        name = "LambertUniversal";

        // Fundamentals of Astrodynamics and Applications, Vallado, 4th Ed., Algorithm 56 p475
        // Take r0, r => a_min, e_min, t_min, v0

        double[] r1_array = new double[] { 0, 0, 0 };
        double[] r2_array = new double[] { 0, 0, 0 };
        double[] center   = new double[] { 0, 0, 0 };

        GravityEngine ge = GravityEngine.Instance();

        // If Nbody is available get position directly. If not (target marker) then
        // use orbit phase to compute position
        ge.GetPositionDouble(centerBody, ref center);
        center3d = new Vector3d(ref center);

        if (fromOrbit.nbody != null)
        {
            ge.GetPositionDouble(fromOrbit.nbody, ref r1_array);
        }
        else
        {
            Vector3 pos = toOrbit.GetPhysicsPositionforEllipse(fromOrbit.phase);
            r1_array = new double[] { pos.x, pos.y, pos.z };
        }

        if (toOrbit.nbody != null)
        {
            ge.GetPositionDouble(toOrbit.nbody, ref r2_array);
        }
        else
        {
            Vector3 pos = toOrbit.GetPhysicsPositionforEllipse(toOrbit.phase);
            r2_array = new double[] { pos.x, pos.y, pos.z };
        }

        r1 = new Vector3d(ref r1_array) - center3d;
        r2 = new Vector3d(ref r2_array) - center3d;

        if (fromOrbit.a < toOrbit.a)
        {
            innerOrbit   = fromOrbit;
            outerOrbit   = toOrbit;
            innerToOuter = true;
        }
        else
        {
            innerOrbit   = toOrbit;
            outerOrbit   = fromOrbit;
            innerToOuter = false;
        }
        mu = ge.GetPhysicsMass(fromOrbit.centralMass);
        // determine t_min.
        // If Nbody is available get position directly. If not (target marker) then
        // use orbit phase to compute position
        double[] r0 = new double[] { 0, 0, 0 };
        double[] r  = new double[] { 0, 0, 0 };
        if (innerOrbit.nbody != null)
        {
            ge.GetPositionDouble(innerOrbit.nbody, ref r0);
        }
        else
        {
            Vector3 pos = toOrbit.GetPhysicsPositionforEllipse(innerOrbit.phase);
            r0 = new double[] { pos.x, pos.y, pos.z };
        }

        if (outerOrbit.nbody != null)
        {
            ge.GetPositionDouble(outerOrbit.nbody, ref r);
        }
        else
        {
            Vector3 pos = toOrbit.GetPhysicsPositionforEllipse(outerOrbit.phase);
            r = new double[] { pos.x, pos.y, pos.z };
        }

        ComputeMinTime(ref r0, ref r, fromOrbit.centralMass, shortPath);
    }