/// <summary> /// Return ratio of perturbation force from third body relative to attraction force of mainAttractor /// </summary> /// <param name="targetBody"></param> /// <param name="mainAttractor"></param> /// <param name="perturbatingAttractor"></param> public static double RelativePerturbationRatio(CelestialBody targetBody, CelestialBody mainAttractor, CelestialBody perturbatingAttractor) { double mainAcceleration = CelestialBodyUtils.AccelerationByAttractionForce( targetBody.position, mainAttractor.position, mainAttractor.MG).magnitude; double perturbAcceleration = CelestialBodyUtils.AccelerationByAttractionForce( targetBody.position, perturbatingAttractor.position, perturbatingAttractor.MG).magnitude; return(perturbAcceleration / mainAcceleration); }
/// <summary> /// Calculate and apply n-body gravitational acceleration to target body, using algorythm Runge-Kutta. /// In result body will change it's velocity according to global gravity. /// </summary> /// <param name="body">Target body.</param> /// <param name="dt">Delta time.</param> /// <param name="minRange">Minimal attraction range for attractors.</param> /// <param name="maxRange">Maximal attraction range for attractors.</param> /// <param name="allAttractors">List of all attractors on scene.</param> public static void CalcAccelerationRungeKuttaForBody(CelestialBody body, double dt, double minRange, double maxRange, List <CelestialBody> allAttractors) { Vector3d result = Vector3d.zero; body._position += body.Velocity * (dt / 2d); for (int i = 0; i < allAttractors.Count; i++) { if (allAttractors[i] == body) { continue; } var t1 = CelestialBodyUtils.AccelerationByAttractionForce( body._position, allAttractors[i].Position, allAttractors[i].MG, minRange, Mathd.Min(maxRange, allAttractors[i].MaxAttractionRange) ) * dt; var t2 = CelestialBodyUtils.AccelerationByAttractionForce( body._position + t1 * 0.5d, allAttractors[i].Position, allAttractors[i].MG, minRange, Mathd.Min(maxRange, allAttractors[i].MaxAttractionRange) ) * dt; var t3 = CelestialBodyUtils.AccelerationByAttractionForce( body._position + t2 * 0.5d, allAttractors[i].Position, allAttractors[i].MG, minRange, Mathd.Min(maxRange, allAttractors[i].MaxAttractionRange) ) * dt; var t4 = CelestialBodyUtils.AccelerationByAttractionForce( body._position + t3, allAttractors[i].Position, allAttractors[i].MG, minRange, Mathd.Min(maxRange, allAttractors[i].MaxAttractionRange) ) * dt; result += new Vector3d( (t1.x + t2.x * 2d + t3.x * 2d + t4.x) / 6d, (t1.y + t2.y * 2d + t3.y * 2d + t4.y) / 6d, (t1.z + t2.z * 2d + t3.z * 2d + t4.z) / 6d); } if (!result.isZero) { body.Velocity += result; } }
public void CalcAccelerationRungeKuttaForBody(CelestialBody body, double dt) { Vector3d result = Vector3d.zero; body._position += body.velocity * (dt / 2d); for (int i = 0; i < attractorsCache.Count; i++) { if (attractorsCache[i] == body) { continue; } var t1 = CelestialBodyUtils.AccelerationByAttractionForce( body._position, attractorsCache[i].position, attractorsCache[i].MG, minAttractionRange, Mathd.Min(maxAttractionRange, attractorsCache[i].maxAttractionRange) ) * dt; var t2 = CelestialBodyUtils.AccelerationByAttractionForce( body._position + t1 * 0.5d, attractorsCache[i].position, attractorsCache[i].MG, minAttractionRange, Mathd.Min(maxAttractionRange, attractorsCache[i].maxAttractionRange) ) * dt; var t3 = CelestialBodyUtils.AccelerationByAttractionForce( body._position + t2 * 0.5d, attractorsCache[i].position, attractorsCache[i].MG, minAttractionRange, Mathd.Min(maxAttractionRange, attractorsCache[i].maxAttractionRange) ) * dt; var t4 = CelestialBodyUtils.AccelerationByAttractionForce( body._position + t3, attractorsCache[i].position, attractorsCache[i].MG, minAttractionRange, Mathd.Min(maxAttractionRange, attractorsCache[i].maxAttractionRange) ) * dt; result += new Vector3d( (t1.x + t2.x * 2d + t3.x * 2d + t4.x) / 6d, (t1.y + t2.y * 2d + t3.y * 2d + t4.y) / 6d, (t1.z + t2.z * 2d + t3.z * 2d + t4.z) / 6d); } body.velocity += result; }
/// <summary> /// Calculate n-body gravitational acceleration at specified world point, using Euler algorythm. /// </summary> /// <param name="pos">World position.</param> /// <param name="minRange">Minimal attraction range for attractors.</param> /// <param name="maxRange">Maximal attraction range for attractors.</param> /// <param name="allAttractors">List of all attractors on scene.</param> /// <returns>Sum of accelerations vectors at position.</returns> public static Vector3d CalcAccelerationEulerInPoint(Vector3d pos, double minRange, double maxRange, List <CelestialBody> allAttractors) { Vector3d result = new Vector3d(); for (int i = 0; i < allAttractors.Count; i++) { if (allAttractors[i].Position == pos) { continue; } result += CelestialBodyUtils.AccelerationByAttractionForce( pos, allAttractors[i].Position, allAttractors[i].MG, minRange, Mathd.Min(maxRange, allAttractors[i].MaxAttractionRange) ); } return(result); }
public Vector3d CalcAccelerationEulerInPoint(Vector3d pos) { Vector3d result = new Vector3d(); for (int i = 0; i < attractorsCache.Count; i++) { if (attractorsCache[i].position == pos) { continue; } result += CelestialBodyUtils.AccelerationByAttractionForce( pos, attractorsCache[i].position, attractorsCache[i].MG, minAttractionRange, Mathd.Min(maxAttractionRange, attractorsCache[i].maxAttractionRange) ); } return(result); }
public void CalcAccelerationEulerForBody(CelestialBody body, double dt) { Vector3d result = Vector3d.zero; for (int i = 0; i < attractorsCache.Count; i++) { if (attractorsCache[i] == body) { continue; } result += CelestialBodyUtils.AccelerationByAttractionForce( body.position, attractorsCache[i].position, attractorsCache[i].MG, minAttractionRange, Mathd.Min(maxAttractionRange, attractorsCache[i].maxAttractionRange) ); } body.velocity += result * dt; }
/// <summary> /// Calculate and apply n-body gravitational acceleration to target body, using Euler algorythm. /// In result body will change it's velocity according to global gravity. /// </summary> /// <param name="body">Target body.</param> /// <param name="dt">Delta time.</param> /// <param name="minRange">Minimal attraction range for attractors.</param> /// <param name="maxRange">Maximal attraction range for attractors.</param> /// <param name="allAttractors">List of all attractors on scene.</param> public static void CalcAccelerationEulerForBody(CelestialBody body, double dt, double minRange, double maxRange, List <CelestialBody> allAttractors) { Vector3d result = Vector3d.zero; for (int i = 0; i < allAttractors.Count; i++) { if (object.ReferenceEquals(allAttractors[i], body)) { continue; } result += CelestialBodyUtils.AccelerationByAttractionForce( body.Position, allAttractors[i].Position, allAttractors[i].MG, minRange, Mathd.Min(maxRange, allAttractors[i].MaxAttractionRange) ); } if (!result.isZero) { body.Velocity += result * dt; } }