本文整理汇总了C#中Orbit.TimeOfTrueAnomaly方法的典型用法代码示例。如果您正苦于以下问题:C# Orbit.TimeOfTrueAnomaly方法的具体用法?C# Orbit.TimeOfTrueAnomaly怎么用?C# Orbit.TimeOfTrueAnomaly使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Orbit
的用法示例。
在下文中一共展示了Orbit.TimeOfTrueAnomaly方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: DrawOrbit
public static void DrawOrbit(Orbit o, Color c)
{
List<Vector3d> points = new List<Vector3d>();
if (o.eccentricity < 1)
{
//elliptical orbits:
for (int trueAnomaly = 0; trueAnomaly < 360; trueAnomaly += 1)
{
points.Add(o.SwappedAbsolutePositionAtUT(o.TimeOfTrueAnomaly(trueAnomaly, 0)));
}
points.Add(points[0]); //close the loop
}
else
{
//hyperbolic orbits:
for (int meanAnomaly = -1000; meanAnomaly <= 1000; meanAnomaly += 5)
{
points.Add(o.SwappedAbsolutePositionAtUT(o.UTAtMeanAnomaly(meanAnomaly * Math.PI / 180, 0)));
}
}
DrawPath(o.referenceBody, points, c, false);
}
示例2: DeltaVAndTimeForInterplanetaryTransferEjection
//Computes the time and delta-V of an ejection burn to a Hohmann transfer from one planet to another.
//It's assumed that the initial orbit around the first planet is circular, and that this orbit
//is in the same plane as the orbit of the first planet around the sun. It's also assumed that
//the target planet has a fairly low relative inclination with respect to the first planet. If the
//inclination change is nonzero you should also do a mid-course correction burn, as computed by
//DeltaVForCourseCorrection.
public static Vector3d DeltaVAndTimeForInterplanetaryTransferEjection(Orbit o, double UT, Orbit target, bool syncPhaseAngle, out double burnUT)
{
Orbit planetOrbit = o.referenceBody.orbit;
//Compute the time and dV for a Hohmann transfer where we pretend that we are the planet we are orbiting.
//This gives us the "ideal" deltaV and UT of the ejection burn, if we didn't have to worry about waiting for the right
//ejection angle and if we didn't have to worry about the planet's gravity dragging us back and increasing the required dV.
double idealBurnUT;
Vector3d idealDeltaV;
if (syncPhaseAngle)
{
//time the ejection burn to intercept the target
idealDeltaV = DeltaVAndTimeForHohmannTransfer(planetOrbit, target, UT, out idealBurnUT);
}
else
{
//don't time the ejection burn to intercept the target; we just care about the final peri/apoapsis
idealBurnUT = UT;
if (target.semiMajorAxis < planetOrbit.semiMajorAxis) idealDeltaV = DeltaVToChangePeriapsis(planetOrbit, idealBurnUT, target.semiMajorAxis);
else idealDeltaV = DeltaVToChangeApoapsis(planetOrbit, idealBurnUT, target.semiMajorAxis);
}
//Compute the actual transfer orbit this ideal burn would lead to.
Orbit transferOrbit = planetOrbit.PerturbedOrbit(idealBurnUT, idealDeltaV);
//Now figure out how to approximately eject from our current orbit into the Hohmann orbit we just computed.
//Assume we want to exit the SOI with the same velocity as the ideal transfer orbit at idealUT -- i.e., immediately
//after the "ideal" burn we used to compute the transfer orbit. This isn't quite right.
//We intend to eject from our planet at idealUT and only several hours later will we exit the SOI. Meanwhile
//the transfer orbit will have acquired a slightly different velocity, which we should correct for. Maybe
//just add in (1/2)(sun gravity)*(time to exit soi)^2 ? But how to compute time to exit soi? Or maybe once we
//have the ejection orbit we should just move the ejection burn back by the time to exit the soi?
Vector3d soiExitVelocity = idealDeltaV;
//project the desired exit direction into the current orbit plane to get the feasible exit direction
Vector3d inPlaneSoiExitDirection = Vector3d.Exclude(o.SwappedOrbitNormal(), soiExitVelocity).normalized;
//compute the angle by which the trajectory turns between periapsis (where we do the ejection burn)
//and SOI exit (approximated as radius = infinity)
double soiExitEnergy = 0.5 * soiExitVelocity.sqrMagnitude - o.referenceBody.gravParameter / o.referenceBody.sphereOfInfluence;
double ejectionRadius = o.semiMajorAxis; //a guess, good for nearly circular orbits
double ejectionKineticEnergy = soiExitEnergy + o.referenceBody.gravParameter / ejectionRadius;
double ejectionSpeed = Math.Sqrt(2 * ejectionKineticEnergy);
//construct a sample ejection orbit
Vector3d ejectionOrbitInitialVelocity = ejectionSpeed * (Vector3d)o.referenceBody.transform.right;
Vector3d ejectionOrbitInitialPosition = o.referenceBody.position + ejectionRadius * (Vector3d)o.referenceBody.transform.up;
Orbit sampleEjectionOrbit = MuUtils.OrbitFromStateVectors(ejectionOrbitInitialPosition, ejectionOrbitInitialVelocity, o.referenceBody, 0);
double ejectionOrbitDuration = sampleEjectionOrbit.NextTimeOfRadius(0, o.referenceBody.sphereOfInfluence);
Vector3d ejectionOrbitFinalVelocity = sampleEjectionOrbit.SwappedOrbitalVelocityAtUT(ejectionOrbitDuration);
double turningAngle = Math.Abs(Vector3d.Angle(ejectionOrbitInitialVelocity, ejectionOrbitFinalVelocity));
//rotate the exit direction by 90 + the turning angle to get a vector pointing to the spot in our orbit
//where we should do the ejection burn. Then convert this to a true anomaly and compute the time closest
//to planetUT at which we will pass through that true anomaly.
Vector3d ejectionPointDirection = Quaternion.AngleAxis(-(float)(90 + turningAngle), o.SwappedOrbitNormal()) * inPlaneSoiExitDirection;
double ejectionTrueAnomaly = o.TrueAnomalyFromVector(ejectionPointDirection);
burnUT = o.TimeOfTrueAnomaly(ejectionTrueAnomaly, idealBurnUT - o.period);
if ((idealBurnUT - burnUT > o.period / 2) || (burnUT < UT))
{
burnUT += o.period;
}
//rotate the exit direction by the turning angle to get a vector pointing to the spot in our orbit
//where we should do the ejection burn
Vector3d ejectionBurnDirection = Quaternion.AngleAxis(-(float)(turningAngle), o.SwappedOrbitNormal()) * inPlaneSoiExitDirection;
Vector3d ejectionVelocity = ejectionSpeed * ejectionBurnDirection;
Vector3d preEjectionVelocity = o.SwappedOrbitalVelocityAtUT(burnUT);
return ejectionVelocity - preEjectionVelocity;
}
示例3: DeltaVAndTimeForInterplanetaryLambertTransferEjection
//Computes the time and delta-V of an ejection burn to a Hohmann transfer from one planet to another.
//It's assumed that the initial orbit around the first planet is circular, and that this orbit
//is in the same plane as the orbit of the first planet around the sun. It's also assumed that
//the target planet has a fairly low relative inclination with respect to the first planet. If the
//inclination change is nonzero you should also do a mid-course correction burn, as computed by
//DeltaVForCourseCorrection.
public static Vector3d DeltaVAndTimeForInterplanetaryLambertTransferEjection(Orbit o, double UT, Orbit target, out double burnUT)
{
Orbit planetOrbit = o.referenceBody.orbit;
//Compute the time and dV for a Hohmann transfer where we pretend that we are the planet we are orbiting.
//This gives us the "ideal" deltaV and UT of the ejection burn, if we didn't have to worry about waiting for the right
//ejection angle and if we didn't have to worry about the planet's gravity dragging us back and increasing the required dV.
double idealBurnUT;
Vector3d idealDeltaV;
//time the ejection burn to intercept the target
//idealDeltaV = DeltaVAndTimeForHohmannTransfer(planetOrbit, target, UT, out idealBurnUT);
double vesselOrbitVelocity = OrbitalManeuverCalculator.CircularOrbitSpeed(o.referenceBody, o.semiMajorAxis);
idealDeltaV = DeltaVAndTimeForHohmannLambertTransfer(planetOrbit, target, UT, out idealBurnUT, vesselOrbitVelocity);
Debug.Log("idealBurnUT = " + idealBurnUT + ", idealDeltaV = " + idealDeltaV);
//Compute the actual transfer orbit this ideal burn would lead to.
Orbit transferOrbit = planetOrbit.PerturbedOrbit(idealBurnUT, idealDeltaV);
//Now figure out how to approximately eject from our current orbit into the Hohmann orbit we just computed.
//Assume we want to exit the SOI with the same velocity as the ideal transfer orbit at idealUT -- i.e., immediately
//after the "ideal" burn we used to compute the transfer orbit. This isn't quite right.
//We intend to eject from our planet at idealUT and only several hours later will we exit the SOI. Meanwhile
//the transfer orbit will have acquired a slightly different velocity, which we should correct for. Maybe
//just add in (1/2)(sun gravity)*(time to exit soi)^2 ? But how to compute time to exit soi? Or maybe once we
//have the ejection orbit we should just move the ejection burn back by the time to exit the soi?
Vector3d soiExitVelocity = idealDeltaV;
Debug.Log("soiExitVelocity = " + (Vector3)soiExitVelocity);
//compute the angle by which the trajectory turns between periapsis (where we do the ejection burn)
//and SOI exit (approximated as radius = infinity)
double soiExitEnergy = 0.5 * soiExitVelocity.sqrMagnitude - o.referenceBody.gravParameter / o.referenceBody.sphereOfInfluence;
double ejectionRadius = o.semiMajorAxis; //a guess, good for nearly circular orbits
Debug.Log("soiExitEnergy = " + soiExitEnergy);
Debug.Log("ejectionRadius = " + ejectionRadius);
double ejectionKineticEnergy = soiExitEnergy + o.referenceBody.gravParameter / ejectionRadius;
double ejectionSpeed = Math.Sqrt(2 * ejectionKineticEnergy);
Debug.Log("ejectionSpeed = " + ejectionSpeed);
//construct a sample ejection orbit
Vector3d ejectionOrbitInitialVelocity = ejectionSpeed * (Vector3d)o.referenceBody.transform.right;
Vector3d ejectionOrbitInitialPosition = o.referenceBody.position + ejectionRadius * (Vector3d)o.referenceBody.transform.up;
Orbit sampleEjectionOrbit = MuUtils.OrbitFromStateVectors(ejectionOrbitInitialPosition, ejectionOrbitInitialVelocity, o.referenceBody, 0);
double ejectionOrbitDuration = sampleEjectionOrbit.NextTimeOfRadius(0, o.referenceBody.sphereOfInfluence);
Vector3d ejectionOrbitFinalVelocity = sampleEjectionOrbit.SwappedOrbitalVelocityAtUT(ejectionOrbitDuration);
double turningAngle = Vector3d.Angle(ejectionOrbitInitialVelocity, ejectionOrbitFinalVelocity);
Debug.Log("turningAngle = " + turningAngle);
//sine of the angle between the vessel orbit and the desired SOI exit velocity
double outOfPlaneAngle = (Math.PI / 180) * (90 - Vector3d.Angle(soiExitVelocity, o.SwappedOrbitNormal()));
Debug.Log("outOfPlaneAngle (rad) = " + outOfPlaneAngle);
double coneAngle = Math.PI / 2 - (Math.PI / 180) * turningAngle;
Debug.Log("coneAngle (rad) = " + coneAngle);
Vector3d exitNormal = Vector3d.Cross(-soiExitVelocity, o.SwappedOrbitNormal()).normalized;
Vector3d normal2 = Vector3d.Cross(exitNormal, -soiExitVelocity).normalized;
//unit vector pointing to the spot on our orbit where we will burn.
//fails if outOfPlaneAngle > coneAngle.
Vector3d ejectionPointDirection = Math.Cos(coneAngle) * (-soiExitVelocity.normalized)
+ Math.Cos(coneAngle) * Math.Tan(outOfPlaneAngle) * normal2
- Math.Sqrt(Math.Pow(Math.Sin(coneAngle), 2) - Math.Pow(Math.Cos(coneAngle) * Math.Tan(outOfPlaneAngle), 2)) * exitNormal;
Debug.Log("soiExitVelocity = " + (Vector3)soiExitVelocity);
Debug.Log("vessel orbit normal = " + (Vector3)(1000 * o.SwappedOrbitNormal()));
Debug.Log("exitNormal = " + (Vector3)(1000 * exitNormal));
Debug.Log("normal2 = " + (Vector3)(1000 * normal2));
Debug.Log("ejectionPointDirection = " + ejectionPointDirection);
double ejectionTrueAnomaly = o.TrueAnomalyFromVector(ejectionPointDirection);
burnUT = o.TimeOfTrueAnomaly(ejectionTrueAnomaly, idealBurnUT - o.period);
if ((idealBurnUT - burnUT > o.period / 2) || (burnUT < UT))
{
burnUT += o.period;
}
Vector3d ejectionOrbitNormal = Vector3d.Cross(ejectionPointDirection, soiExitVelocity).normalized;
Debug.Log("ejectionOrbitNormal = " + ejectionOrbitNormal);
Vector3d ejectionBurnDirection = Quaternion.AngleAxis(-(float)(turningAngle), ejectionOrbitNormal) * soiExitVelocity.normalized;
Debug.Log("ejectionBurnDirection = " + ejectionBurnDirection);
Vector3d ejectionVelocity = ejectionSpeed * ejectionBurnDirection;
Vector3d preEjectionVelocity = o.SwappedOrbitalVelocityAtUT(burnUT);
return ejectionVelocity - preEjectionVelocity;
}
示例4: DeltaVAndApsisPhaseAngleOfHohmannTransfer
//Computes the dV of a Hohmann transfer burn at time UT that will put the apoapsis or periapsis
//of the transfer orbit on top of the target orbit.
//The output value apsisPhaseAngle is the phase angle between the transferring vessel and the
//target object as the transferring vessel crosses the target orbit at the apoapsis or periapsis
//of the transfer orbit.
//Actually, it's not exactly the phase angle. It's a sort of mean anomaly phase angle. The
//difference is not important for how this function is used by DeltaVAndTimeForHohmannTransfer.
private static Vector3d DeltaVAndApsisPhaseAngleOfHohmannTransfer(Orbit o, Orbit target, double UT, out double apsisPhaseAngle)
{
Vector3d apsisDirection = -o.SwappedRelativePositionAtUT(UT);
double desiredApsis = target.RadiusAtTrueAnomaly(MathExtensions.Deg2Rad * target.TrueAnomalyFromVector(apsisDirection));
Vector3d dV;
if (desiredApsis > o.ApR)
{
dV = DeltaVToChangeApoapsis(o, UT, desiredApsis);
Orbit transferOrbit = o.PerturbedOrbit(UT, dV);
double transferApTime = transferOrbit.NextApoapsisTime(UT);
Vector3d transferApDirection = transferOrbit.SwappedRelativePositionAtApoapsis(); // getRelativePositionAtUT was returning NaNs! :(((((
double targetTrueAnomaly = target.TrueAnomalyFromVector(transferApDirection);
double meanAnomalyOffset = 360 * (target.TimeOfTrueAnomaly(targetTrueAnomaly, UT) - transferApTime) / target.period;
apsisPhaseAngle = meanAnomalyOffset;
}
else
{
dV = DeltaVToChangePeriapsis(o, UT, desiredApsis);
Orbit transferOrbit = o.PerturbedOrbit(UT, dV);
double transferPeTime = transferOrbit.NextPeriapsisTime(UT);
Vector3d transferPeDirection = transferOrbit.SwappedRelativePositionAtPeriapsis(); // getRelativePositionAtUT was returning NaNs! :(((((
double targetTrueAnomaly = target.TrueAnomalyFromVector(transferPeDirection);
double meanAnomalyOffset = 360 * (target.TimeOfTrueAnomaly(targetTrueAnomaly, UT) - transferPeTime) / target.period;
apsisPhaseAngle = meanAnomalyOffset;
}
apsisPhaseAngle = MuUtils.ClampDegrees180(apsisPhaseAngle);
return dV;
}