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); } }
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); } }
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; }
/// <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)); }
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)); } }
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); } } }
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); } }
// 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); }
/// <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); }
/// <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); }
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)); }
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)); } } } }
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()); } }