public void HyperOmegaUInclNoPhase()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc         = 1.4f;
        orbitHyper.perihelion  = 20f;
        orbitHyper.r_initial   = 20f;
        orbitHyper.inclination = 35f;

        // Try some values of om
        float[] omegaValues = { 30f, 45f, 60f, 90f, 135f, 180f, 210f, 275f, 355f };
        foreach (float omega in omegaValues)
        {
            orbitHyper.omega_uc = omega;
            TestSetupUtils.SetupGravityEngine(star, planet);

            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("omega = " + omega + " od.omega_uc=" + od.omega_uc);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqualMod360(omega, od.omega_uc, 0.05));
        }
    }
    public void HyperPhaseNoIncl()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float orbitPeri  = 15f;
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc        = 1.4f;
        orbitHyper.perihelion = orbitPeri;
        orbitHyper.r_initial  = orbitPeri;

        // Try some values of om
        float[] rinit_values = { orbitPeri, orbitPeri + 2f, orbitPeri + 5f, orbitPeri + 10f, orbitPeri + 20f };
        foreach (float rinit in rinit_values)
        {
            orbitHyper.r_initial = rinit;
            TestSetupUtils.SetupGravityEngine(star, planet);

            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("rinit = " + rinit + " od.r_initial=" + od.r_initial);
            // Need a bit of leeway at 0 with error
            TestRV(od, planet, star);
        }
    }
Example #3
0
    private void HyperInit(GameObject go, NBody nbody, GameObject parent)
    {
        OrbitHyper hyper = go.GetComponent <OrbitHyper>();

        if (hyper == null)
        {
            Debug.LogError("Failed to get OrbitHyper from prefab:" + go.name);
            return;
        }
        // Awkward test code
        if (parent == star)
        {
            hyper.perihelion = Random.Range(minRadius, maxRadius);
            // aribitrary - start at fixed distance from peri
            hyper.r_initial    = 1.0f * hyper.perihelion;
            hyper.inclination  = Random.Range(-80f, 80f);
            hyper.ecc          = Random.Range(1.1f, 2f);
            hyper.centerObject = parent;
        }
        hyper.SetNBody(nbody);
        hyper.Init();
        OrbitPredictor op = go.GetComponentInChildren <OrbitPredictor>();

        if (op != null)
        {
            op.SetNBody(nbody);
            op.SetCenterObject(parent);
        }
    }
Example #4
0
    void Start()
    {
        // calculate positions for the LineRenderer (cannot assume Editor script has been invoked to do this)
        GameObject parent = transform.parent.gameObject;

        if (parent != null)
        {
            EllipseBase ellipseBase = parent.GetComponent <EllipseBase>();
            if (ellipseBase != null)
            {
                orbitP = ellipseBase;
            }
            else
            {
                OrbitHyper orbitHyper = parent.GetComponent <OrbitHyper>();
                if (orbitHyper != null)
                {
                    orbitP = orbitHyper;
                }
                else
                {
                    Debug.LogWarning("Parent object must have OrbitEllipse or OrbitHyper - cannot compute positions for line");
                }
            }
        }
        else
        {
            Debug.LogWarning("No parent object - cannot compute positions for line");
        }
        lineR = GetComponent <LineRenderer>();
        lineR.positionCount = numPoints;
    }
Example #5
0
 /// <summary>
 /// SetOrbit
 /// Determine orbit params from an attached orbit component (if Kepler) otherwise use the velocity to
 /// determine the orbit
 /// </summary>
 /// <param name="forNbody"></param>
 /// <param name="aroundNBody"></param>
 public void SetOrbit(NBody forNbody, NBody aroundNBody)
 {
     nbody       = forNbody;
     centralMass = aroundNBody;
     if (nbody.engineRef.fixedBody != null)
     {
         OrbitEllipse orbitEllipse = nbody.GetComponent <OrbitEllipse>();
         if (orbitEllipse != null)
         {
             ecc         = orbitEllipse.ecc;
             a           = orbitEllipse.a;
             omega_lc    = orbitEllipse.omega_lc;
             omega_uc    = orbitEllipse.omega_uc;
             inclination = orbitEllipse.inclination;
             period      = CalcPeriod(a, aroundNBody);
             // need tau, period
             return;
         }
         OrbitHyper orbitHyper = nbody.GetComponent <OrbitHyper>();
         if (orbitHyper != null)
         {
             ecc         = orbitHyper.ecc;
             perihelion  = orbitHyper.perihelion;
             omega_lc    = orbitHyper.omega_lc;
             omega_uc    = orbitHyper.omega_uc;
             inclination = orbitHyper.inclination;
             // need phase, tau, period
             return;
         }
     }
     SetOrbitForVelocity(forNbody, aroundNBody);
 }
    private void TestRV(OrbitData od, GameObject planet, GameObject star)
    {
        GameObject testPlanet = TestSetupUtils.CreatePlanetInHyper(star, 1f);

        testPlanet.name = "TestPlanet";
        OrbitHyper testHyper = testPlanet.GetComponent <OrbitHyper>();

        testHyper.InitFromOrbitData(od);

        planet.name = "Planet";

        // Awkward but cannot add a new object to GE when it is stopped, so re-add all three
        GravityEngine ge = GravityEngine.Instance();

        ge.Clear();
        ge.AddBody(star);
        ge.AddBody(planet);
        ge.AddBody(testPlanet);
        ge.Setup();
        ge.LogDump();
        Vector3 r_od = ge.GetPhysicsPosition(testPlanet.GetComponent <NBody>());
        Vector3 v_od = ge.GetVelocity(testPlanet);
        Vector3 r_i  = ge.GetPhysicsPosition(planet.GetComponent <NBody>());
        Vector3 v_i  = ge.GetVelocity(planet);

        Debug.Log(" r_i=" + r_i + " r_od=" + r_od + " delta=" + Vector3.Distance(r_i, r_od));
        Debug.Log(" v_i=" + v_i + " v_od=" + v_od + " delta=" + Vector3.Distance(v_i, v_od));
        Assert.IsTrue(FloatEqual(Vector3.Distance(r_i, r_od), 0f, 5E-2));
        Assert.IsTrue(FloatEqual(Vector3.Distance(v_i, v_od), 0f, 5E-2));
    }
Example #7
0
    public void HyperOmegaLNoInclNoPhase()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        const float orbitPeri  = 15f;
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc        = 1.4f;
        orbitHyper.perihelion = orbitPeri;
        orbitHyper.r_initial  = orbitPeri;

        // Try some values of om
        float[] omegaValues = { 30f, 45f, 60f, 90f, 135f, 180f, 0f };
        foreach (float omega in omegaValues)
        {
            orbitHyper.omega_lc = omega;
            orbitHyper.Init();
            orbitHyper.InitNBody(1f, 1f);
            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("omega = " + omega + " od.omega_l=" + od.omega_lc);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(omega, od.omega_lc, 0.05));
            TestRV(od, planet, star);
        }
    }
    public void HyperInclination()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.ecc       = 1.4f;
        orbitHyper.r_initial = 20f;

        // Try some values of om
        float[] inclValues = { 30f, 45f, 60f, 90f, 135f, 180f, 0f };
        foreach (float incl in inclValues)
        {
            orbitHyper.inclination = incl;
            TestSetupUtils.SetupGravityEngine(star, planet);

            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("incl = " + incl + " od.incl=" + od.inclination);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(incl, od.inclination, 0.02));
        }
    }
Example #9
0
    public void HyperInclOmega()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.r_initial = 20f;
        orbitHyper.ecc       = 2.5f;

        // Try some values of phase
        float[] inclinationValues = { 0f, 30f, 45f, 60f, 90f, 135f, 180f };
        float[] omegaUValues      = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float incl in inclinationValues)
        {
            foreach (float omegau in omegaUValues)
            {
                orbitHyper.inclination = incl;
                orbitHyper.omega_uc    = omegau;
                orbitHyper.Init();
                orbitHyper.InitNBody(1f, 1f);
                orbitHyper.Log("Initial circle:");
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
                Debug.Log("incl = " + incl + " od.incl=" + od.inclination);
                Debug.Log("omegaU = " + omegau + " od.omegau=" + od.omega_uc);
                TestRV(od, planet, star);
            }
        }
    }
Example #10
0
    public override void OnInspectorGUI()
    {
        GUI.changed = false;
        OrbitHyper hyperBase = (OrbitHyper)target;
        // fields in class
        GameObject centerObject       = null;
        float      ecc                = 0;
        float      perihelion         = 0;
        float      omega_uc           = 0;
        float      omega_lc           = 0;
        float      inclination        = 0;
        float      r_initial          = 0;
        bool       r_initial_outbound = false;

        if (!(target is BinaryPair))
        {
            centerObject = (GameObject)EditorGUILayout.ObjectField(
                new GUIContent("CenterObject", centerTip),
                hyperBase.centerObject,
                typeof(GameObject),
                true);
        }

        EditorGUIUtility.labelWidth = 200;
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Ellipse Parameters", EditorStyles.boldLabel);


        ecc = EditorGUILayout.FloatField(new GUIContent("Eccentricity", eTip), hyperBase.ecc);
        if (ecc <= 1f)
        {
            ecc = 1.01f;
        }

        perihelion = EditorGUILayout.FloatField(new GUIContent("Perihelion", pTip), hyperBase.perihelion);
        // implementation uses AngleAxis, so degrees are more natural
        omega_uc    = EditorGUILayout.Slider(new GUIContent("\u03a9 (Longitude of AN)", omega_ucTip), hyperBase.omega_uc, 0, 360f);
        omega_lc    = EditorGUILayout.Slider(new GUIContent("\u03c9 (AN to Pericenter)", omega_lcTip), hyperBase.omega_lc, 0, 360f);
        inclination = EditorGUILayout.Slider(new GUIContent("Inclination", inclinationTip), hyperBase.inclination, 0f, 180f);
        r_initial   = EditorGUILayout.FloatField(new GUIContent("Initial Distance", phaseTip), hyperBase.r_initial);
        if (r_initial < perihelion)
        {
            r_initial = perihelion;
        }
        r_initial_outbound = EditorGUILayout.Toggle(new GUIContent("Initial Distance Outbound", obTip), hyperBase.r_initial_outbound);

        if (GUI.changed)
        {
            Undo.RecordObject(hyperBase, "OrbitHyper Change");
            hyperBase.perihelion         = perihelion;
            hyperBase.ecc                = ecc;
            hyperBase.centerObject       = centerObject;
            hyperBase.omega_lc           = omega_lc;
            hyperBase.omega_uc           = omega_uc;
            hyperBase.inclination        = inclination;
            hyperBase.r_initial          = r_initial;
            hyperBase.r_initial_outbound = r_initial_outbound;
            EditorUtility.SetDirty(hyperBase);
        }
    }
Example #11
0
    // Use this for initialization
    void Start()
    {
        nbody = body.GetComponent <NBody>();
        if (nbody == null)
        {
            Debug.LogWarning("Cannot show orbit - Body requires NBody component");
            return;
        }
        aroundNBody = centerBody.GetComponent <NBody>();
        if (aroundNBody == null)
        {
            Debug.LogWarning("Cannot show orbit - centerBody requires NBody component");
            return;
        }
        initOk             = true;
        lineR              = GetComponent <LineRenderer>();
        lineR.numPositions = numPoints;
        orbitData          = new OrbitData();

        ellipseBase = transform.gameObject.AddComponent <EllipseBase>();
        ellipseBase.centerObject = centerBody;

        orbitHyper = transform.gameObject.AddComponent <OrbitHyper>();
        orbitHyper.centerObject = centerBody;
    }
    // Create a planet in orbit around center object with semi-major axis a
    public static GameObject CreatePlanetInHyper(GameObject center, float mass)
    {
        // position will be trumped by orbit
        GameObject planet = CreateNBody(mass, new Vector3(1, 0, 0));

        OrbitHyper orbitHyper = planet.AddComponent <OrbitHyper>();

        orbitHyper.SetCenterBody(center);
        return(planet);
    }
Example #13
0
 /// <summary>
 /// SetOrbit
 /// Determine orbit params from an attached orbit component (if Kepler) otherwise use the velocity to
 /// determine the orbit
 /// </summary>
 /// <param name="forNbody"></param>
 /// <param name="aroundNBody"></param>
 public void SetOrbit(NBody forNbody, NBody aroundNBody)
 {
     nbody       = forNbody;
     centralMass = aroundNBody;
     // is this a Kepler body
     if (nbody.engineRef.fixedBody != null)
     {
         OrbitEllipse orbitEllipse = nbody.GetComponent <OrbitEllipse>();
         if (orbitEllipse != null)
         {
             ecc         = orbitEllipse.ecc;
             a           = orbitEllipse.a * GravityEngine.Instance().GetLengthScale();
             omega_lc    = orbitEllipse.omega_lc;
             omega_uc    = orbitEllipse.omega_uc;
             inclination = orbitEllipse.inclination;
             mu          = GravityEngine.Instance().GetPhysicsMass(aroundNBody);
             period      = CalcPeriod();
             // TODO:  tau
             phase = orbitEllipse.phase;
             return;
         }
         OrbitUniversal orbitU = nbody.GetComponent <OrbitUniversal>();
         if (orbitU != null)
         {
             ecc = (float)orbitU.eccentricity;
             // Might need to make a > 0 for hyperbola since OrbitData got this wrong??
             a           = (float)orbitU.p / (1 - ecc * ecc);
             omega_lc    = (float)orbitU.omega_lc;
             omega_uc    = (float)orbitU.omega_uc;
             inclination = (float)orbitU.inclination;
             mu          = GravityEngine.Instance().GetPhysicsMass(aroundNBody);
             period      = CalcPeriod();
             // TODO:  tau
             phase = (float)orbitU.phase;
             return;
         }
         OrbitHyper orbitHyper = nbody.GetComponent <OrbitHyper>();
         if (orbitHyper != null)
         {
             ecc         = orbitHyper.ecc;
             perihelion  = orbitHyper.perihelion * GravityEngine.Instance().GetLengthScale();
             omega_lc    = orbitHyper.omega_lc;
             omega_uc    = orbitHyper.omega_uc;
             inclination = orbitHyper.inclination;
             // need phase, tau, period
             return;
         }
     }
     SetOrbitForVelocity(forNbody, aroundNBody);
 }
Example #14
0
    /// <summary>
    /// Determine if and how many objects are orbital parents.
    /// e.g. Sun = 0, planet=1, moon=2
    /// </summary>
    public void CalcOrbitDepth()
    {
        GameObject go = gameObject;

        do
        {
            OrbitEllipse ellipse = go.GetComponent <OrbitEllipse>();
            if (ellipse != null)
            {
                go = ellipse.centerObject;
                orbitDepth++;
                continue;
            }
            OrbitUniversal orbitU = go.GetComponent <OrbitUniversal>();
            if (orbitU != null)
            {
                go = orbitU.centerNbody.gameObject;
                orbitDepth++;
                continue;
            }
            OrbitHyper hyper = go.GetComponent <OrbitHyper>();
            if (hyper != null)
            {
                go = hyper.centerObject;
                orbitDepth++;
                continue;
            }
            if (go.transform.parent != null)
            {
                BinaryPair bp = go.transform.parent.gameObject.GetComponent <BinaryPair>();
                if (bp != null)
                {
                    go = bp.gameObject;
                    orbitDepth++;
                    continue;
                }
                // If parent has an NBody, then it's an orbital parent, since need to inherit its velocity
                NBody nbody_parent = go.transform.parent.gameObject.GetComponent <NBody>();
                if (nbody_parent != null)
                {
                    go = nbody_parent.gameObject;
                    orbitDepth++;
                    continue;
                }
            }
            go = null;
        } while (go != null);
    }
Example #15
0
    private void TestRV(OrbitData od, GameObject planet, GameObject star)
    {
        Vector3 r_initial = planet.transform.position;
        Vector3 v_initial = planet.GetComponent <NBody>().vel;

        GameObject testPlanet = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper testHyper  = testPlanet.GetComponent <OrbitHyper>();

        testHyper.InitFromOrbitData(od);
        testHyper.Init();
        testHyper.InitNBody(1f, 1f);
        Vector3 r = testPlanet.transform.position;
        Vector3 v = testPlanet.GetComponent <NBody>().vel;

        Debug.Log(" r_i=" + r_initial + " r=" + r + " delta=" + Vector3.Distance(r_initial, r));
        Debug.Log(" v_i=" + v_initial + " v=" + v + " delta=" + Vector3.Distance(v_initial, v));
        Assert.IsTrue(FloatEqual(Vector3.Distance(r_initial, r), 0f, 5E-2));
        Assert.IsTrue(FloatEqual(Vector3.Distance(v_initial, v), 0f, 5E-2));
    }
Example #16
0
    public void HyperBasic()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        // Try some values of om
        float[] eccValues = { 1.1f, 1.3f, 2f, 2.2f, 3f, 10f };
        foreach (float ecc in eccValues)
        {
            orbitHyper.ecc = ecc;
            orbitHyper.Init();
            orbitHyper.InitNBody(1f, 1f);
            orbitHyper.Log(System.Reflection.MethodBase.GetCurrentMethod().Name);
            OrbitData od = new OrbitData();
            od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
            Debug.Log("ecc = " + ecc + " od.ecc=" + od.ecc);
            // Need a bit of leeway at 0 with error
            Assert.IsTrue(FloatEqual(ecc, od.ecc, 0.02));
        }
    }
    public void HyperInclOmega()
    {
        const float mass       = 1000f;
        GameObject  star       = TestSetupUtils.CreateNBody(mass, new Vector3(0, 0, 0));
        GameObject  planet     = TestSetupUtils.CreatePlanetInHyper(star, 1f);
        OrbitHyper  orbitHyper = planet.GetComponent <OrbitHyper>();

        orbitHyper.r_initial = 20f;
        orbitHyper.ecc       = 2.5f;

        // Try some values of phase (incl=0 covered by another test)
        float[] inclinationValues = { 30f, 45f, 60f, 90f, 135f, 180f };
        float[] omegaUValues      = { 0f, 30f, 45f, 60f, 90f, 135f, 180f, 210f, 320f };
        foreach (float incl in inclinationValues)
        {
            foreach (float omegau in omegaUValues)
            {
                orbitHyper.inclination = incl;
                orbitHyper.omega_uc    = omegau;
                TestSetupUtils.SetupGravityEngine(star, planet);
                Debug.LogFormat("Test for i={0} omegaU={1}", incl, omegau);
                orbitHyper.Log("Initial circle:");
                OrbitData od = new OrbitData();
                od.SetOrbitForVelocity(planet.GetComponent <NBody>(), star.GetComponent <NBody>());
                Debug.Log("OrbitData: " + od.LogString());
                TestRV(od, planet, star);
                Debug.Log("incl = " + incl + " od.incl=" + od.inclination);
                Debug.Log("omegaU = " + omegau + " od.omegau=" + od.omega_uc + " od.omega_lc=" + od.omega_lc);
                if (incl != 180f)
                {
                    // 180 comes back as omegaL = omegaU = 180, but TestRV is ok
                    Assert.IsTrue(FloatEqual(incl, od.inclination, 0.02));
                    Assert.IsTrue(FloatEqualMod360(omegau, od.omega_uc, 0.02));
                }
            }
        }
    }
Example #18
0
    public override void OnInspectorGUI()
    {
        GUI.changed = false;
        OrbitHyper hyperBase = (OrbitHyper)target;
        // fields in class
        GameObject centerObject       = null;
        float      ecc                = 0;
        float      perihelion         = 0;
        float      omega_uc           = 0;
        float      omega_lc           = 0;
        float      inclination        = 0;
        float      r_initial          = 0;
        bool       r_initial_outbound = false;
        bool       r_initial_flip     = false;
        float      branchFactor       = 0f;

        if (!(target is BinaryPair))
        {
            centerObject = (GameObject)EditorGUILayout.ObjectField(
                new GUIContent("CenterObject", centerTip),
                hyperBase.centerObject,
                typeof(GameObject),
                true);
        }

        EditorGUIUtility.labelWidth = 200;
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Orbit Parameters", EditorStyles.boldLabel);

        OrbitHyper.EvolveType evolveMode = hyperBase.evolveMode;

        evolveMode = (OrbitHyper.EvolveType)EditorGUILayout.EnumPopup(new GUIContent("Evolve Mode", modeTip), hyperBase.evolveMode);


        ecc = EditorGUILayout.FloatField(new GUIContent("Eccentricity", eTip), hyperBase.ecc);
        if (ecc <= 1f)
        {
            ecc = 1.01f;
        }

        perihelion = EditorGUILayout.FloatField(new GUIContent("Periapse", pTip), hyperBase.perihelion);
        // implementation uses AngleAxis, so degrees are more natural
        omega_uc    = EditorGUILayout.Slider(new GUIContent("\u03a9 (Longitude of AN)", omega_ucTip), hyperBase.omega_uc, 0, 360f);
        omega_lc    = EditorGUILayout.Slider(new GUIContent("\u03c9 (AN to Pericenter)", omega_lcTip), hyperBase.omega_lc, 0, 360f);
        inclination = EditorGUILayout.Slider(new GUIContent("Inclination", inclinationTip), hyperBase.inclination, 0f, 180f);
        r_initial   = EditorGUILayout.FloatField(new GUIContent("Initial Distance", phaseTip), hyperBase.r_initial);
        if (r_initial < perihelion)
        {
            r_initial = perihelion;
        }
        r_initial_outbound = EditorGUILayout.Toggle(new GUIContent("Initial Distance Outbound", obTip), hyperBase.r_initial_outbound);
        r_initial_flip     = EditorGUILayout.Toggle(new GUIContent("Flip Initial Position", flipTip), hyperBase.r_start_flip);

        branchFactor = EditorGUILayout.Slider(new GUIContent("Branch Display Fraction", branchTip), hyperBase.branchDisplayFactor, 0, 0.9f);

        if (GUI.changed)
        {
            Undo.RecordObject(hyperBase, "OrbitHyper Change");
            hyperBase.evolveMode          = evolveMode;
            hyperBase.perihelion          = perihelion;
            hyperBase.ecc                 = ecc;
            hyperBase.centerObject        = centerObject;
            hyperBase.omega_lc            = omega_lc;
            hyperBase.omega_uc            = omega_uc;
            hyperBase.inclination         = inclination;
            hyperBase.r_initial           = r_initial;
            hyperBase.r_initial_outbound  = r_initial_outbound;
            hyperBase.r_start_flip        = r_initial_flip;
            hyperBase.branchDisplayFactor = branchFactor;
            EditorUtility.SetDirty(hyperBase);
            hyperBase.ApplyScale(GravityEngine.Instance().GetLengthScale());
        }
    }