public static double HeadingForLaunchInclination(CelestialBody body, double inclinationDegrees, double latitudeDegrees, double orbVel) { double cosDesiredSurfaceAngle = Math.Cos(inclinationDegrees * MathExtensions.Deg2Rad) / Math.Cos(latitudeDegrees * MathExtensions.Deg2Rad); if (Math.Abs(cosDesiredSurfaceAngle) > 1.0) { //If inclination < latitude, we get this case: the desired inclination is impossible if (Math.Abs(MuUtils.ClampDegrees180(inclinationDegrees)) < 90) { return(90); } else { return(270); } } else { double betaFixed = Math.Asin(cosDesiredSurfaceAngle); double velLaunchSite = body.Radius * body.angularVelocity.magnitude * Math.Cos(latitudeDegrees * MathExtensions.Deg2Rad); double vx = orbVel * Math.Sin(betaFixed) - velLaunchSite; double vy = orbVel * Math.Cos(betaFixed); double angle = MathExtensions.Rad2Deg * Math.Atan(vx / vy); if (inclinationDegrees < 0) { angle = 180 - angle; } return(MuUtils.ClampDegrees360(angle)); } }
//Returns whether o has a descending node with the equator. This can be false //if o is hyperbolic and the would-be descending node is within the opening //angle of the hyperbola. public static bool DescendingNodeEquatorialExists(this Orbit o) { return(Math.Abs(MuUtils.ClampDegrees180(o.DescendingNodeEquatorialTrueAnomaly())) <= o.MaximumTrueAnomaly()); }
//Returns whether a has a descending node with b. This can be false //if a is hyperbolic and the would-be descending node is within the opening //angle of the hyperbola. public static bool DescendingNodeExists(this Orbit a, Orbit b) { return(Math.Abs(MuUtils.ClampDegrees180(a.DescendingNodeTrueAnomaly(b))) <= a.MaximumTrueAnomaly()); }