pub trait OrbitTrait2D {
Show 104 methods
// Required methods
fn set_apoapsis(&mut self, apoapsis: f64) -> Result<(), ApoapsisSetterError>;
fn set_apoapsis_force(&mut self, apoapsis: f64);
fn get_transformation_matrix(&self) -> DMat2;
fn get_pqw_basis_vector_p(&self) -> DVec2;
fn get_pqw_basis_vector_q(&self) -> DVec2;
fn get_eccentricity(&self) -> f64;
fn set_eccentricity(&mut self, eccentricity: f64);
fn get_periapsis(&self) -> f64;
fn set_periapsis(&mut self, periapsis: f64);
fn get_arg_pe(&self) -> f64;
fn set_arg_pe(&mut self, arg_pe: f64);
fn get_mean_anomaly_at_epoch(&self) -> f64;
fn set_mean_anomaly_at_epoch(&mut self, mean_anomaly: f64);
fn get_gravitational_parameter(&self) -> f64;
fn set_gravitational_parameter(
&mut self,
gravitational_parameter: f64,
mode: MuSetterMode2D,
);
// Provided methods
fn get_semi_major_axis(&self) -> f64 { ... }
fn get_semi_minor_axis(&self) -> f64 { ... }
fn get_semi_latus_rectum(&self) -> f64 { ... }
fn get_linear_eccentricity(&self) -> f64 { ... }
fn get_true_anomaly_at_asymptote(&self) -> f64 { ... }
fn get_position_at_periapsis(&self) -> DVec2 { ... }
fn get_position_at_periapsis_unchecked(&self, p_vector: DVec2) -> DVec2 { ... }
fn get_position_at_apoapsis(&self) -> DVec2 { ... }
fn get_position_at_apoapsis_unchecked(&self, p_vector: DVec2) -> DVec2 { ... }
fn get_apoapsis(&self) -> f64 { ... }
fn get_mean_motion(&self) -> f64 { ... }
fn get_focal_parameter(&self) -> f64 { ... }
fn get_specific_angular_momentum(&self) -> f64 { ... }
fn get_specific_orbital_energy(&self) -> f64 { ... }
fn get_area_sweep_rate(&self) -> f64 { ... }
fn get_time_of_periapsis(&self) -> f64 { ... }
fn get_time_of_apoapsis(&self) -> f64 { ... }
fn get_pqw_basis_vectors(&self) -> (DVec2, DVec2) { ... }
fn get_eccentricity_vector(&self) -> DVec2 { ... }
fn get_eccentricity_vector_unchecked(&self, p_vector: DVec2) -> DVec2 { ... }
fn get_eccentric_anomaly_at_mean_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_approx_hyperbolic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_hyperbolic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_elliptic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_eccentric_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... }
fn get_eccentric_anomaly_at_time(&self, time: f64) -> f64 { ... }
fn get_true_anomaly_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> f64 { ... }
fn get_true_anomaly_at_mean_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_true_anomaly_at_time(&self, time: f64) -> f64 { ... }
fn get_true_anomaly_at_altitude(&self, altitude: f64) -> f64 { ... }
fn get_true_anomaly_at_altitude_unchecked(
&self,
semi_latus_rectum: f64,
altitude: f64,
eccentricity_recip: f64,
) -> f64 { ... }
fn get_mean_anomaly_at_time(&self, time: f64) -> f64 { ... }
fn get_mean_anomaly_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> f64 { ... }
fn get_mean_anomaly_at_elliptic_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
sin_eccentric_anomaly: f64,
) -> f64 { ... }
fn get_mean_anomaly_at_hyperbolic_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
sinh_eccentric_anomaly: f64,
) -> f64 { ... }
fn get_mean_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... }
fn get_position_at_true_anomaly(&self, angle: f64) -> DVec2 { ... }
fn get_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2 { ... }
fn get_speed_at_true_anomaly(&self, angle: f64) -> f64 { ... }
fn get_speed_at_altitude(&self, altitude: f64) -> f64 { ... }
fn get_speed_at_periapsis(&self) -> f64 { ... }
fn get_speed_at_apoapsis(&self) -> f64 { ... }
fn get_speed_at_infinity(&self) -> f64 { ... }
fn get_speed_at_time(&self, time: f64) -> f64 { ... }
fn get_speed_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64 { ... }
fn get_speed_at_mean_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_pqw_velocity_at_true_anomaly(&self, angle: f64) -> DVec2 { ... }
fn get_pqw_velocity_at_periapsis(&self) -> DVec2 { ... }
fn get_pqw_velocity_at_apoapsis(&self) -> DVec2 { ... }
fn get_pqw_velocity_at_incoming_asymptote(&self) -> DVec2 { ... }
fn get_pqw_velocity_at_outgoing_asymptote(&self) -> DVec2 { ... }
fn get_pqw_velocity_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> DVec2 { ... }
fn get_pqw_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2 { ... }
fn get_pqw_velocity_at_eccentric_anomaly_unchecked(
&self,
outer_mult: f64,
q_mult: f64,
trig_ecc_anom: (f64, f64),
) -> DVec2 { ... }
fn get_pqw_velocity_at_time(&self, time: f64) -> DVec2 { ... }
fn get_pqw_position_at_true_anomaly(&self, angle: f64) -> DVec2 { ... }
fn get_pqw_position_at_true_anomaly_unchecked(
&self,
altitude: f64,
sincos_angle: (f64, f64),
) -> DVec2 { ... }
fn get_pqw_position_at_time(&self, time: f64) -> DVec2 { ... }
fn get_pqw_position_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> DVec2 { ... }
fn get_velocity_at_true_anomaly(&self, angle: f64) -> DVec2 { ... }
fn get_velocity_at_periapsis(&self) -> DVec2 { ... }
fn get_velocity_at_apoapsis(&self) -> DVec2 { ... }
fn get_velocity_at_incoming_asymptote(&self) -> DVec2 { ... }
fn get_velocity_at_outgoing_asymptote(&self) -> DVec2 { ... }
fn get_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2 { ... }
fn get_velocity_at_time(&self, time: f64) -> DVec2 { ... }
fn get_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2 { ... }
fn get_altitude_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... }
fn get_altitude_at_true_anomaly_unchecked(
&self,
semi_latus_rectum: f64,
cos_true_anomaly: f64,
) -> f64 { ... }
fn get_altitude_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64 { ... }
fn get_altitude_at_time(&self, time: f64) -> f64 { ... }
fn get_position_at_time(&self, time: f64) -> DVec2 { ... }
fn get_position_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2 { ... }
fn get_state_vectors_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> StateVectors2D { ... }
fn get_state_vectors_at_true_anomaly(
&self,
true_anomaly: f64,
) -> StateVectors2D { ... }
fn get_state_vectors_at_mean_anomaly(
&self,
mean_anomaly: f64,
) -> StateVectors2D { ... }
fn get_state_vectors_at_time(&self, time: f64) -> StateVectors2D { ... }
fn get_state_vectors_from_unchecked_parts(
&self,
sqrt_abs_gm_a: f64,
altitude: f64,
q_mult: f64,
trig_ecc_anom: (f64, f64),
sincos_angle: (f64, f64),
) -> StateVectors2D { ... }
fn get_time_at_mean_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_time_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64 { ... }
fn get_time_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... }
fn transform_pqw_vector(&self, position: DVec2) -> DVec2 { ... }
fn is_circular(&self) -> bool { ... }
fn is_elliptic(&self) -> bool { ... }
fn is_closed(&self) -> bool { ... }
fn is_parabolic(&self) -> bool { ... }
fn is_hyperbolic(&self) -> bool { ... }
fn is_open(&self) -> bool { ... }
fn get_orbital_period(&self) -> f64 { ... }
}Expand description
A trait that defines the methods that a 2D-constrained Keplerian orbit must implement.
This trait is implemented by both Orbit2D and CompactOrbit2D.
§Examples
use keplerian_sim::{Orbit2D, OrbitTrait2D, CompactOrbit2D};
fn accepts_orbit(orbit: &impl OrbitTrait2D) {
println!("That's an orbit!");
}
fn main() {
let orbit = Orbit2D::default();
accepts_orbit(&orbit);
let compact = CompactOrbit2D::default();
accepts_orbit(&compact);
}This example will fail to compile:
let not_orbit = (0.0, 1.0);
accepts_orbit(¬_orbit);Required Methods§
Sourcefn set_apoapsis(&mut self, apoapsis: f64) -> Result<(), ApoapsisSetterError>
fn set_apoapsis(&mut self, apoapsis: f64) -> Result<(), ApoapsisSetterError>
Sets the apoapsis of the orbit.\
§Errors
Errors when the apoapsis is less than the periapsis, or less than zero.
If you want a setter that does not error, use set_apoapsis_force, which will
try its best to interpret what you might have meant, but may have
undesirable behavior.
§Examples
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(50.0);
assert!(
orbit.set_apoapsis(100.0)
.is_ok()
);
let result = orbit.set_apoapsis(25.0);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
keplerian_sim::ApoapsisSetterError::ApoapsisLessThanPeriapsis
);
let result = orbit.set_apoapsis(-25.0);
assert!(result.is_err());
assert_eq!(
result.unwrap_err(),
keplerian_sim::ApoapsisSetterError::ApoapsisNegative
);Sourcefn set_apoapsis_force(&mut self, apoapsis: f64)
fn set_apoapsis_force(&mut self, apoapsis: f64)
Sets the apoapsis of the orbit, with a best-effort attempt at interpreting
possibly-invalid values.
This function will not error, but may have undesirable behavior:
- If the given apoapsis is less than the periapsis but more than zero, the orbit will be flipped and the periapsis will be set to the given apoapsis.
- If the given apoapsis is negative but between zero and negative periapsis, the apoapsis will get treated as infinity and the orbit will be parabolic. (This is because even in hyperbolic orbits, apoapsis cannot be between 0 and -periapsis)\
- If the given apoapsis is negative AND less than negative periapsis, the orbit will be hyperbolic.
If these behaviors are undesirable, consider creating a custom wrapper around
set_eccentricity instead.
§Examples
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut base = Orbit2D::default();
base.set_periapsis(50.0);
let mut normal = base.clone();
// Set the apoapsis to 100
normal.set_apoapsis_force(100.0);
assert_eq!(normal.get_apoapsis(), 99.99999999999997);
assert_eq!(normal.get_periapsis(), 50.0);
assert_eq!(normal.get_arg_pe(), 0.0);
assert_eq!(normal.get_mean_anomaly_at_epoch(), 0.0);
let mut flipped = base.clone();
// Set the "apoapsis" to 25
// This will flip the orbit, setting the altitude
// where the current apoapsis is, to 25, and
// flipping the orbit.
// This sets the periapsis to 25, and the apoapsis to the
// previous periapsis.
flipped.set_apoapsis_force(25.0);
assert_eq!(flipped.get_apoapsis(), 49.999999999999986);
assert_eq!(flipped.get_periapsis(), 25.0);
assert_eq!(flipped.get_arg_pe(), std::f64::consts::PI);
assert_eq!(flipped.get_mean_anomaly_at_epoch(), std::f64::consts::PI);
let mut hyperbolic = base.clone();
// Set the "apoapsis" to -250
hyperbolic.set_apoapsis_force(-250.0);
assert_eq!(hyperbolic.get_apoapsis(), -250.0);
assert_eq!(hyperbolic.get_periapsis(), 50.0);
assert_eq!(hyperbolic.get_arg_pe(), 0.0);
assert!(hyperbolic.get_eccentricity() > 1.0);
assert_eq!(hyperbolic.get_mean_anomaly_at_epoch(), 0.0);
let mut parabolic = base.clone();
// Set the "apoapsis" to between 0 and -50
// This will set the apoapsis to infinity, and the orbit will be parabolic.
parabolic.set_apoapsis_force(-25.0);
assert!(parabolic.get_apoapsis().is_infinite());
assert_eq!(parabolic.get_periapsis(), 50.0);
assert_eq!(parabolic.get_arg_pe(), 0.0);
assert_eq!(parabolic.get_eccentricity(), 1.0);
assert_eq!(parabolic.get_mean_anomaly_at_epoch(), 0.0);Sourcefn get_transformation_matrix(&self) -> DMat2
fn get_transformation_matrix(&self) -> DMat2
Gets the transformation matrix needed to tilt a 2D vector into the tilted orbital plane.
§Performance
For CompactOrbit2D, this will perform a few trigonometric operations.
If you need this value often, consider using the cached orbit struct instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::{DVec2, DMat2};
let orbit = Orbit2D::default();
let matrix = orbit.get_transformation_matrix();
assert_eq!(matrix, DMat2 {
x_axis: DVec2::new(1.0, 0.0),
y_axis: DVec2::new(0.0, 1.0),
});Sourcefn get_pqw_basis_vector_p(&self) -> DVec2
fn get_pqw_basis_vector_p(&self) -> DVec2
Gets the p basis vector for the perifocal coordinate (PQW) system.
The p basis vector is a unit vector that points to the periapsis.
For more information about the PQW system, visit the Wikipedia article.
§Performance
For CompactOrbit2D, this will perform a few trigonometric operations
and multiplications, and therefore is not too performant.
For Orbit2D, this will only need to access the cache, and
therefore is much more performant.
If you want to get multiple basis vectors, use
get_pqw_basis_vectors
instead, as that skips some duplicated work.
§Example
use keplerian_sim::{Orbit2D, CompactOrbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = Orbit2D::default();
let p = orbit.get_pqw_basis_vector_p();
let q = orbit.get_pqw_basis_vector_q();
assert_eq!(p, DVec2::X);
assert_eq!(q, DVec2::Y);
let compact_orbit = CompactOrbit2D::default();
let p = compact_orbit.get_pqw_basis_vector_p();
let q = compact_orbit.get_pqw_basis_vector_q();
assert_eq!(p, DVec2::X);
assert_eq!(q, DVec2::Y);Sourcefn get_pqw_basis_vector_q(&self) -> DVec2
fn get_pqw_basis_vector_q(&self) -> DVec2
Gets the q basis vector for the perifocal coordinate (PQW) system.
The q basis vector is orthogonal to the p basis vector and points 90° counterclockwise from the periapsis on the orbital plane.
For more information about the PQW system, visit the Wikipedia article.
§Performance
For CompactOrbit2D, this will perform a few trigonometric operations
and multiplications, and therefore is not too performant.
For Orbit2D, this will only need to access the cache, and
therefore is much more performant.
If you want to get multiple basis vectors, use
get_pqw_basis_vectors
instead, as that skips some duplicated work.
§Example
use keplerian_sim::{Orbit2D, CompactOrbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = Orbit2D::default();
let p = orbit.get_pqw_basis_vector_p();
let q = orbit.get_pqw_basis_vector_q();
assert_eq!(p, DVec2::X);
assert_eq!(q, DVec2::Y);
let compact_orbit = CompactOrbit2D::default();
let p = compact_orbit.get_pqw_basis_vector_p();
let q = compact_orbit.get_pqw_basis_vector_q();
assert_eq!(p, DVec2::X);
assert_eq!(q, DVec2::Y);Sourcefn get_eccentricity(&self) -> f64
fn get_eccentricity(&self) -> f64
Gets the eccentricity of the orbit.
The eccentricity of an orbit is a measure of how much it deviates from a perfect circle.
An eccentricity of 0 means the orbit is a perfect circle.
Between 0 and 1, the orbit is elliptic, and has an oval shape.
An orbit with an eccentricity of 1 is said to be parabolic.
If it’s greater than 1, the orbit is hyperbolic.
For hyperbolic trajectories, the higher the eccentricity, the straighter the path.
Wikipedia on conic section eccentricity: https://en.wikipedia.org/wiki/Eccentricity_(mathematics)
(Keplerian orbits are conic sections, so the concepts still apply)
Sourcefn set_eccentricity(&mut self, eccentricity: f64)
fn set_eccentricity(&mut self, eccentricity: f64)
Sets the eccentricity of the orbit.
The eccentricity of an orbit is a measure of how much it deviates from a perfect circle.
An eccentricity of 0 means the orbit is a perfect circle.
Between 0 and 1, the orbit is elliptic, and has an oval shape.
An orbit with an eccentricity of 1 is said to be parabolic.
If it’s greater than 1, the orbit is hyperbolic.
For hyperbolic trajectories, the higher the eccentricity, the straighter the path.
Wikipedia on conic section eccentricity: https://en.wikipedia.org/wiki/Eccentricity_(mathematics)
(Keplerian orbits are conic sections, so the concepts still apply)
Sourcefn get_periapsis(&self) -> f64
fn get_periapsis(&self) -> f64
Gets the periapsis of the orbit.
The periapsis of an orbit is the distance at the closest point to the parent body.
More simply, this is the “minimum altitude” of an orbit.
Wikipedia: https://en.wikipedia.org/wiki/Apsis
Sourcefn set_periapsis(&mut self, periapsis: f64)
fn set_periapsis(&mut self, periapsis: f64)
Sets the periapsis of the orbit.
The periapsis of an orbit is the distance at the closest point to the parent body.
More simply, this is the “minimum altitude” of an orbit.
Wikipedia: https://en.wikipedia.org/wiki/Apsis
Sourcefn get_arg_pe(&self) -> f64
fn get_arg_pe(&self) -> f64
Gets the argument of periapsis of the orbit in radians.
Wikipedia:
The argument of periapsis is the angle from the body’s
ascending node to its periapsis, measured in the direction of
motion.
https://en.wikipedia.org/wiki/Argument_of_periapsis
In simple terms, it tells you how, and in which direction, the orbit “tilts”.
Sourcefn set_arg_pe(&mut self, arg_pe: f64)
fn set_arg_pe(&mut self, arg_pe: f64)
Sets the argument of periapsis of the orbit in radians.
Wikipedia:
The argument of periapsis is the angle from the body’s
ascending node to its periapsis, measured in the direction of
motion.
https://en.wikipedia.org/wiki/Argument_of_periapsis
In simple terms, it tells you how, and in which direction, the orbit “tilts”.
Sourcefn get_mean_anomaly_at_epoch(&self) -> f64
fn get_mean_anomaly_at_epoch(&self) -> f64
Gets the mean anomaly of the orbit at a certain epoch.
For elliptic orbits, it’s measured in radians and so are bounded
between 0 and tau; anything out of range will get wrapped around.
For hyperbolic orbits, it’s unbounded.
Wikipedia:
The mean anomaly at epoch, M_0, is defined as the instantaneous mean
anomaly at a given epoch, t_0.
https://en.wikipedia.org/wiki/Mean_anomaly#Mean_anomaly_at_epoch
In simple terms, this modifies the “offset” of the orbit progression.
Sourcefn set_mean_anomaly_at_epoch(&mut self, mean_anomaly: f64)
fn set_mean_anomaly_at_epoch(&mut self, mean_anomaly: f64)
Sets the mean anomaly of the orbit at a certain epoch.
For elliptic orbits, it’s measured in radians and so are bounded
between 0 and tau; anything out of range will get wrapped around.
For hyperbolic orbits, it’s unbounded.
Wikipedia:
The mean anomaly at epoch, M_0, is defined as the instantaneous mean
anomaly at a given epoch, t_0.
https://en.wikipedia.org/wiki/Mean_anomaly#Mean_anomaly_at_epoch
In simple terms, this modifies the “offset” of the orbit progression.
Sourcefn get_gravitational_parameter(&self) -> f64
fn get_gravitational_parameter(&self) -> f64
Gets the gravitational parameter of the parent body.
The gravitational parameter mu of the parent body equals a certain gravitational constant G times the mass of the parent body M.
In other words, mu = GM.
Sourcefn set_gravitational_parameter(
&mut self,
gravitational_parameter: f64,
mode: MuSetterMode2D,
)
fn set_gravitational_parameter( &mut self, gravitational_parameter: f64, mode: MuSetterMode2D, )
Sets the gravitational parameter of the parent body.
The gravitational parameter mu of the parent body equals a certain gravitational constant G times the mass of the parent body M.
In other words, mu = GM.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D, MuSetterMode2D};
let mut orbit = Orbit2D::new(
0.0, // Eccentricity
1.0, // Periapsis
0.0, // Argument of Periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter (mu = GM)
);
orbit.set_gravitational_parameter(3.0, MuSetterMode2D::KeepElements);
assert_eq!(orbit.get_eccentricity(), 0.0);
assert_eq!(orbit.get_periapsis(), 1.0);
assert_eq!(orbit.get_arg_pe(), 0.0);
assert_eq!(orbit.get_mean_anomaly_at_epoch(), 0.0);
assert_eq!(orbit.get_gravitational_parameter(), 3.0);Provided Methods§
Sourcefn get_semi_major_axis(&self) -> f64
fn get_semi_major_axis(&self) -> f64
Gets the semi-major axis of the orbit.
In an elliptic orbit, the semi-major axis is the
average of the apoapsis and periapsis.
This function uses a generalization which uses
eccentricity instead.
This function returns infinity for parabolic orbits, and negative values for hyperbolic orbits.
Learn more: https://en.wikipedia.org/wiki/Semi-major_and_semi-minor_axes
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(50.0);
orbit.set_apoapsis_force(100.0);
let sma = orbit.get_semi_major_axis();
let expected = 75.0;
assert!((sma - expected).abs() < 1e-6);§Performance
This function is very performant and should not be the cause of any performance issues.
Sourcefn get_semi_minor_axis(&self) -> f64
fn get_semi_minor_axis(&self) -> f64
Gets the semi-minor axis of the orbit.
In an elliptic orbit, the semi-minor axis is half of the maximum “width” of the orbit.
Learn more: https://en.wikipedia.org/wiki/Semi-major_and_semi-minor_axes
§Performance
This function is performant and is unlikely to be the cause of any performance issues.
Sourcefn get_semi_latus_rectum(&self) -> f64
fn get_semi_latus_rectum(&self) -> f64
Gets the semi-latus rectum of the orbit, in meters.
Learn more: https://en.wikipedia.org/wiki/Ellipse#Semi-latus_rectum
https://en.wikipedia.org/wiki/Conic_section#Conic_parameters
§Performance
This function is very performant and should not be the cause of any performance issues.
Sourcefn get_linear_eccentricity(&self) -> f64
fn get_linear_eccentricity(&self) -> f64
Gets the linear eccentricity of the orbit, in meters.
In an elliptic orbit, the linear eccentricity is the distance between its center and either of its two foci (focuses).
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(50.0);
orbit.set_apoapsis_force(100.0);
// Let's say the periapsis is at x = -50.
// The apoapsis would be at x = 100.
// The midpoint would be at x = 25.
// The parent body - one of its foci - is always at the origin (x = 0).
// This means the linear eccentricity is 25.
let linear_eccentricity = orbit.get_linear_eccentricity();
let expected = 25.0;
assert!((linear_eccentricity - expected).abs() < 1e-6);Sourcefn get_true_anomaly_at_asymptote(&self) -> f64
fn get_true_anomaly_at_asymptote(&self) -> f64
Gets the true anomaly asymptote (f_∞) of the hyperbolic trajectory.
This returns a positive number between π/2 and π for open trajectories, and NaN for closed orbits.
This can be used to get the range of possible true anomalies that
a hyperbolic trajectory can be in.
This function returns the maximum true anomaly, and the minimum
true anomaly can be derived simply by negating the result:
f_-∞ = -f_∞The minimum and maximum together represent the range of possible true anomalies.
§Performance
This function is moderately performant and contains only one trigonometry operation.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
// Closed (elliptic) orbit with eccentricity = 0.8
let closed = Orbit2D::new(0.8, 1.0, 0.0, 0.0, 1.0);
// True anomaly asymptote is only defined for open orbits,
// i.e., eccentricity ≥ 1
assert!(closed.get_true_anomaly_at_asymptote().is_nan());
let parabolic = Orbit2D::new(1.0, 1.0, 0.0, 0.0, 1.0);
assert_eq!(
parabolic.get_true_anomaly_at_asymptote(),
std::f64::consts::PI
);
let hyperbolic = Orbit2D::new(2.0, 1.0, 0.0, 0.0, 1.0);
let asymptote = 2.0943951023931957;
assert_eq!(
hyperbolic.get_true_anomaly_at_asymptote(),
asymptote
);
// At the asymptote, the altitude is infinite.
// Note: We can't use the regular `get_altitude_at_true_anomaly` here
// because it is less accurate (since it uses cos() while the asymptote uses
// acos(), and the roundtrip causes precision loss).
// We use the unchecked version with the exact cosine value
// of the true anomaly (-1/e) to avoid float inaccuracies.
let asymptote_cos = -1.0 / hyperbolic.get_eccentricity();
// We first check that asymptote_cos is close to cos(asymptote):
assert!(
(asymptote_cos - asymptote.cos()).abs() < 1e-15
);
// Then we can be fairly confident this will be exactly infinite:
assert!(
hyperbolic
.get_altitude_at_true_anomaly_unchecked(
hyperbolic.get_semi_latus_rectum(),
asymptote_cos
)
.is_infinite()
)Sourcefn get_position_at_periapsis(&self) -> DVec2
fn get_position_at_periapsis(&self) -> DVec2
Gets the position of the orbit at periapsis.
§Performance
In the cached orbit struct (Orbit2D), this function is
very performant and only involves three multiplications.
However, in the compact orbit struct (CompactOrbit2D), this
is a lot slower and involves some trigonometric calculations.
If you already know the P basis vector of the PQW coordinate system,
you may use the unchecked version instead
(get_position_at_periapsis_unchecked),
which is a lot faster and would skip repeated calculations.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = Orbit2D::new(
0.25, // Eccentricity
1.0, // Periapsis
0.0, // Argument of periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
assert_eq!(
orbit.get_position_at_periapsis(),
DVec2::new(1.0, 0.0)
);Sourcefn get_position_at_periapsis_unchecked(&self, p_vector: DVec2) -> DVec2
fn get_position_at_periapsis_unchecked(&self, p_vector: DVec2) -> DVec2
Gets the position of the orbit at periapsis based on a known P basis vector.
The P basis vector is one of the basis vector from the PQW coordinate system.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
§Unchecked Operation
This function does not check that the given p_vector
is a unit vector nor whether it actually is the basis vector in the
PQW coordinate system.
It is expected that callers get this vector from either
the transformation matrix
(get_transformation_matrix),
the basis vector collective getter
(get_pqw_basis_vectors),
or the individual basis vector getter
(get_pqw_basis_vector_p).
A safe wrapper is available, but that may be slower; see the Performance section for details.
§Performance
There is no reason to use this if you are using the cached
orbit struct (Orbit2D) as the performance is identical to the
wrapper function.
However, in the compact orbit struct (CompactOrbit2D), this
skips some expensive trigonometry operations and therefore is
a lot faster than the wrapper function.
§Example
use keplerian_sim::{CompactOrbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = CompactOrbit2D::new(
0.25, // Eccentricity
1.0, // Periapsis
0.0, // Argument of periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
let p_vector = orbit.get_pqw_basis_vector_p();
// Use p_vector here...
// Use it again for periapsis position!
assert_eq!(
orbit.get_position_at_periapsis_unchecked(p_vector),
DVec2::new(1.0, 0.0)
);Sourcefn get_position_at_apoapsis(&self) -> DVec2
fn get_position_at_apoapsis(&self) -> DVec2
Gets the position of the orbit at apoapsis.
§Performance
In the cached orbit struct (Orbit2D), this function is
very performant and only involves three multiplications.
However, in the compact orbit struct (CompactOrbit2D), this
is a lot slower and involves some trigonometric calculations.
If you already know the P basis vector of the PQW coordinate system,
you may use the unchecked version instead
(get_position_at_apoapsis_unchecked),
which is a lot faster and would skip repeated calculations.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = Orbit2D::new(
0.25, // Eccentricity
1.0, // Periapsis
0.0, // Argument of periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
assert_eq!(
orbit.get_position_at_apoapsis(),
DVec2::new(-1.6666666666666665, 0.0)
);Sourcefn get_position_at_apoapsis_unchecked(&self, p_vector: DVec2) -> DVec2
fn get_position_at_apoapsis_unchecked(&self, p_vector: DVec2) -> DVec2
Gets the position of the orbit at apoapsis based on a known P basis vector.
The P basis vector is one of the basis vector from the PQW coordinate system.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
§Unchecked Operation
This function does not check that the given p_vector
is a unit vector nor whether it actually is the basis vector in the
PQW coordinate system.
It is expected that callers get this vector from either
the transformation matrix
(get_transformation_matrix),
the basis vector collective getter
(get_pqw_basis_vectors),
or the individual basis vector getter
(get_pqw_basis_vector_p).
A safe wrapper is available, but that may be slower; see the Performance section for details.
§Performance
There is no reason to use this if you are using the cached
orbit struct (Orbit2D) as the performance is identical to the
wrapper function.
However, in the compact orbit struct (CompactOrbit2D), this
skips some expensive trigonometry operations and therefore is
a lot faster than the wrapper function.
§Example
use keplerian_sim::{CompactOrbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = CompactOrbit2D::new(
0.25, // Eccentricity
1.0, // Periapsis
0.0, // Argument of periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
let p_vector = orbit.get_pqw_basis_vector_p();
// Use p_vector here...
// Use it again for apoapsis position!
assert_eq!(
orbit.get_position_at_apoapsis_unchecked(p_vector),
DVec2::new(-1.6666666666666665, 0.0)
);Sourcefn get_apoapsis(&self) -> f64
fn get_apoapsis(&self) -> f64
Gets the apoapsis of the orbit.
Returns infinity for parabolic orbits.
Returns negative values for hyperbolic orbits.\
§Performance
This function is very performant and should not be the cause of any performance issues.
§Examples
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_eccentricity(0.5); // Elliptic
assert!(orbit.get_apoapsis() > 0.0);
orbit.set_eccentricity(1.0); // Parabolic
assert!(orbit.get_apoapsis().is_infinite());
orbit.set_eccentricity(2.0); // Hyperbolic
assert!(orbit.get_apoapsis() < 0.0);Sourcefn get_mean_motion(&self) -> f64
fn get_mean_motion(&self) -> f64
Gets the mean motion of the orbit, in radians per second.
Mean motion (represented by n) is the angular speed required for
a body to complete one orbit, assuming constant speed in a circular
orbit which completes in the same time as the variable speed,
elliptical orbit of the actual body.
§Performance
This function is performant and is unlikely to be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let orbit = Orbit2D::new(
0.8, // Eccentricity
9.4, // Periapsis
2.0, // Argument of periapsis
1.5, // Mean anomaly at epoch
0.8, // Gravitational parameter
);
let orbital_period = orbit.get_orbital_period();
let mean_motion = std::f64::consts::TAU / orbital_period;
assert!((orbit.get_mean_motion() - mean_motion).abs() < f64::EPSILON);Sourcefn get_focal_parameter(&self) -> f64
fn get_focal_parameter(&self) -> f64
Gets the focal parameter of the orbit, in meters.
This returns infinity in circular orbits (e = 0).
The focal parameter (p) is the distance from a focus to the corresponding directrix.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let orbit = Orbit2D::new(
1.0, // Eccentricity
3.0, // Periapsis
2.9, // Argument of periapsis
0.8, // Mean anomaly at epoch
1.9, // Gravitational parameter
);
// From Wikipedia's focal parameter equation for parabolas (e = 1)
// (a in this case is periapsis distance, not semi-major axis)
let expected_focal_parameter = 2.0 * orbit.get_periapsis();
assert!(
(orbit.get_focal_parameter() - expected_focal_parameter).abs() < f64::EPSILON
);Sourcefn get_specific_angular_momentum(&self) -> f64
fn get_specific_angular_momentum(&self) -> f64
Gets the specific angular momentum of the orbit, in square meters per second (m^2/s).
The specific relative angular momentum of a body is the angular momentum of that body divided by its mass.
§Performance
This function is performant and is unlikely to be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let orbit = Orbit2D::new(
1.2, // Eccentricity
2.0, // Periapsis
3.0, // Argument of periapsis
4.8, // Mean anomaly at epoch
5.0, // Gravitational parameter
);
const EXPECTED_VALUE: f64 = 4.69041575982343;
let momentum =
orbit.get_specific_angular_momentum();
assert!((momentum - EXPECTED_VALUE).abs() < f64::EPSILON);Sourcefn get_specific_orbital_energy(&self) -> f64
fn get_specific_orbital_energy(&self) -> f64
Gets the specific orbital energy ε of the orbit,
in joules per kilogram (J/kg, equiv. to m^2 ⋅ s^-2).
For closed orbits (eccentricity < 0), ε < 0.
When eccentricity equals 1 (parabolic), ε equals 0,
and when eccentricity exceeds 1 (hyperbolic), ε is positive.
The specific orbital energy ε of two orbiting bodies is
the constant quotient of their mechanical energy
(the sum of their mutual potential energy, ε_p, and their
kinetic energy, ε_k) to their reduced mass.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let elliptic = Orbit2D::new(0.3, 1.0, 0.0, 0.0, 1.0);
let parabolic = Orbit2D::new(1.0, 1.0, 0.0, 0.0, 1.0);
let hyperbolic = Orbit2D::new(2.6, 1.0, 0.0, 0.0, 1.0);
assert!(elliptic.get_specific_orbital_energy() < 0.0);
assert!(parabolic.get_specific_orbital_energy() == 0.0);
assert!(hyperbolic.get_specific_orbital_energy() > 0.0);Sourcefn get_area_sweep_rate(&self) -> f64
fn get_area_sweep_rate(&self) -> f64
Gets the area swept out by the orbit in square meters per second (m^2/s).
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let orbit = Orbit2D::new(
2.9, // Eccentricity
4.9, // Periapsis
0.2, // Argument of periapsis
0.9, // Mean anomaly at epoch
9.8, // Gravitational parameter
);
const EXPECTED_RATE: f64 = 6.842477621446782;
assert!(
(orbit.get_area_sweep_rate() - EXPECTED_RATE).abs() < f64::EPSILON
);Sourcefn get_time_of_periapsis(&self) -> f64
fn get_time_of_periapsis(&self) -> f64
Gets the time when the orbit is in periapsis, in seconds since epoch.
This returns the time when mean anomaly equals zero.
This means although it will represent a time of periapsis,
it doesn’t mean “next periapsis” nor “previous periapsis”,
it just means “a periapsis”, at least for closed orbits
(e < 1).
§Parabolic Support
This function does not support parabolic trajectories yet.
Calling this function on a parabolic trajectory results in a
non-finite number.
§Performance
This function is performant and is unlikely to be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
const PERIAPSIS: f64 = 1.0;
let orbit = Orbit2D::new(
0.3, // Eccentricity
PERIAPSIS,
2.9, // Argument of periapsis
1.5, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
let time_of_pe = orbit.get_time_of_periapsis();
let alt_of_pe = orbit.get_altitude_at_time(time_of_pe);
assert!(
(alt_of_pe - PERIAPSIS).abs() < 1e-15
);Sourcefn get_time_of_apoapsis(&self) -> f64
fn get_time_of_apoapsis(&self) -> f64
Gets the time when the orbit is in apoapsis, in seconds since epoch.
This returns the time when mean anomaly equals pi.
This means although it will represent a time of apoapsis,
it doesn’t mean “next apoapsis” nor “previous apoapsis”,
it just means “an apoapsis”, at least for closed orbits
(e < 1).
§Performance
This function is performant and is unlikely to be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
const APOAPSIS: f64 = 2.0;
const PERIAPSIS: f64 = 1.0;
let orbit = Orbit2D::with_apoapsis(
APOAPSIS,
PERIAPSIS,
2.9, // Argument of periapsis
1.5, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
let time_of_ap = orbit.get_time_of_apoapsis();
let alt_of_ap = orbit.get_altitude_at_time(time_of_ap);
assert!(
(alt_of_ap - APOAPSIS).abs() < 1e-15
);Sourcefn get_pqw_basis_vectors(&self) -> (DVec2, DVec2)
fn get_pqw_basis_vectors(&self) -> (DVec2, DVec2)
Gets the basis vectors for the perifocal coordinate (PQW) system.
§Output
This function returns a tuple of two vectors. The vectors are the p and q basis vectors, respectively.
The p basis vector is a unit vector that points to the periapsis.
The q basis vector is orthogonal to that and points 90° counterclockwise
from the periapsis on the orbital plane.
The w basis vector is orthogonal to the XY plane and is
excluded from this function’s output.
For more information about the PQW system, visit the Wikipedia article.
§Performance
For CompactOrbit2D, this will perform a few trigonometric operations
and therefore is not too performant.
For Orbit2D, this will only need to access the cache, and
therefore is much more performant.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let orbit = Orbit2D::default();
let (p, q) = orbit.get_pqw_basis_vectors();
assert_eq!(p, DVec2::X);
assert_eq!(q, DVec2::Y);Sourcefn get_eccentricity_vector(&self) -> DVec2
fn get_eccentricity_vector(&self) -> DVec2
Gets the eccentricity vector of this orbit.
The eccentricity vector of a Kepler orbit is the dimensionless vector with direction pointing from apoapsis to periapsis and with magnitude equal to the orbit’s scalar eccentricity.
§Performance
This function is significantly faster in the cached version of the
orbit struct (Orbit2D) than the compact version (CompactOrbit2D).
Consider using the cached version if this function will be called often.
Alternatively, if you want to keep using the compact version and know
the periapsis unit vector, use the unchecked version:
get_eccentricity_vector_unchecked
The cached version only needs to do a lookup, and therefore is very performant.
The compact version computes one trig operation, and therefore is slightly less performant.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
// Parabolic orbit (e = 1)
let orbit = Orbit2D::new(1.0, 1.0, 0.0, 0.0, 1.0);
let eccentricity_vector = orbit.get_eccentricity_vector();
assert_eq!(
eccentricity_vector,
DVec2::X
);Sourcefn get_eccentricity_vector_unchecked(&self, p_vector: DVec2) -> DVec2
fn get_eccentricity_vector_unchecked(&self, p_vector: DVec2) -> DVec2
Gets the eccentricity vector of this orbit.
The eccentricity vector of a Kepler orbit is the dimensionless vector with direction pointing from apoapsis to periapsis and with magnitude equal to the orbit’s scalar eccentricity.
§Unchecked Operation
This function does not check for the validity of the given P basis vector. The given P vector should be of length 1.
It is expected that callers get this basis vector
from either the transformation matrix or the
get_pqw_basis_vectors
function.
If the given P vector is not of length 1, you may get nonsensical outputs.
§Performance
This function, by itself, is very performant, and should not be the cause of any performance problems.
However, for the cached orbit struct (Orbit2D), this function
has the same performance as the safer
get_eccentricity_vector
function. There should be no need to use this function if you are
using the cached orbit struct.
§Example
use keplerian_sim::{CompactOrbit2D, OrbitTrait2D};
use glam::DVec2;
// Parabolic orbit (e = 1)
let orbit = CompactOrbit2D::new(1.0, 1.0, 0.0, 0.0, 1.0);
// Expensive op for compact orbit: get basis vectors
let basis_vectors = orbit.get_pqw_basis_vectors();
// Use basis vectors for something...
assert_eq!(
basis_vectors,
(DVec2::X, DVec2::Y)
);
// You can reuse it here! No need to recompute (as long as
// orbit hasn't changed)
let eccentricity_vector = orbit.get_eccentricity_vector_unchecked(
// basis vectors: P, Q, and W; we get the first one (0th index)
basis_vectors.0
);
assert_eq!(
eccentricity_vector,
DVec2::X
);Sourcefn get_eccentric_anomaly_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
fn get_eccentric_anomaly_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
Gets the eccentric anomaly at a given mean anomaly in the orbit.
When the orbit is open (has an eccentricity of at least 1), the hyperbolic eccentric anomaly would be returned instead.
§Parabolic Support
This function doesn’t yet support parabolic trajectories. It may return NaNs
or nonsensical values in this case.
§Performance
The method to get the eccentric anomaly from the mean anomaly
uses numerical approach methods, and so it is not performant.
It is recommended to cache this value if you can.
The eccentric anomaly is an angular parameter that defines the position of a body that is moving along an elliptic Kepler orbit.
Sourcefn get_approx_hyperbolic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64
fn get_approx_hyperbolic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64
Get an initial guess for the hyperbolic eccentric anomaly of an orbit.
§Performance
This function uses plenty of floating-point operations, including divisions, natural logarithms, squareroots, and cuberoots, and thus it is not very performant.
§Unchecked Operation
This function does not check whether or not the orbit is hyperbolic. If this function is called on a non-hyperbolic orbit (i.e., elliptic or parabolic), invalid values may be returned.
§Approximate Guess
This function returns a “good” initial guess for the hyperbolic eccentric anomaly.
There are no constraints on the accuracy of the guess, and users may not
rely on this value being very accurate, especially in some edge cases.
§Source
From the paper:
“A new method for solving the hyperbolic Kepler equation”
by Baisheng Wu et al.
Quote:
“we divide the hyperbolic eccentric anomaly interval into two parts:
a finite interval and an infinite interval. For the finite interval,
we apply a piecewise Pade approximation to establish an initial
approximate solution of HKE. For the infinite interval, an analytical
initial approximate solution is constructed.”
Sourcefn get_hyperbolic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64
fn get_hyperbolic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64
Gets the hyperbolic eccentric anomaly of the orbit.
§Unchecked Operation
This function does not check whether or not the orbit is actually hyperbolic.
Nonsensical output may be produced if the orbit is not hyperbolic, but rather
elliptic or parabolic.
§Performance
This function uses numerical methods to approach the value and therefore is not performant. It is recommended to cache this value if you can.
§Source
From the paper:
“A new method for solving the hyperbolic Kepler equation”
by Baisheng Wu et al.
Sourcefn get_elliptic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64
fn get_elliptic_eccentric_anomaly(&self, mean_anomaly: f64) -> f64
Gets the elliptic eccentric anomaly of the orbit.
§Unchecked Operation
This function does not check whether or not the orbit is actually elliptic (e < 1).
Nonsensical output may be produced if the orbit is not elliptic, but rather
hyperbolic or parabolic.
§Performance
This function uses numerical methods to approach the value and therefore is not performant. It is recommended to cache this value if you can.
§Source
From the paper
“An improved algorithm due to laguerre for the solution of Kepler’s equation.”
by Bruce A. Conway
https://doi.org/10.1007/bf01230852
Sourcefn get_eccentric_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64
fn get_eccentric_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64
Gets the eccentric anomaly at a given true anomaly in the orbit.
When the orbit is open (has an eccentricity of at least 1), the hyperbolic eccentric anomaly would be returned instead.
The eccentric anomaly is an angular parameter that defines the position of a body that is moving along an elliptic Kepler orbit.
§Parabolic Support
This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.
§Performance
The method to get the eccentric anomaly from the true anomaly
uses a few trigonometry operations, and so it is not too performant.
It is, however, faster than the numerical approach methods used by
the mean anomaly to eccentric anomaly conversion.
It is still recommended to cache this value if you can.
Sourcefn get_eccentric_anomaly_at_time(&self, time: f64) -> f64
fn get_eccentric_anomaly_at_time(&self, time: f64) -> f64
Gets the eccentric anomaly at a given time in the orbit.
When the orbit is open (has an eccentricity of at least 1), the hyperbolic eccentric anomaly would be returned instead.
The eccentric anomaly is an angular parameter that defines the position of a body that is moving along an elliptic Kepler orbit.
§Time
The time is expressed in seconds.
§Performance
The method to get the eccentric anomaly from the time
uses numerical approach methods, and so it is not performant.
It is recommended to cache this value if you can.
Sourcefn get_true_anomaly_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
fn get_true_anomaly_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
Gets the true anomaly at a given eccentric anomaly in the orbit.
This function is faster than the function which takes mean anomaly as input, as the eccentric anomaly is hard to calculate.
This function returns +/- pi for parabolic orbits due to how the equation works, and so may result in infinities when combined with other functions.
The true anomaly is the angle between the direction of periapsis and the current position of the body, as seen from the main focus of the ellipse.
§Performance
This function is faster than the function which takes mean anomaly as input,
as the eccentric anomaly is hard to calculate.
However, this function still uses a few trigonometric functions, so it is
not too performant.
It is recommended to cache this value if you can.
Sourcefn get_true_anomaly_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
fn get_true_anomaly_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
Gets the true anomaly at a given mean anomaly in the orbit.
This function returns +/- pi for parabolic orbits due to how the equation works, and so may result in infinities when combined with other functions.
The true anomaly is the angle between the direction of periapsis and the current position of the body, as seen from the main focus of the ellipse.
§Performance
The true anomaly is derived from the eccentric anomaly, which
uses numerical approach methods and so is not performant.
It is recommended to cache this value if you can.
Alternatively, if you already know the eccentric anomaly, you should use
get_true_anomaly_at_eccentric_anomaly
instead.
Sourcefn get_true_anomaly_at_time(&self, time: f64) -> f64
fn get_true_anomaly_at_time(&self, time: f64) -> f64
Gets the true anomaly at a given time in the orbit.
The true anomaly is the angle between the direction of periapsis and the current position of the body, as seen from the main focus of the ellipse.
This function returns +/- pi for parabolic orbits due to how the equation works, and so may result in infinities when combined with other functions.
§Time
The time is expressed in seconds.
§Performance
The true anomaly is derived from the eccentric anomaly, which
uses numerical approach methods and so is not performant.
It is recommended to cache this value if you can.
Alternatively, if you already know the eccentric anomaly, you should use
get_true_anomaly_at_eccentric_anomaly
instead.
If you already know the mean anomaly, consider using
get_true_anomaly_at_mean_anomaly
instead.
It won’t help performance much, but it’s not zero.
Sourcefn get_true_anomaly_at_altitude(&self, altitude: f64) -> f64
fn get_true_anomaly_at_altitude(&self, altitude: f64) -> f64
Gets the true anomaly where a certain altitude is reached.
Returns NaN if the orbit is circular or there are no solutions.
§Altitude
The altitude is measured in meters, and measured from the center of the parent body (origin).
The altitude given to this function should be between
the periapsis (minimum) and the apoapsis (maximum).
Anything out of range will return NaN.
In the case of hyperbolic orbits, there is no maximum,
but the altitude should be positive and more than the periapsis.
Although there technically is a mathematical solution for “negative altitudes”
between negative infinity and the apoapsis (which in this case is negative),
they may not be very useful in most scenarios.
§Domain
This function returns a float between 0 and π, unless if
it returns NaN.
Do note that, although this is the principal solution,
other solutions exist, and may be desired. There exists an
alternate solution when you negate the principal solution,
and the solutions repeat every 2π.
§Example
If there is a principal solution at 1, that means there
is an alternate solution at -1, and there are also
solutions 2π + 1, 2π - 1, 4π + 1, 4π - 1, etc.
§Performance
This function is moderately performant and is unlikely to be the culprit of any performance issues.
However, if you already computed the semi-latus rectum or the
reciprocal of the eccentricity, you may use the unchecked version
of this function for a small performance boost:
get_true_anomaly_at_altitude_unchecked
Sourcefn get_true_anomaly_at_altitude_unchecked(
&self,
semi_latus_rectum: f64,
altitude: f64,
eccentricity_recip: f64,
) -> f64
fn get_true_anomaly_at_altitude_unchecked( &self, semi_latus_rectum: f64, altitude: f64, eccentricity_recip: f64, ) -> f64
Gets the true anomaly where a certain altitude is reached.
Returns NaN if the orbit is circular or there are no solutions.
§Altitude
The altitude is measured in meters, and measured from the center of the parent body (origin).
The altitude given to this function should be between
the periapsis (minimum) and the apoapsis (maximum).
Anything out of range will return NaN.
In the case of hyperbolic orbits, there is no maximum,
but the altitude should be positive and more than the periapsis.
Although there technically is a mathematical solution for “negative altitudes”
between negative infinity and the apoapsis (which in this case is negative),
they may not be very useful in most scenarios.
§Unchecked Operation
This function does not check the validity of the inputted values. Nonsensical/invalid inputs may result in nonsensical/invalid outputs.
§Domain
This function returns a float between 0 and π, unless if
it returns NaN.
Do note that, although this is the principal solution,
other solutions exist, and may be desired. There exists an
alternate solution when you negate the principal solution,
and the solutions repeat every 2π.
§Example
If there is a principal solution at 1, that means there
is an alternate solution at -1, and there are also
solutions 2π + 1, 2π - 1, 4π + 1, 4π - 1, etc.
§Performance
This function is moderately performant and is unlikely to be the culprit of any performance issues.
Sourcefn get_mean_anomaly_at_time(&self, time: f64) -> f64
fn get_mean_anomaly_at_time(&self, time: f64) -> f64
Gets the mean anomaly at a given time in the orbit.
The mean anomaly is the fraction of an elliptical orbit’s period that has elapsed since the orbiting body passed periapsis, expressed as an angle which can be used in calculating the position of that body in the classical two-body problem.
§Time
The time is expressed in seconds.
§Performance
This function is performant and is unlikely to be the culprit of any performance issues.
Sourcefn get_mean_anomaly_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
fn get_mean_anomaly_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
Gets the mean anomaly at a given eccentric anomaly in the orbit.
The mean anomaly is the fraction of an elliptical orbit’s period that has elapsed since the orbiting body passed periapsis, expressed as an angle which can be used in calculating the position of that body in the classical two-body problem.
§Parabolic Support
This function doesn’t consider parabolic trajectories yet.
NaNs or nonsensical values may be returned.
§Performance
This function is a wrapper around
get_mean_anomaly_at_elliptic_eccentric_anomaly
and
get_mean_anomaly_at_hyperbolic_eccentric_anomaly.
It does some trigonometry, but if you know sin(eccentric_anomaly) or sinh(eccentric_anomaly)
beforehand, this can be skipped by directly using those inner functions.
Sourcefn get_mean_anomaly_at_elliptic_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
sin_eccentric_anomaly: f64,
) -> f64
fn get_mean_anomaly_at_elliptic_eccentric_anomaly( &self, eccentric_anomaly: f64, sin_eccentric_anomaly: f64, ) -> f64
Gets the mean anomaly at a given eccentric anomaly in the orbit and its precomputed sine.
The mean anomaly is the fraction of an elliptical orbit’s period that has elapsed since the orbiting body passed periapsis, expressed as an angle which can be used in calculating the position of that body in the classical two-body problem.
§Unchecked Operation
This function does no checks on the validity of the value given
as sin_eccentric_anomaly. It also doesn’t check if the orbit is elliptic.
If invalid values are passed in, you will receive a possibly-nonsensical value as output.
§Performance
This function is performant and is unlikely to be the culprit of any performance issues.
Sourcefn get_mean_anomaly_at_hyperbolic_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
sinh_eccentric_anomaly: f64,
) -> f64
fn get_mean_anomaly_at_hyperbolic_eccentric_anomaly( &self, eccentric_anomaly: f64, sinh_eccentric_anomaly: f64, ) -> f64
Gets the mean anomaly at a given eccentric anomaly in the orbit and its precomputed sine.
The mean anomaly is the fraction of an elliptical orbit’s period that has elapsed since the orbiting body passed periapsis, expressed as an angle which can be used in calculating the position of that body in the classical two-body problem.
§Unchecked Operation
This function does no checks on the validity of the value given
as sinh_eccentric_anomaly. It also doesn’t check if the orbit is hyperbolic.
If invalid values are passed in, you will receive a possibly-nonsensical value as output.
§Performance
This function is performant and is unlikely to be the culprit of any performance issues.
Sourcefn get_mean_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64
fn get_mean_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64
Gets the mean anomaly at a given true anomaly in the orbit.
The mean anomaly is the fraction of an elliptical orbit’s period that has elapsed since the orbiting body passed periapsis, expressed as an angle which can be used in calculating the position of that body in the classical two-body problem.
§Performance
The method to get the eccentric anomaly from the true anomaly
uses a few trigonometry operations, and so it is not too performant.
It is, however, faster than the numerical approach methods used by
the mean anomaly to eccentric anomaly conversion.
It is still recommended to cache this value if you can.
Alternatively, if you already know the eccentric anomaly, use
get_mean_anomaly_at_eccentric_anomaly
instead.
Sourcefn get_position_at_true_anomaly(&self, angle: f64) -> DVec2
fn get_position_at_true_anomaly(&self, angle: f64) -> DVec2
Gets the position at a given angle (true anomaly) in the orbit.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Performance
This function is somewhat performant.
This function benefits significantly from being in the cached version of the orbit struct.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_true_anomaly
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
If you only want to get the altitude of the orbit, you can use the
get_altitude_at_true_anomaly
function instead.
If you already know the altitude at the angle, you can
rotate the altitude using the true anomaly, then tilt
it using the transform_pqw_vector
function instead.
§Example
use glam::DVec2;
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
let pos = orbit.get_position_at_true_anomaly(0.0);
assert_eq!(pos, DVec2::new(100.0, 0.0));Sourcefn get_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
fn get_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
Gets the position at a given eccentric anomaly in the orbit.
§Performance
This function benefits significantly from being in the
cached version of the orbit struct.
This function is not too performant as it uses a few trigonometric
operations. It is recommended to cache this value if you can.
Alternatively, if you already know the true anomaly, you can use the
get_position_at_true_anomaly
function instead.
Or, if you only need the altitude, use the
get_altitude_at_eccentric_anomaly
function instead.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_eccentric_anomaly
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
Sourcefn get_speed_at_true_anomaly(&self, angle: f64) -> f64
fn get_speed_at_true_anomaly(&self, angle: f64) -> f64
Gets the speed at a given angle (true anomaly) in the orbit.
The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Angle
The angle is expressed in radians, and ranges from 0 to tau. Anything out of range will get wrapped around.
§Performance
This function is performant, however, if you already know the altitude at the angle,
you can use the get_speed_at_altitude
function instead to skip some calculations.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let speed_periapsis = orbit.get_speed_at_true_anomaly(0.0);
let speed_apoapsis = orbit.get_speed_at_true_anomaly(std::f64::consts::PI);
assert!(speed_periapsis > speed_apoapsis);Sourcefn get_speed_at_altitude(&self, altitude: f64) -> f64
fn get_speed_at_altitude(&self, altitude: f64) -> f64
Gets the speed at a given altitude in the orbit.
The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Unchecked Operation
This function does no checks on the validity of the value given
in the altitude parameter, namely whether or not this altitude
is possible in the given orbit.
If invalid values are passed in, you will receive a possibly-nonsensical
value as output.
§Altitude
The altitude is expressed in meters, and is the distance to the center of the orbit.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
const PERIAPSIS: f64 = 100.0;
let mut orbit = Orbit2D::default();
orbit.set_periapsis(PERIAPSIS);
orbit.set_eccentricity(0.5);
let apoapsis = orbit.get_apoapsis();
let speed_periapsis = orbit.get_speed_at_altitude(PERIAPSIS);
let speed_apoapsis = orbit.get_speed_at_altitude(apoapsis);
assert!(speed_periapsis > speed_apoapsis);Sourcefn get_speed_at_periapsis(&self) -> f64
fn get_speed_at_periapsis(&self) -> f64
Gets the speed at the periapsis of the orbit.
The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
const PERIAPSIS: f64 = 100.0;
let mut orbit = Orbit2D::default();
orbit.set_periapsis(PERIAPSIS);
orbit.set_eccentricity(0.5);
let naive_getter = orbit.get_speed_at_altitude(PERIAPSIS);
let dedicated_getter = orbit.get_speed_at_periapsis();
assert!((naive_getter - dedicated_getter).abs() < 1e-14);Sourcefn get_speed_at_apoapsis(&self) -> f64
fn get_speed_at_apoapsis(&self) -> f64
Gets the speed at the apoapsis of the orbit.
The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Open orbits (eccentricity >= 1)
This function does not handle open orbits specially, and will return
a non-physical value. You might want to use the getter for the speed
at infinity:
get_speed_at_infinity
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
const APOAPSIS: f64 = 200.0;
const PERIAPSIS: f64 = 100.0;
let orbit = Orbit2D::with_apoapsis(
APOAPSIS,
PERIAPSIS,
0.0, // Argument of periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
let naive_getter = orbit.get_speed_at_altitude(APOAPSIS);
let dedicated_getter = orbit.get_speed_at_apoapsis();
assert!((naive_getter - dedicated_getter).abs() < 1e-14);Sourcefn get_speed_at_infinity(&self) -> f64
fn get_speed_at_infinity(&self) -> f64
Gets the hyperbolic excess speed (v_∞) of the trajectory.
Under simplistic assumptions a body traveling along [a hyperbolic] trajectory will coast towards infinity, settling to a final excess velocity relative to the central body.
In other words, as the time of a hyperbolic trajectory approaches infinity, the speed approaches a certain speed, called the hyperbolic excess speed.
§Unchecked Operation
This function does not check that the orbit is open.
This function will return NaN for closed orbits (e < 1).
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let orbit = Orbit2D::new(
1.0, // Eccentricity
1.0, // Periapsis
0.0, // Argument of periapsis
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
assert_eq!(orbit.get_speed_at_infinity(), 0.0);Sourcefn get_speed_at_time(&self, time: f64) -> f64
fn get_speed_at_time(&self, time: f64) -> f64
Gets the speed at a given time in the orbit.
§Time
The time is expressed in seconds.
§Performance
The time will be converted into an eccentric anomaly, which uses numerical methods and so is not very performant. It is recommended to cache this value if you can.
Alternatively, if you know the eccentric anomaly or the true anomaly,
then you should use the
get_speed_at_eccentric_anomaly
and
get_speed_at_true_anomaly
functions instead.
Those do not use numerical methods and therefore are a lot faster.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_speed_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
fn get_speed_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
Gets the speed at a given eccentric anomaly in the orbit.
The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Performance
This function is not too performant as it uses a few trigonometric
operations.
It is recommended to cache this value if you can.
Alternatively, if you already know the true anomaly,
then you should use the
get_speed_at_true_anomaly
function instead.
Sourcefn get_speed_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
fn get_speed_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
Gets the speed at a given mean anomaly in the orbit.
§Performance
The time will be converted into an eccentric anomaly, which uses numerical methods and so is not very performant. It is recommended to cache this value if you can.
Alternatively, if you know the eccentric anomaly or the true anomaly,
then you should use the
get_speed_at_eccentric_anomaly
and
get_speed_at_true_anomaly
functions instead.
Those do not use numerical methods and therefore are a lot faster.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_pqw_velocity_at_true_anomaly(&self, angle: f64) -> DVec2
fn get_pqw_velocity_at_true_anomaly(&self, angle: f64) -> DVec2
Gets the velocity at a given angle (true anomaly) in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_true_anomaly instead.
§Performance
This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_true_anomaly instead.
And if you already know the eccentric anomaly, use
get_pqw_velocity_at_eccentric_anomaly
instead.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let vel_periapsis = orbit.get_pqw_velocity_at_true_anomaly(0.0);
let vel_apoapsis = orbit.get_pqw_velocity_at_true_anomaly(std::f64::consts::PI);
let speed_periapsis = vel_periapsis.length();
let speed_apoapsis = vel_apoapsis.length();
assert!(speed_periapsis > speed_apoapsis);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_pqw_velocity_at_periapsis(&self) -> DVec2
fn get_pqw_velocity_at_periapsis(&self) -> DVec2
Gets the velocity at the periapsis of the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_periapsis instead.
§Performance
This function is very performant and should not be the cause of any performance issues.
Alternatively, if you only want to know the speed, use
get_speed_at_periapsis instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let vel = orbit.get_pqw_velocity_at_periapsis();
assert_eq!(
vel,
DVec2::new(0.0, orbit.get_speed_at_periapsis())
);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_pqw_velocity_at_apoapsis(&self) -> DVec2
fn get_pqw_velocity_at_apoapsis(&self) -> DVec2
Gets the velocity at the apoapsis of the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_apoapsis instead.
§Open orbits (eccentricity >= 1)
This function does not handle open orbits specially, and will return a non-physical value. You might want to use the getters for the velocity at the incoming and outgoing asymptotes:
§Performance
This function is very performant and should not be the cause of any performance issues.
Alternatively, if you only want to know the speed, use
get_speed_at_apoapsis instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let vel = orbit.get_pqw_velocity_at_apoapsis();
assert_eq!(
vel,
DVec2::new(0.0, -orbit.get_speed_at_apoapsis())
);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_pqw_velocity_at_incoming_asymptote(&self) -> DVec2
fn get_pqw_velocity_at_incoming_asymptote(&self) -> DVec2
Gets the velocity at the incoming asymptote of the trajectory in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_incoming_asymptote
instead.
§Unchecked Operation
This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).
§Performance
This function is very performant and should not be the cause of any performance issues.
Alternatively, if you only want to know the speed, use
get_speed_at_infinity instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);
let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_pqw_velocity_at_incoming_asymptote();
assert!((vel.length() - speed).abs() < 1e-15);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_pqw_velocity_at_outgoing_asymptote(&self) -> DVec2
fn get_pqw_velocity_at_outgoing_asymptote(&self) -> DVec2
Gets the velocity at the outgoing asymptote of the trajectory in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_outgoing_asymptote
instead.
§Unchecked Operation
This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).
§Performance
This function is very performant and should not be the cause of any performance issues.
Alternatively, if you only want to know the speed, use
get_speed_at_infinity instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
use glam::DVec2;
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);
let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_pqw_velocity_at_outgoing_asymptote();
assert!((vel.length() - speed).abs() < 1e-15);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_pqw_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
fn get_pqw_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
Gets the velocity at a given eccentric anomaly in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_eccentric_anomaly instead.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Parabolic Support
This function doesn’t consider parabolic trajectories yet.
NaNs or parabolic trajectories may be returned.
§Performance
This function is not too performant as it uses some trigonometric
operations.
It is recommended to cache this value if you can.
If you want to just get the speed, consider using the
get_speed_at_eccentric_anomaly
function instead.
Alternatively, if you already know some values (such as the altitude), consider
using the unchecked version of the function instead:
get_pqw_velocity_at_eccentric_anomaly_unchecked
Sourcefn get_pqw_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2
fn get_pqw_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2
Gets the velocity at a given mean anomaly in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_mean_anomaly instead.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Parabolic Support
This function doesn’t consider parabolic trajectories yet.
NaNs or parabolic trajectories may be returned.
§Performance
This method involves converting the mean anomaly into an eccentric anomaly,
which uses numerical methods and so is not performant.
It is recommended to cache this value if you can.
If you want to just get the speed, consider using the
get_speed_at_mean_anomaly
function instead.
Alternatively, if you already know the eccentric anomaly or true anomaly values,
use the
get_pqw_velocity_at_eccentric_anomaly
and
get_pqw_velocity_at_true_anomaly
functions instead.
Those functions do not use numerical methods and are therefore a lot faster.
Sourcefn get_pqw_velocity_at_eccentric_anomaly_unchecked(
&self,
outer_mult: f64,
q_mult: f64,
trig_ecc_anom: (f64, f64),
) -> DVec2
fn get_pqw_velocity_at_eccentric_anomaly_unchecked( &self, outer_mult: f64, q_mult: f64, trig_ecc_anom: (f64, f64), ) -> DVec2
Gets the velocity at a given eccentric anomaly in the orbit in the perifocal coordinate system.
§Unchecked Operation
This function does not check the validity of the
inputs passed to this function.
It is your responsibility to make sure the inputs passed in are valid.
Failing to do so may result in nonsensical outputs.
§Parameters
§outer_mult
This parameter is a multiplier for the entire 2D vector.
If the orbit is elliptic (e < 1), it should be calculated by
the formula sqrt(GM * a) / r, where GM is the gravitational
parameter, a is the semi-major axis, and r is the altitude of
the orbit at that point.
If the orbit is hyperbolic (e > 1), it should instead be calculated by
the formula sqrt(-GM * a) / r.
For the general case, the formula sqrt(abs(GM * a)) / r can be used instead.
§q_mult
This parameter is a multiplier for the second element in the PQW vector.
For elliptic orbits, it should be calculated by the formula sqrt(1 - e^2),
where e is the eccentricity of the orbit.
For hyperbolic orbits, it should be calculated by the formula sqrt(e^2 - 1),
where e is the eccentricity of the orbit.
Alternatively, for the general case, you can use the formula sqrt(abs(1 - e^2)).
§trig_ecc_anom
For elliptic orbits, this parameter should be a tuple containing the sine and cosine
values of the eccentric anomaly, respectively.
For hyperbolic orbits, this parameter should be a tuple containing the hyperbolic
sine and hyperbolic cosine values of the eccentric anomaly, respectively.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
You can convert from the PQW system to the regular 2D space using
transform_pqw_vector.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Parabolic Support
This function doesn’t consider parabolic trajectories yet.
NaNs or parabolic trajectories may be returned.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D, sinhcosh};
let orbit = Orbit2D::default();
let eccentric_anomaly: f64 = 1.25;
let pqw_vel = orbit.get_pqw_velocity_at_eccentric_anomaly(eccentric_anomaly);
let gm = orbit.get_gravitational_parameter();
let a = orbit.get_semi_major_axis();
let altitude = orbit.get_altitude_at_eccentric_anomaly(eccentric_anomaly);
let outer_mult = (gm * a).sqrt() / altitude;
let q_mult = (1.0 - orbit.get_eccentricity().powi(2)).sqrt();
let trig_ecc_anom = eccentric_anomaly.sin_cos();
let pqw_vel_2 = orbit
.get_pqw_velocity_at_eccentric_anomaly_unchecked(outer_mult, q_mult, trig_ecc_anom);
assert_eq!(pqw_vel, pqw_vel_2);
}use keplerian_sim::{Orbit2D, OrbitTrait2D, sinhcosh};
let mut hyperbolic = Orbit2D::default();
hyperbolic.set_eccentricity(3.0);
let eccentric_anomaly: f64 = 2.35;
let pqw_vel = hyperbolic.get_pqw_velocity_at_eccentric_anomaly(eccentric_anomaly);
let gm = hyperbolic.get_gravitational_parameter();
let a = hyperbolic.get_semi_major_axis();
let altitude = hyperbolic.get_altitude_at_eccentric_anomaly(eccentric_anomaly);
let outer_mult = (-gm * a).sqrt() / altitude;
let q_mult = (hyperbolic.get_eccentricity().powi(2) - 1.0).sqrt();
let trig_ecc_anom = sinhcosh(eccentric_anomaly);
let pqw_vel_2 = hyperbolic
.get_pqw_velocity_at_eccentric_anomaly_unchecked(outer_mult, q_mult, trig_ecc_anom);
assert_eq!(pqw_vel, pqw_vel_2);Sourcefn get_pqw_velocity_at_time(&self, time: f64) -> DVec2
fn get_pqw_velocity_at_time(&self, time: f64) -> DVec2
Gets the velocity at a given time in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_velocity_at_time instead.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Time
The time is expressed in seconds.
§Performance
This method involves converting the time into an eccentric anomaly,
which uses numerical methods and so is not performant.
It is recommended to cache this value if you can.
Alternatively, if you already know the eccentric anomaly or the true anomaly,
then you should use the
get_pqw_velocity_at_eccentric_anomaly
and
get_pqw_velocity_at_true_anomaly
functions instead.
Those do not use numerical methods and therefore are a lot faster.
Sourcefn get_pqw_position_at_true_anomaly(&self, angle: f64) -> DVec2
fn get_pqw_position_at_true_anomaly(&self, angle: f64) -> DVec2
Gets the position at a given angle (true anomaly) in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_position_at_true_anomaly instead.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Performance
This function is somewhat performant. However, if you already know
the altitude beforehand, you might be interested in the unchecked
version of this function:
get_pqw_position_at_true_anomaly_unchecked
If you’re looking to just get the altitude at a given angle,
consider using the get_altitude_at_true_anomaly
function instead.
§Example
use glam::DVec2;
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.0);
let pos = orbit.get_pqw_position_at_true_anomaly(0.0);
assert_eq!(pos, DVec2::new(100.0, 0.0));Sourcefn get_pqw_position_at_true_anomaly_unchecked(
&self,
altitude: f64,
sincos_angle: (f64, f64),
) -> DVec2
fn get_pqw_position_at_true_anomaly_unchecked( &self, altitude: f64, sincos_angle: (f64, f64), ) -> DVec2
Gets the position at a certain point in the orbit in the perifocal coordinate system.
§Unchecked Operation
This function does not check on the validity of the parameters.
Invalid values may lead to nonsensical results.
§Parameters
§altitude
The altitude at that certain point in the orbit.
The altitude is measured in meters, and measured from the
center of the parent body (origin).
§sincos_angle
A tuple containing the sine and cosine (respectively) of the true anomaly of the point in the orbit.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
To convert from the PQW coordinates to regular 2D space, use the
transform_pqw_vector function.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Performance
This function is very performant and should not be the cause of any performance issues.
§Example
use glam::DVec2;
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.0);
let true_anomaly = 1.06;
let pos = orbit.get_pqw_position_at_true_anomaly(true_anomaly);
let altitude = orbit.get_altitude_at_true_anomaly(true_anomaly);
let sincos_angle = true_anomaly.sin_cos();
let pos2 = orbit.get_pqw_position_at_true_anomaly_unchecked(altitude, sincos_angle);
assert_eq!(pos, pos2);Sourcefn get_pqw_position_at_time(&self, time: f64) -> DVec2
fn get_pqw_position_at_time(&self, time: f64) -> DVec2
Gets the position at a given time in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_position_at_time instead.
§Time
The time is expressed in seconds.
§Parabolic Support
This function returns non-finite numbers for parabolic orbits due to how the equation for true anomaly works.
§Performance
This involves calculating the true anomaly at a given time, and so is not performant. It is recommended to cache this value when possible.
Alternatively, if you already know the eccentric anomaly or the true anomaly,
consider using the
get_pqw_position_at_eccentric_anomaly
and
get_pqw_position_at_true_anomaly
functions instead.
Those do not use numerical methods and therefore are a lot faster.
If you only want to get the altitude of the orbit, you can use the
get_altitude_at_time
function instead.
Sourcefn get_pqw_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
fn get_pqw_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
Gets the position at a given eccentric anomaly in the orbit in the perifocal coordinate system.
§Perifocal Coordinate System
This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.
Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
If you want to get the vector in the regular coordinate system instead, use
get_position_at_eccentric_anomaly instead.
§Time
The time is expressed in seconds.
§Parabolic Support
This function returns non-finite numbers for parabolic orbits due to how the equation for true anomaly works.
§Performance
This function is not too performant as it uses a few trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you already know the true anomaly,
consider using the
get_pqw_position_at_true_anomaly
function instead.
Sourcefn get_velocity_at_true_anomaly(&self, angle: f64) -> DVec2
fn get_velocity_at_true_anomaly(&self, angle: f64) -> DVec2
Gets the velocity at a given angle (true anomaly) in the orbit.
§Performance
This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_true_anomaly instead.
Or, if you already have the eccentric anomaly, use
get_velocity_at_eccentric_anomaly
instead.
These functions do less work and therefore are a lot faster.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_true_anomaly
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let vel_periapsis = orbit.get_velocity_at_true_anomaly(0.0);
let vel_apoapsis = orbit.get_velocity_at_true_anomaly(std::f64::consts::PI);
let speed_periapsis = vel_periapsis.length();
let speed_apoapsis = vel_apoapsis.length();
assert!(speed_periapsis > speed_apoapsis)§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_velocity_at_periapsis(&self) -> DVec2
fn get_velocity_at_periapsis(&self) -> DVec2
Gets the velocity at the periapsis of the orbit.
§Performance
This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_periapsis instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let speed = orbit.get_speed_at_periapsis();
let vel = orbit.get_velocity_at_periapsis();
assert!((vel.length() - speed).abs() < 1e-15);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_velocity_at_apoapsis(&self) -> DVec2
fn get_velocity_at_apoapsis(&self) -> DVec2
Gets the velocity at the apoapsis of the orbit.
§Performance
This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_apoapsis instead.
§Open orbits (eccentricity >= 1)
This function does not handle open orbits specially, and will return a non-physical value. You might want to use the getters for the velocity at the incoming and outgoing asymptotes:
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let speed = orbit.get_speed_at_apoapsis();
let vel = orbit.get_velocity_at_apoapsis();
assert!((vel.length() - speed).abs() < 1e-15);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_velocity_at_incoming_asymptote(&self) -> DVec2
fn get_velocity_at_incoming_asymptote(&self) -> DVec2
Gets the velocity at the incoming asymptote of the trajectory.
§Performance
This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_infinity instead.
§Unchecked Operation
This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);
let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_velocity_at_incoming_asymptote();
assert!((vel.length() - speed).abs() < 1e-15);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_velocity_at_outgoing_asymptote(&self) -> DVec2
fn get_velocity_at_outgoing_asymptote(&self) -> DVec2
Gets the velocity at the outgoing asymptote of the trajectory.
§Performance
This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_infinity instead.
§Unchecked Operation
This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);
let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_velocity_at_outgoing_asymptote();
assert!((vel.length() - speed).abs() < 1e-15);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
fn get_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec2
Gets the velocity at a given eccentric anomaly in the orbit.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let vel_periapsis = orbit.get_velocity_at_true_anomaly(0.0);
let vel_apoapsis = orbit.get_velocity_at_true_anomaly(std::f64::consts::PI);§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Performance
This function is not too performant as it uses a few trigonometric
operations.
It is recommended to cache this value if you can.
Alternatively, if you just want to get the speed, consider using the
get_speed_at_eccentric_anomaly
function instead.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_eccentric_anomaly
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
This function benefits significantly from being in the cached version of the orbit struct.
Sourcefn get_velocity_at_time(&self, time: f64) -> DVec2
fn get_velocity_at_time(&self, time: f64) -> DVec2
Gets the velocity at a given time in the orbit.
§Time
The time is expressed in seconds.
§Performance
The velocity is derived from the eccentric anomaly, which uses numerical
methods and so is not performant.
It is recommended to cache this value if you can.
Alternatively, if you only want to know the speed, use
get_speed_at_time instead.
Or, if you already have the eccentric anomaly or true anomaly, use the
get_velocity_at_eccentric_anomaly
and
get_velocity_at_true_anomaly
functions instead.
These functions do not require numerical methods and therefore are a lot faster.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_time
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
Sourcefn get_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2
fn get_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2
Gets the velocity at a given mean anomaly in the orbit.
§Speed vs. Velocity
Speed is not to be confused with velocity.
Speed tells you how fast something is moving,
while velocity tells you how fast and in what direction it’s moving in.
§Parabolic Support
This function doesn’t consider parabolic trajectories yet.
NaNs or parabolic trajectories may be returned.
§Performance
This method involves converting the mean anomaly into an eccentric anomaly,
which uses numerical methods and so is not performant.
It is recommended to cache this value if you can.
If you want to just get the speed, consider using the
get_speed_at_mean_anomaly
function instead.
Alternatively, if you already know the eccentric anomaly or true anomaly values,
use the
get_velocity_at_eccentric_anomaly
and
get_velocity_at_true_anomaly
functions instead.
Those functions do not use numerical methods and are therefore a lot faster.
Sourcefn get_altitude_at_true_anomaly(&self, true_anomaly: f64) -> f64
fn get_altitude_at_true_anomaly(&self, true_anomaly: f64) -> f64
Gets the altitude of the body from its parent at a given angle (true anomaly) in the orbit.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
Note that some angles, even within 0 to tau, are impossible for
hyperbolic orbits and may result in invalid values.
Check for the range of angles for a hyperbolic orbit using
get_true_anomaly_at_asymptote.
§Altitude
The altitude is measured in meters, and measured from the center of the parent body (origin).
§Performance
This function is performant, however, if you already
know the orbit’s semi-latus rectum or the cosine of the true anomaly,
you can use the
get_altitude_at_true_anomaly_unchecked
function to skip a few steps in the calculation.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.0);
let altitude = orbit.get_altitude_at_true_anomaly(0.0);
assert_eq!(altitude, 100.0);Sourcefn get_altitude_at_true_anomaly_unchecked(
&self,
semi_latus_rectum: f64,
cos_true_anomaly: f64,
) -> f64
fn get_altitude_at_true_anomaly_unchecked( &self, semi_latus_rectum: f64, cos_true_anomaly: f64, ) -> f64
Gets the altitude of the body from its parent given the cosine of the true anomaly.
This function should only be used if you already know the semi-latus
rectum or cos(true_anomaly) beforehand, and want to minimize
duplicated work.
§Unchecked Operation
This function does not perform any checks on the validity
of the cos_true_anomaly parameter. Invalid values result in
possibly-nonsensical output values.
§Altitude
The altitude is measured in meters, and measured from the center of the parent body (origin).
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
Note that some angles, even within 0 to tau, are impossible for
hyperbolic orbits and may result in invalid values.
Check for the range of angles for a hyperbolic orbit using
get_true_anomaly_at_asymptote.
§Performance
This function, by itself, is performant and is unlikely to be the culprit of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);
let true_anomaly = 1.2345f64;
// Precalculate some values...
// Scenario 1: If you know just the semi-latus rectum
let scenario_1 = orbit.get_altitude_at_true_anomaly_unchecked(
semi_latus_rectum, // We pass in our precalculated SLR...
true_anomaly.cos() // but calculate the cosine
);
// Scenario 2: If you know just the cosine of the true anomaly
let scenario_2 = orbit.get_altitude_at_true_anomaly_unchecked(
orbit.get_semi_latus_rectum(), // We calculate the SLR...
cos_true_anomaly // but use our precalculated cosine
);
// Scenario 3: If you know both the semi-latus rectum:
let scenario_3 = orbit.get_altitude_at_true_anomaly_unchecked(
semi_latus_rectum, // We pass in our precalculated SLR...
cos_true_anomaly // AND use our precalculated cosine
);
assert_eq!(scenario_1, scenario_2);
assert_eq!(scenario_2, scenario_3);
assert_eq!(scenario_3, orbit.get_altitude_at_true_anomaly(true_anomaly));Sourcefn get_altitude_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
fn get_altitude_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
Gets the altitude at a given eccentric anomaly in the orbit.
§Altitude
The altitude is measured in meters, and measured from the center of the parent body (origin).
§Performance
This function is not too performant as it uses a few trigonometric operations. It is recommended to cache this value if you can.
Alternatively, if you already know the true anomaly, use the
get_altitude_at_true_anomaly
function instead.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let mut orbit = Orbit2D::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.0);
let altitude = orbit.get_altitude_at_eccentric_anomaly(0.0);
assert_eq!(altitude, 100.0);Sourcefn get_altitude_at_time(&self, time: f64) -> f64
fn get_altitude_at_time(&self, time: f64) -> f64
Gets the altitude of the body from its parent at a given time in the orbit.
Note that due to floating-point imprecision, values of extreme magnitude may not be accurate.
§Time
The time is expressed in seconds.
§Altitude
The altitude is measured in meters, and measured from the center of the parent body (origin).
§Performance
This involves calculating the true anomaly at a given time, and so is not very performant.
It is recommended to cache this value when possible.
Alternatively, if you already know the eccentric anomaly or the true anomaly,
consider using the
get_altitude_at_eccentric_anomaly
and
get_altitude_at_true_anomaly
functions instead.
Those do not use numerical methods and therefore are a lot faster.
§Parabolic Support
This function returns infinity for parabolic orbits due to how the equation for true anomaly works.
Sourcefn get_position_at_time(&self, time: f64) -> DVec2
fn get_position_at_time(&self, time: f64) -> DVec2
Gets the position at a given time in the orbit.
§Time
The time is expressed in seconds.
§Performance
This involves calculating the true anomaly at a given time,
and so is not very performant.
It is recommended to cache this value when possible.
This function benefits significantly from being in the cached version of the orbit struct.
Alternatively, if you already know the true anomaly,
consider using the
get_position_at_true_anomaly
function instead.
That does not use numerical methods and therefore is a lot faster.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_time
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
§Parabolic Support
This function returns non-finite numbers for parabolic orbits due to how the equation for true anomaly works.
Sourcefn get_position_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2
fn get_position_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2
Gets the position at a given mean anomaly in the orbit.
§Performance
This involves calculating the true anomaly at a given time,
and so is not very performant.
It is recommended to cache this value when possible.
This function benefits significantly from being in the cached version of the orbit struct.
Alternatively, if you already know the true anomaly,
consider using the
get_position_at_true_anomaly
function instead.
That does not use numerical methods and therefore is a lot faster.
If you want to get both the position and velocity vectors, you can
use the
get_state_vectors_at_mean_anomaly
function instead. It prevents redundant calculations and is therefore
faster than calling the position and velocity functions separately.
§Parabolic Support
This function returns non-finite numbers for parabolic orbits due to how the equation for true anomaly works.
Sourcefn get_state_vectors_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> StateVectors2D
fn get_state_vectors_at_eccentric_anomaly( &self, eccentric_anomaly: f64, ) -> StateVectors2D
Gets the position and velocity at a given eccentric anomaly in the orbit.
§Performance
This function uses several trigonometric functions, and so it is not too performant.
It is recommended to cache this value if you can.
This is, however, faster than individually calling the position and velocity getters separately, as this will reuse calculations whenever possible.
If you need only one of the vectors, though, you should instead call the dedicated
getters:
get_velocity_at_eccentric_anomaly
get_position_at_eccentric_anomaly
This function should give similar performance to the getter from the true anomaly:
get_state_vectors_at_true_anomaly
In case you really want to, an unchecked version of this function is available:
get_state_vectors_from_unchecked_parts
§Parabolic Support
This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.
Sourcefn get_state_vectors_at_true_anomaly(&self, true_anomaly: f64) -> StateVectors2D
fn get_state_vectors_at_true_anomaly(&self, true_anomaly: f64) -> StateVectors2D
Gets the position and velocity at a given angle (true anomaly) in the orbit.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Performance
This function uses several trigonometric functions, and so it is not too performant.
It is recommended to cache this value if you can.
This is, however, faster than individually calling the position and velocity getters separately, as this will reuse calculations whenever possible.
If you need only one of the vectors, though, you should instead call the dedicated
getters:
get_velocity_at_true_anomaly
get_position_at_true_anomaly
This function should give similar performance to the getter from the eccentric anomaly:
get_state_vectors_at_eccentric_anomaly
In case you really want to, an unchecked version of this function is available:
get_state_vectors_from_unchecked_parts
§Parabolic Support
This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.
Sourcefn get_state_vectors_at_mean_anomaly(&self, mean_anomaly: f64) -> StateVectors2D
fn get_state_vectors_at_mean_anomaly(&self, mean_anomaly: f64) -> StateVectors2D
Gets the position and velocity at a given mean anomaly in the orbit.
§Performance
This function involves converting the mean anomaly to an eccentric anomaly,
which involves numerical approach methods and are therefore not performant.
It is recommended to cache this value if you can.
Alternatively, if you already know the eccentric anomaly or true anomaly,
use the following functions instead, which do not use numerical methods and
therefore are significantly faster:
get_state_vectors_at_eccentric_anomaly
get_state_vectors_at_true_anomaly
This function is faster than individually calling the position and velocity getters separately, as this will reuse calculations whenever possible.
§Parabolic Support
This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.
Sourcefn get_state_vectors_at_time(&self, time: f64) -> StateVectors2D
fn get_state_vectors_at_time(&self, time: f64) -> StateVectors2D
Gets the position and velocity at a given time in the orbit.
§Time
The time is measured in seconds.
§Performance
This function involves converting a mean anomaly (derived from the time)
into an eccentric anomaly.
This involves numerical approach methods and are therefore not performant.
It is recommended to cache this value if you can.
Alternatively, if you already know the eccentric anomaly or true anomaly,
use the following functions instead, which do not use numerical methods and
therefore are significantly faster:
get_state_vectors_at_eccentric_anomaly
get_state_vectors_at_true_anomaly
If you only know the mean anomaly, then that may help with performance a little bit,
in which case you can use
get_state_vectors_at_mean_anomaly
instead.
This function is faster than individually calling the position and velocity getters separately, as this will reuse calculations whenever possible.
If you need only one of the vectors, though, you should instead call the dedicated
getters:
get_velocity_at_time
get_position_at_time
§Parabolic Support
This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.
Sourcefn get_state_vectors_from_unchecked_parts(
&self,
sqrt_abs_gm_a: f64,
altitude: f64,
q_mult: f64,
trig_ecc_anom: (f64, f64),
sincos_angle: (f64, f64),
) -> StateVectors2D
fn get_state_vectors_from_unchecked_parts( &self, sqrt_abs_gm_a: f64, altitude: f64, q_mult: f64, trig_ecc_anom: (f64, f64), sincos_angle: (f64, f64), ) -> StateVectors2D
Gets the position and velocity at a certain point in the orbit.
§Unchecked Operation
This function does not check the validity of the inputs.
Invalid inputs may lead to nonsensical results.
§Parameters
§sqrt_abs_gm_a
This parameter’s value should be calculated using the formula:
sqrt(abs(GM * a))
where:
GMis the gravitational parameter (a.k.a. mu)ais the semi-major axis of the orbit
Alternatively, for elliptic orbits, this formula can be used:
sqrt(GM * a)
As for hyperbolic orbits, this formula can be used:
sqrt(-GM * a)
§altitude
The altitude at that point in the orbit.
The altitude is measured in meters, and measured from the
center of the parent body (origin).
§q_mult
This parameter is a multiplier for the second element in the velocity PQW vector.
For elliptic orbits, it should be calculated by the formula sqrt(1 - e^2),
where e is the eccentricity of the orbit.
For hyperbolic orbits, it should be calculated by the formula sqrt(e^2 - 1),
where e is the eccentricity of the orbit.
Alternatively, for the general case, you can use the formula sqrt(abs(1 - e^2)).
§trig_ecc_anom
For elliptic orbits, this parameter should be a tuple containing the sine and cosine
values of the eccentric anomaly, respectively.
For hyperbolic orbits, this parameter should be a tuple containing the hyperbolic
sine and hyperbolic cosine values of the eccentric anomaly, respectively.
§sincos_angle
This parameter should be calculated by passing the true anomaly into f64::sin_cos():
let true_anomaly: f64 = 1.25; // Example value
let sincos_angle = true_anomaly.sin_cos();§Performance
This function, by itself, is very performant and should not be the cause of any performance issues.
§Parabolic Support
This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D, StateVectors2D};
// Elliptic (circular) case
let orbit = Orbit2D::default();
let true_anomaly: f64 = 1.24; // Example value
let eccentric_anomaly = orbit
.get_eccentric_anomaly_at_true_anomaly(true_anomaly);
let sqrt_abs_gm_a = (
orbit.get_gravitational_parameter() *
orbit.get_semi_major_axis()
).abs().sqrt();
let altitude = orbit.get_altitude_at_true_anomaly(true_anomaly);
let q_mult = (
1.0 - orbit.get_eccentricity().powi(2)
).abs().sqrt();
let trig_ecc_anom = eccentric_anomaly.sin_cos();
let sincos_angle = true_anomaly.sin_cos();
let sv = StateVectors2D {
position: orbit.get_position_at_true_anomaly(true_anomaly),
velocity: orbit.get_velocity_at_true_anomaly(true_anomaly),
};
let sv2 = orbit.get_state_vectors_from_unchecked_parts(
sqrt_abs_gm_a,
altitude,
q_mult,
trig_ecc_anom,
sincos_angle
);
assert_eq!(sv, sv2);use keplerian_sim::{Orbit2D, OrbitTrait2D, sinhcosh, StateVectors2D};
// Hyperbolic case
let mut orbit = Orbit2D::default();
orbit.set_eccentricity(1.5);
let true_anomaly: f64 = 1.24; // Example value
let eccentric_anomaly = orbit
.get_eccentric_anomaly_at_true_anomaly(true_anomaly);
let sqrt_abs_gm_a = (
orbit.get_gravitational_parameter() *
orbit.get_semi_major_axis()
).abs().sqrt();
let altitude = orbit.get_altitude_at_true_anomaly(true_anomaly);
let q_mult = (
1.0 - orbit.get_eccentricity().powi(2)
).abs().sqrt();
let trig_ecc_anom = sinhcosh(eccentric_anomaly);
let sincos_angle = true_anomaly.sin_cos();
let sv = StateVectors2D {
position: orbit.get_position_at_true_anomaly(true_anomaly),
velocity: orbit.get_velocity_at_true_anomaly(true_anomaly),
};
let sv2 = orbit.get_state_vectors_from_unchecked_parts(
sqrt_abs_gm_a,
altitude,
q_mult,
trig_ecc_anom,
sincos_angle
);
assert_eq!(sv, sv2);Sourcefn get_time_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
fn get_time_at_mean_anomaly(&self, mean_anomaly: f64) -> f64
Gets the time of the orbit at a certain mean anomaly.
§Time
The time is measured in seconds.
§Performance
This function is performant and is unlikely to be the source of any performance issues.
§Example
use keplerian_sim::{Orbit2D, OrbitTrait2D};
let orbit = Orbit2D::new(
2.1, // Eccentricity
5.0, // Periapsis
2.9, // Argument of periapsis
1.0, // Mean anomaly at epoch
1.0, // Gravitational parameter
);
const TIME: f64 = 2.0;
let mean_anomaly = orbit.get_mean_anomaly_at_time(TIME);
let time_result = orbit.get_time_at_mean_anomaly(mean_anomaly);
const TOLERANCE: f64 = 1e-15;
assert!(
(time_result - TIME).abs() < TOLERANCE
);Sourcefn get_time_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
fn get_time_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64
Gets the time of the orbit at a certain eccentric anomaly.
§Time
The time is measured in seconds.
§Performance
This function is not too performant as it performs some trigonometry.
Alternatively, if you already have the mean anomaly, you can instead use that
along with get_time_at_mean_anomaly.
Or if you know sin(eccentric_anomaly) or sinh(eccentric_anomaly)
beforehand, you may use
get_mean_anomaly_at_elliptic_eccentric_anomaly
and
get_mean_anomaly_at_hyperbolic_eccentric_anomaly
instead, for closed and hyperbolic orbits respectively.
Those functions do not do trigonometry and are therefore a lot faster.
Sourcefn get_time_at_true_anomaly(&self, true_anomaly: f64) -> f64
fn get_time_at_true_anomaly(&self, true_anomaly: f64) -> f64
Gets the time of the orbit at a certain true anomaly.
§Time
The time is measured in seconds.
§Performance
This function is not too performant as it performs some trigonometry.
Alternatively, if you already have the mean anomaly, you can instead use that
along with get_time_at_mean_anomaly.
Or if you already have the eccentric anomaly, you can instead use that
along with get_time_at_eccentric_anomaly.
Those functions are faster as they do less trigonometry (and in the case of the first one: no trig whatsoever).
Sourcefn transform_pqw_vector(&self, position: DVec2) -> DVec2
fn transform_pqw_vector(&self, position: DVec2) -> DVec2
Transforms a position from the perifocal coordinate (PQW) system into world space, using the orbital parameters.
§Perifocal Coordinate (PQW) System
The perifocal coordinate (PQW) system is a frame of reference using the basis vectors p-hat, q-hat, and w-hat, where p-hat points to the periapsis, q-hat has a true anomaly 90 degrees more than p-hat, and w-hat points perpendicular to the orbital plane.
Learn more: https://en.wikipedia.org/wiki/Perifocal_coordinate_system
§Performance
This function performs 10x faster in the cached version of the
Orbit2D struct, as it doesn’t need to recalculate the transformation
matrix needed to transform 2D vector.
Sourcefn is_circular(&self) -> bool
fn is_circular(&self) -> bool
Gets whether or not the orbit is circular.
A circular orbit has an eccentricity of 0.
Sourcefn is_elliptic(&self) -> bool
fn is_elliptic(&self) -> bool
Gets whether or not the orbit is strictly elliptic.
A strictly elliptic orbit has an eccentricity between 0 and 1.
For getting whether or not the orbit is circular
or elliptic, use is_closed
Sourcefn is_closed(&self) -> bool
fn is_closed(&self) -> bool
Gets whether or not the orbit is closed.
A closed orbit can be either circular or elliptic, i.e. has an eccentricity of less than 1.
For getting whether or not the orbit is circular (e = 0),
use is_circular.
For getting whether or not the orbit is strictly
elliptic (0 < e < 1), use is_elliptic.
Sourcefn is_parabolic(&self) -> bool
fn is_parabolic(&self) -> bool
Gets whether or not the trajectory is parabolic.
A parabolic trajectory has an eccentricity of exactly 1.
Sourcefn is_hyperbolic(&self) -> bool
fn is_hyperbolic(&self) -> bool
Gets whether or not the trajectory is hyperbolic.
A hyperbolic trajectory has an eccentricity of greater than 1.
For getting whether or not the trajectory is open — i.e.,
has an eccentricity of at least 1 — use
is_open.
Sourcefn is_open(&self) -> bool
fn is_open(&self) -> bool
Gets whether or not the trajectory is open.
An open trajectory has an eccentricity of at least 1, i.e., is either a parabolic trajectory or a hyperbolic trajectory.
For getting whether or not a trajectory is parabolic (e = 1),
use is_parabolic.
For getting whether or not a trajectory is hyperbolic (e > 1),
use is_hyperbolic.
Sourcefn get_orbital_period(&self) -> f64
fn get_orbital_period(&self) -> f64
Gets the time it takes to complete one revolution of the orbit.
This function returns infinite values for parabolic trajectories and NaN for hyperbolic trajectories.
§Time
The time is measured in seconds.
§Performance
This function is performant and is unlikely to be the cause of any performance issues.