Exemplo n.º 1
0
        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));
            }
        }
Exemplo n.º 2
0
        //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);
            }
        }
Exemplo n.º 3
0
 //Gives the true anomaly at which o crosses the equator going southwards, if o is east-moving,
 //or northwards, if o is west-moving.
 //The returned value is always between 0 and 360.
 public static double DescendingNodeEquatorialTrueAnomaly(this Orbit o)
 {
     return(MuUtils.ClampDegrees360(o.AscendingNodeEquatorialTrueAnomaly() + 180));
 }
Exemplo n.º 4
0
 //Gives the true anomaly (in a's orbit) at which a crosses its descending node
 //with b's orbit.
 //The returned value is always between 0 and 360.
 public static double DescendingNodeTrueAnomaly(this Orbit a, Orbit b)
 {
     return(MuUtils.ClampDegrees360(a.AscendingNodeTrueAnomaly(b) + 180));
 }