/// <summary> /// Scale the size of the orbit /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static KeplerOrbitalParameters operator *(double b, KeplerOrbitalParameters a) { KeplerOrbitalParameters kop = new KeplerOrbitalParameters(a); kop.semiMajorLength *= b; return(kop); }
public KeplerOrbitalParameters(KeplerOrbitalParameters other) { this.ascendingNodeInRad = other.ascendingNodeInRad; this.eccentricity = other.eccentricity; this.inclinationInRad = other.inclinationInRad; this.meanAnomaly = other.meanAnomaly; this.perifocusInRad = other.perifocusInRad; this.semiMajorLength = other.semiMajorLength; }
/// <summary> /// Construct kepler orbit from orbital parameters object /// </summary> /// <param name="parent"></param> /// <param name="parameters"></param> public KeplerOrbit(KeplerBody parent, KeplerOrbitalParameters parameters) : this( parent, parameters.semiMajorLength, parameters.eccentricity, parameters.meanAnomaly, parameters.inclinationInRad, parameters.perifocusInRad, parameters.ascendingNodeInRad ) { }
/// <summary> /// Add velocity to modify the orbit /// </summary> /// <param name="deltaV"></param> public void AddVelocity(Vector3d deltaV) { Vector3d vel = this.GetCurrentVelocity() + deltaV; KeplerOrbitalParameters kp = KeplerOrbitalParameters.SolveOrbitalParameters(this.standardGravitationalParameter, this.GetCurrentPosition(), vel); this.semiMajorLength = kp.semiMajorLength; this.eccentricity = kp.eccentricity; this.meanAnomaly = kp.meanAnomaly; this.inclination = kp.inclinationInRad; this.perifocus = kp.perifocusInRad; this.ascendingNode = kp.ascendingNodeInRad; }
/// <summary> /// Create orbital parameters from an object in a cartesian coordinate system centered on a large mass in which to orbit /// https://en.wikipedia.org/wiki/Orbital_elements /// http://orbitsimulator.com/formulas/OrbitalElements.html /// </summary> /// <param name="mu">standard gravitational parameter</param> /// <param name="position">relative position</param> /// <param name="velocity">velocity</param> /// <returns></returns> public static KeplerOrbitalParameters SolveOrbitalParameters(double mu, Vector3d position, Vector3d velocity) { KeplerOrbitalParameters kop = new KeplerOrbitalParameters(); Vector3d r = position; Vector3d v = velocity; double R = r.magnitude; double V = v.magnitude; //Semi major axis double a = 1 / (2 / R - V * V / mu); //Angular momentum Vector3d h = Vector3d.Cross(r, v); double H = h.magnitude; Vector3d node = Vector3d.Cross(Vector3d.up, h); //... double p = H * H / mu; double q = Vector3d.Dot(r, v); //Eccentricity Vector3d e = (V * V / mu - 1 / R) * r - (q / mu) * v; double E = Math.Sqrt(1.0d - p / a); double Ex = 1.0d - R / a; double Ez = q / Math.Sqrt(a * mu); //Inclination (0 - 180 degrees) double i = Math.Acos(h.y / H); if (i >= KeplerConstants.PI) { i = KeplerConstants.PI - i; } if (i == KeplerConstants.TWO_PI) { i = 0; } double lan = 0; if (i % KeplerConstants.PI != 0) { lan = Math.Atan2(h.x, -h.z); } //Argument of perifocus double W; if (i == 0) { //Equitorial orbit W = Math.Atan2(e.z, e.x); } else { W = Math.Acos( Vector3d.Dot(node, e) / (node.magnitude * E) ); } if (W < 0) { W = KeplerConstants.TWO_PI + W; } //Compute anomalies double tAnom = Math.Acos(Vector3d.Dot(e, r) / (E * R)); if (q < 0) { tAnom = KeplerConstants.TWO_PI - tAnom; } double eAnom = KeplerUtils.TrueToEccentric(tAnom, E); double mAnom = KeplerUtils.EccentricToMean(eAnom, E); //double eAnom = Math.Atan2(Ez, Ex); //eccentric anomaly //double mAnom = eAnom - E * Math.Sin(eAnom); //mean anomaly //Set the values kop.ascendingNodeInRad = lan; kop.eccentricity = E; kop.inclinationInRad = i; kop.meanAnomaly = mAnom; kop.perifocusInRad = W; kop.semiMajorLength = a; return(kop); }