/// <summary> /// Traces a massive body orbit by re-centering the world around the parent. /// </summary> public static OrbitTrace TraceMassiveBody(MassiveBodyBase body) { IMassiveBody parent = body.GravitationalParent; DVector2 initialPosition = body.Position - parent.Position; var proxyParent = new MassiveBodyProxy(DVector2.Zero, DVector2.Zero, parent); var proxySatellite = new MassiveBodyProxy(initialPosition, body.Velocity - parent.Velocity, body); double orbitalTerminationRadius; double altitude = body.GetRelativeAltitude(); double orbitalDt = GetOrbitalDt(initialPosition, proxySatellite.Velocity, out orbitalTerminationRadius); var trace = new OrbitTrace(body.Position, altitude); for (int i = 0; i < 300; i++) { proxySatellite.ResetAccelerations(); proxySatellite.ResolveGravitation(proxyParent); proxySatellite.Update(orbitalDt); altitude = proxyParent.GetRelativeHeight(proxySatellite.Position); // Check expensive termination conditions after half of the iterations if (i > 150) { DVector2 offsetVector = proxySatellite.Position - initialPosition; double distanceFromStart = offsetVector.Length(); // Terminate and add the end point if (distanceFromStart < orbitalTerminationRadius) { trace.AddPoint(proxySatellite.Position + parent.Position, altitude); break; } } trace.AddPoint(proxySatellite.Position + parent.Position, altitude); } return(trace); }
/// <summary> /// Traces a massive body orbit by re-centering the world around the parent. /// </summary> public static void TraceMassiveBody(MassiveBodyBase body, OrbitTrace trace) { IMassiveBody parent = body.GravitationalParent; DVector2 initialPosition = body.Position - parent.Position; var proxyParent = new MassiveBodyProxy(DVector2.Zero, DVector2.Zero, parent); var proxySatellite = new MassiveBodyProxy(initialPosition, body.Velocity - parent.Velocity, body); double orbitalDt = GetOrbitalDt(initialPosition.Length(), parent.Mass, proxySatellite.Velocity.Length()); trace.Reset(body.Position); // Assumes that the parent is (0,0) which will be true in this case double previousAngle = proxySatellite.Position.Angle(); double totalAngularDisplacement = 0; // Max of 1000 steps, in practice it's 150-200 for (int i = 0; i < 1000; i++) { proxySatellite.ResetAccelerations(); proxySatellite.ResolveGravitation(proxyParent); proxySatellite.Update(orbitalDt); double currentAngle = proxySatellite.Position.Angle(); totalAngularDisplacement += DeltaAngle(currentAngle, previousAngle); // Made a full orbit if (totalAngularDisplacement > AngularCutoff) { break; } previousAngle = currentAngle; double altitude = proxyParent.GetRelativeHeight(proxySatellite.Position); trace.AddPoint(proxySatellite.Position + parent.Position, altitude); } }