//Originally by Zool, revised by The_Duck //Converts a true anomaly into an eccentric anomaly. //For elliptical orbits this returns a value between 0 and 2pi //For hyperbolic orbits the returned value can be any number. //NOTE: For a hyperbolic orbit, if a true anomaly is requested that does not exist (a true anomaly //past the true anomaly of the asymptote) then an ArgumentException is thrown public static double GetEccentricAnomalyAtTrueAnomaly(this Orbit o, double trueAnomaly) { double e = o.eccentricity; trueAnomaly = MuUtils.ClampDegrees360(trueAnomaly); trueAnomaly = trueAnomaly * (Math.PI / 180); if (e < 1) //elliptical orbits { double cosE = (e + Math.Cos(trueAnomaly)) / (1 + e * Math.Cos(trueAnomaly)); double sinE = Math.Sqrt(1 - (cosE * cosE)); if (trueAnomaly > Math.PI) { sinE *= -1; } return(MuUtils.ClampRadiansTwoPi(Math.Atan2(sinE, cosE))); } else //hyperbolic orbits { double coshE = (e + Math.Cos(trueAnomaly)) / (1 + e * Math.Cos(trueAnomaly)); if (coshE < 1) { throw new ArgumentException("OrbitExtensions.GetEccentricAnomalyAtTrueAnomaly: True anomaly of " + trueAnomaly + " radians is not attained by orbit with eccentricity " + o.eccentricity); } double E = MuUtils.Acosh(coshE); if (trueAnomaly > Math.PI) { E *= -1; } return(E); } }
//The next time at which the orbiting object will reach the given mean anomaly. //For elliptical orbits, this will be a time between UT and UT + o.period //For hyperbolic orbits, this can be any time, including a time in the past, if //the given mean anomaly occurred in the past public static double UTAtMeanAnomaly(this Orbit o, double meanAnomaly, double UT) { double currentMeanAnomaly = o.MeanAnomalyAtUT(UT); double meanDifference = meanAnomaly - currentMeanAnomaly; if (o.eccentricity < 1) { meanDifference = MuUtils.ClampRadiansTwoPi(meanDifference); } return(UT + meanDifference / o.MeanMotion()); }
//The mean anomaly of the orbit. //For elliptical orbits, the value return is always between 0 and 2pi //For hyperbolic orbits, the value can be any number. public static double MeanAnomalyAtUT(this Orbit o, double UT) { // We use ObtAtEpoch and not meanAnomalyAtEpoch because somehow meanAnomalyAtEpoch // can be wrong when using the RealSolarSystem mod. ObtAtEpoch is always correct. double ret = (o.ObTAtEpoch + (UT - o.epoch)) * o.MeanMotion(); if (o.eccentricity < 1) { ret = MuUtils.ClampRadiansTwoPi(ret); } return(ret); }
//Originally by Zool, revised by The_Duck //Converts an eccentric anomaly into a mean anomaly. //For an elliptical orbit, the returned value is between 0 and 2pi //For a hyperbolic orbit, the returned value is any number public static double GetMeanAnomalyAtEccentricAnomaly(this Orbit o, double E) { double e = o.eccentricity; if (e < 1) //elliptical orbits { return(MuUtils.ClampRadiansTwoPi(E - (e * Math.Sin(E)))); } else //hyperbolic orbits { return((e * Math.Sinh(E)) - E); } }