/// <summary> /// Sets the mean anomaly and updates all other anomalies. /// </summary> /// <param name="m">The m.</param> public void SetMeanAnomaly(double m) { if (!IsValidOrbit) { return; } MeanAnomaly = m % KeplerOrbitUtils.PI_2; if (Eccentricity < 1.0) { if (MeanAnomaly < 0) { MeanAnomaly += KeplerOrbitUtils.PI_2; } EccentricAnomaly = KeplerOrbitUtils.KeplerSolver(MeanAnomaly, Eccentricity); TrueAnomaly = KeplerOrbitUtils.ConvertEccentricToTrueAnomaly(EccentricAnomaly, Eccentricity); } else if (Eccentricity > 1.0) { EccentricAnomaly = KeplerOrbitUtils.KeplerSolverHyperbolicCase(MeanAnomaly, Eccentricity); TrueAnomaly = KeplerOrbitUtils.ConvertEccentricToTrueAnomaly(EccentricAnomaly, Eccentricity); } else { EccentricAnomaly = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(MeanAnomaly, Eccentricity); TrueAnomaly = EccentricAnomaly; } SetPositionByCurrentAnomaly(); SetVelocityByCurrentAnomaly(); }
/// <summary> /// Updates the value of orbital anomalies by defined deltatime. /// </summary> /// <param name="deltaTime">The delta time.</param> /// <remarks> /// Only anomalies values will be changed. /// Position and velocity states needs to be updated too after this method call. /// </remarks> public void UpdateOrbitAnomaliesByTime(double deltaTime) { if (Eccentricity < 1.0) { MeanAnomaly += MeanMotion * deltaTime; MeanAnomaly %= KeplerOrbitUtils.PI_2; if (MeanAnomaly < 0) { MeanAnomaly = KeplerOrbitUtils.PI_2 - MeanAnomaly; } EccentricAnomaly = KeplerOrbitUtils.KeplerSolver(MeanAnomaly, Eccentricity); double cosE = Math.Cos(EccentricAnomaly); TrueAnomaly = Math.Acos((cosE - Eccentricity) / (1 - Eccentricity * cosE)); if (MeanAnomaly > Math.PI) { TrueAnomaly = KeplerOrbitUtils.PI_2 - TrueAnomaly; } } else if (Eccentricity > 1.0) { MeanAnomaly = MeanAnomaly + MeanMotion * deltaTime; EccentricAnomaly = KeplerOrbitUtils.KeplerSolverHyperbolicCase(MeanAnomaly, Eccentricity); TrueAnomaly = Math.Atan2(Math.Sqrt(Eccentricity * Eccentricity - 1.0) * Math.Sinh(EccentricAnomaly), Eccentricity - Math.Cosh(EccentricAnomaly)); } else { MeanAnomaly = MeanAnomaly + MeanMotion * deltaTime; EccentricAnomaly = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(MeanAnomaly, Eccentricity); TrueAnomaly = EccentricAnomaly; } }
/// <summary> /// Updates the value of orbital anomalies by defined deltatime. /// </summary> /// <param name="deltaTime">The delta time.</param> /// <remarks> /// Only anomalies values will be changed. /// Position and velocity states needs to be updated too after this method call. /// </remarks> public void UpdateOrbitAnomaliesByTime(double deltaTime) { if (Eccentricity < 1) { if (Period > 1e-5) { MeanAnomaly += KeplerOrbitUtils.PI_2 * deltaTime / Period; } MeanAnomaly %= KeplerOrbitUtils.PI_2; if (MeanAnomaly < 0) { MeanAnomaly = KeplerOrbitUtils.PI_2 - MeanAnomaly; } EccentricAnomaly = KeplerOrbitUtils.KeplerSolver(MeanAnomaly, Eccentricity); var cosE = Math.Cos(EccentricAnomaly); TrueAnomaly = Math.Acos((cosE - Eccentricity) / (1 - Eccentricity * cosE)); if (MeanAnomaly > Math.PI) { TrueAnomaly = KeplerOrbitUtils.PI_2 - TrueAnomaly; } if (double.IsNaN(MeanAnomaly) || double.IsInfinity(MeanAnomaly)) { Debug.Log("KeplerOrbitData: NaN(INF) MEAN ANOMALY"); //little paranoya Debug.Break(); } if (double.IsNaN(EccentricAnomaly) || double.IsInfinity(EccentricAnomaly)) { Debug.Log("KeplerOrbitData: NaN(INF) ECC ANOMALY"); Debug.Break(); } if (double.IsNaN(TrueAnomaly) || double.IsInfinity(TrueAnomaly)) { Debug.Log("KeplerOrbitData: NaN(INF) TRUE ANOMALY"); Debug.Break(); } } else { double n = Math.Sqrt(AttractorMass * GravConst / Math.Pow(SemiMajorAxis, 3));// * Math.Sign(OrbitNormalDotEclipticNormal); MeanAnomaly = MeanAnomaly + n * deltaTime; EccentricAnomaly = KeplerOrbitUtils.KeplerSolverHyperbolicCase(MeanAnomaly, Eccentricity); TrueAnomaly = Math.Atan2(Math.Sqrt(Eccentricity * Eccentricity - 1.0) * Math.Sinh(EccentricAnomaly), Eccentricity - Math.Cosh(EccentricAnomaly)); } }
/// <summary> /// Updates the value of orbital anomalies by defined deltatime. /// </summary> /// <param name="deltaTime">The delta time.</param> /// <remarks> /// Only anomalies values will be changed. /// Position and velocity states needs to be updated too after this method call. /// </remarks> public void UpdateOrbitAnomaliesByTime(double deltaTime) { if (Eccentricity < 1) { if (Period > KeplerOrbitUtils.Epsilon) { MeanAnomaly += MeanMotion * deltaTime; } MeanAnomaly %= KeplerOrbitUtils.PI_2; if (MeanAnomaly < 0) { MeanAnomaly = KeplerOrbitUtils.PI_2 - MeanAnomaly; } EccentricAnomaly = KeplerOrbitUtils.KeplerSolver(MeanAnomaly, Eccentricity); double cosE = Math.Cos(EccentricAnomaly); TrueAnomaly = Math.Acos((cosE - Eccentricity) / (1 - Eccentricity * cosE)); if (MeanAnomaly > Math.PI) { TrueAnomaly = KeplerOrbitUtils.PI_2 - TrueAnomaly; } if (double.IsNaN(MeanAnomaly) || double.IsInfinity(MeanAnomaly)) { Debug.Log("KeplerOrbitData: NaN(INF) MEAN ANOMALY"); //little paranoya Debug.Break(); } if (double.IsNaN(EccentricAnomaly) || double.IsInfinity(EccentricAnomaly)) { Debug.Log("KeplerOrbitData: NaN(INF) ECC ANOMALY"); Debug.Break(); } if (double.IsNaN(TrueAnomaly) || double.IsInfinity(TrueAnomaly)) { Debug.Log("KeplerOrbitData: NaN(INF) TRUE ANOMALY"); Debug.Break(); } } else { MeanAnomaly = MeanAnomaly + MeanMotion * deltaTime; EccentricAnomaly = KeplerOrbitUtils.KeplerSolverHyperbolicCase(MeanAnomaly, Eccentricity); TrueAnomaly = Math.Atan2(Math.Sqrt(Eccentricity * Eccentricity - 1.0) * Math.Sinh(EccentricAnomaly), Eccentricity - Math.Cosh(EccentricAnomaly)); } }
/// <summary> /// Sets the eccentricity and updates all corresponding orbit state values. /// </summary> /// <param name="e">The new eccentricity value.</param> public void SetEccentricity(double e) { if (!IsValidOrbit) { return; } e = Math.Abs(e); double periapsis = PeriapsisDistance; // Periapsis remains constant Eccentricity = e; double compresion = Eccentricity < 1 ? (1 - Eccentricity * Eccentricity) : (Eccentricity * Eccentricity - 1); SemiMajorAxis = Math.Abs(periapsis / (1 - Eccentricity)); FocalParameter = SemiMajorAxis * compresion; SemiMinorAxis = SemiMajorAxis * Math.Sqrt(compresion); CenterPoint = SemiMajorAxis * Math.Abs(Eccentricity) * SemiMajorAxisBasis; if (Eccentricity < 1.0) { EccentricAnomaly = KeplerOrbitUtils.KeplerSolver(MeanAnomaly, Eccentricity); double cosE = Math.Cos(EccentricAnomaly); TrueAnomaly = Math.Acos((cosE - Eccentricity) / (1 - Eccentricity * cosE)); if (MeanAnomaly > Math.PI) { TrueAnomaly = KeplerOrbitUtils.PI_2 - TrueAnomaly; } } else if (Eccentricity > 1.0) { EccentricAnomaly = KeplerOrbitUtils.KeplerSolverHyperbolicCase(MeanAnomaly, Eccentricity); TrueAnomaly = Math.Atan2(Math.Sqrt(Eccentricity * Eccentricity - 1) * Math.Sinh(EccentricAnomaly), Eccentricity - Math.Cosh(EccentricAnomaly)); } else { EccentricAnomaly = KeplerOrbitUtils.ConvertMeanToEccentricAnomaly(MeanAnomaly, Eccentricity); TrueAnomaly = EccentricAnomaly; } SetVelocityByCurrentAnomaly(); SetPositionByCurrentAnomaly(); CalculateOrbitStateFromOrbitalVectors(); }