void UpdateReletiveTargetData(object Sender, UpdateEventArgs e) // Only works in atmosphere { Vector3D PlanetPos; Cockpit.TryGetPlanetPosition(out PlanetPos); Vector3D MePos = Me.CubeGrid.GetPosition(); Vector3D TargetPos = LastTargetData.HitPosition ?? MePos; Vector3D MeVelocity = Cockpit.GetShipVelocities().LinearVelocity; Vector3D MeGravity = Cockpit.GetNaturalGravity(); double Distance = Vector3D.Distance(TargetPos, MePos); double MeHeight = Vector3D.Distance(MePos, PlanetPos); double TargetHeight = Vector3D.Distance(TargetPos, PlanetPos); double RelativeTargetHeight = TargetHeight - MeHeight; // Should be negative when aircraft is above Vector3D RelativePlanetPos = PlanetPos - MePos; Vector3D MeRelativeGroundPos = RelativePlanetPos * (-RelativeTargetHeight / MeHeight); Vector3D MeGroundPos = MePos + MeRelativeGroundPos; Vector3D GroundPosToTarget = TargetPos - MeGroundPos; double S, U, V, A, T; // Equations of motion in SUVAT notation. T = ProjectileGroundInterceptTime(RelativeTargetHeight, Cockpit.GetShipVelocities().LinearVelocity, Cockpit.GetNaturalGravity()); S = ProjectileLateralTravelDistance(T, GroundPosToTarget, Cockpit.GetShipVelocities().LinearVelocity); double GroundDistanceToDrop = Vector3D.Distance(MeGroundPos, TargetPos) - S; double TimeUntilDrop = GroundDistanceToDrop / Cockpit.GetShipVelocities().LinearVelocity.Dot(Vector3D.Normalize(GroundPosToTarget)); Vector3D RelativePlanetPosFromTarget = PlanetPos - MePos; Vector3D ToRight = Vector3D.Normalize(GroundPosToTarget.Cross(MeGravity)); double ToRightCorrection = Vector3D.Normalize(MeVelocity).Dot(ToRight); double ToRightCorrectionAngle = Math.Asin(ToRightCorrection) / Math.PI * 180; string ToRightText = ToRightCorrectionAngle >= 0 ? "Right" : "Left"; ConsoleBuffers["ToRightCorrectionAngle"] = $"To {ToRightText}: {Math.Abs(ToRightCorrectionAngle):F1}°"; ConsoleBuffers["TimeUntilDrop"] = $"Time until Drop: {TimeUntilDrop:F1}s"; ConsoleBuffers["GroundDistanceUntillDrop"] = $"Distance until Drop: {GroundDistanceToDrop:F1}m"; }