pub trait OrbitTrait {
Show 66 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) -> Matrix3x2;
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_inclination(&self) -> f64;
fn set_inclination(&mut self, inclination: f64);
fn get_arg_pe(&self) -> f64;
fn set_arg_pe(&mut self, arg_pe: f64);
fn get_long_asc_node(&self) -> f64;
fn set_long_asc_node(&mut self, long_asc_node: 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: MuSetterMode,
);
// 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_apoapsis(&self) -> f64 { ... }
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_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) -> DVec3 { ... }
fn get_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3 { ... }
fn get_speed_at_true_anomaly(&self, angle: f64) -> f64 { ... }
fn get_speed_at_altitude(&self, altitude: f64) -> f64 { ... }
fn get_speed_at_time(&self, time: f64) -> f64 { ... }
fn get_speed_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64 { ... }
fn get_pqw_velocity_at_true_anomaly(&self, angle: f64) -> DVec2 { ... }
fn get_pqw_velocity_at_eccentric_anomaly(
&self,
eccentric_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) -> DVec3 { ... }
fn get_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3 { ... }
fn get_velocity_at_time(&self, time: f64) -> DVec3 { ... }
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) -> DVec3 { ... }
fn get_state_vectors_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> StateVectors { ... }
fn get_state_vectors_at_true_anomaly(
&self,
true_anomaly: f64,
) -> StateVectors { ... }
fn get_state_vectors_at_mean_anomaly(
&self,
mean_anomaly: f64,
) -> StateVectors { ... }
fn get_state_vectors_at_time(&self, time: f64) -> StateVectors { ... }
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),
) -> StateVectors { ... }
fn transform_pqw_vector(&self, position: DVec2) -> DVec3 { ... }
fn get_approx_hyp_ecc_anomaly(&self, mean_anomaly: f64) -> f64 { ... }
fn get_orbital_period(&self) -> f64 { ... }
}Expand description
A trait that defines the methods that a Keplerian orbit must implement.
This trait is implemented by both Orbit and CompactOrbit.
§Examples
use keplerian_sim::{Orbit, OrbitTrait, CompactOrbit};
fn accepts_orbit(orbit: &impl OrbitTrait) {
println!("That's an orbit!");
}
fn main() {
let orbit = Orbit::default();
accepts_orbit(&orbit);
let compact = CompactOrbit::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 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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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::{Orbit, OrbitTrait};
let mut base = Orbit::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) -> Matrix3x2
fn get_transformation_matrix(&self) -> Matrix3x2
Gets the transformation matrix needed to tilt a 2D vector into the tilted orbital plane.
§Performance
For CompactOrbit, this will perform a few trigonometric operations.
If you need this value often, consider using the cached orbit struct instead.
§Example
use keplerian_sim::{Orbit, OrbitTrait};
let orbit = Orbit::default();
let matrix = orbit.get_transformation_matrix();
assert_eq!(matrix, keplerian_sim::Matrix3x2 {
e11: 1.0, e12: 0.0,
e21: 0.0, e22: 1.0,
e31: 0.0, e32: 0.0,
});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_inclination(&self) -> f64
fn get_inclination(&self) -> f64
Gets the inclination of the orbit in radians.
The inclination of an orbit is the angle between the plane of the orbit and the reference plane.
In simple terms, it tells you how “tilted” the orbit is.
Wikipedia: https://en.wikipedia.org/wiki/Orbital_inclination
Sourcefn set_inclination(&mut self, inclination: f64)
fn set_inclination(&mut self, inclination: f64)
Sets the inclination of the orbit in radians.
The inclination of an orbit is the angle between the plane of the orbit and the reference plane.
In simple terms, it tells you how “tilted” the orbit is.
Wikipedia: https://en.wikipedia.org/wiki/Orbital_inclination
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_long_asc_node(&self) -> f64
fn get_long_asc_node(&self) -> f64
Gets the longitude of ascending node of the orbit in radians.
Wikipedia:
The longitude of ascending node is the angle from a specified
reference direction, called the origin of longitude, to the direction
of the ascending node, as measured in a specified reference plane.
https://en.wikipedia.org/wiki/Longitude_of_the_ascending_node
In simple terms, it tells you how, and in which direction, the orbit “tilts”.
Sourcefn set_long_asc_node(&mut self, long_asc_node: f64)
fn set_long_asc_node(&mut self, long_asc_node: f64)
Sets the longitude of ascending node of the orbit in radians.
Wikipedia:
The longitude of ascending node is the angle from a specified
reference direction, called the origin of longitude, to the direction
of the ascending node, as measured in a specified reference plane.
https://en.wikipedia.org/wiki/Longitude_of_the_ascending_node
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: MuSetterMode,
)
fn set_gravitational_parameter( &mut self, gravitational_parameter: f64, mode: MuSetterMode, )
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::{Orbit, OrbitTrait, MuSetterMode};
let mut orbit = Orbit::new(
0.0, // Eccentricity
1.0, // Periapsis
0.0, // Inclination
0.0, // Argument of Periapsis
0.0, // Longitude of Ascending Node
0.0, // Mean anomaly at epoch
1.0, // Gravitational parameter (mu = GM)
);
orbit.set_gravitational_parameter(3.0, MuSetterMode::KeepElements);
assert_eq!(orbit.get_eccentricity(), 0.0);
assert_eq!(orbit.get_periapsis(), 1.0);
assert_eq!(orbit.get_inclination(), 0.0);
assert_eq!(orbit.get_arg_pe(), 0.0);
assert_eq!(orbit.get_long_asc_node(), 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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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.
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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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_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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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_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.
§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_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) -> DVec3
fn get_position_at_true_anomaly(&self, angle: f64) -> DVec3
Gets the 3D 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::DVec3;
use keplerian_sim::{Orbit, OrbitTrait};
let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.0);
let pos = orbit.get_position_at_true_anomaly(0.0);
assert_eq!(pos, DVec3::new(100.0, 0.0, 0.0));Sourcefn get_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3
fn get_position_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3
Gets the 3D 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 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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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 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::{Orbit, OrbitTrait};
const PERIAPSIS: f64 = 100.0;
let mut orbit = Orbit::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_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 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_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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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_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_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, and it also doesn’t check
that the orbit is elliptic.
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 3D 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::{Orbit, OrbitTrait, sinhcosh};
let orbit = Orbit::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::{Orbit, OrbitTrait, sinhcosh};
let mut hyperbolic = Orbit::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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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.
§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 3D 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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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) -> DVec3
fn get_velocity_at_true_anomaly(&self, angle: f64) -> DVec3
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 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_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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3
fn get_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3
Gets the velocity at a given eccentric anomaly in the orbit.
§Example
use keplerian_sim::{Orbit, OrbitTrait};
let mut orbit = Orbit::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) -> DVec3
fn get_velocity_at_time(&self, time: f64) -> DVec3
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_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.
§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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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.
§Angle
The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.
§Performance
This function, by itself, is performant and is unlikely to be the culprit of any performance issues.
§Example
use keplerian_sim::{Orbit, OrbitTrait};
let mut orbit = Orbit::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.
§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::{Orbit, OrbitTrait};
let mut orbit = Orbit::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.
§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) -> DVec3
fn get_position_at_time(&self, time: f64) -> DVec3
Gets the 3D 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_state_vectors_at_eccentric_anomaly(
&self,
eccentric_anomaly: f64,
) -> StateVectors
fn get_state_vectors_at_eccentric_anomaly( &self, eccentric_anomaly: f64, ) -> StateVectors
Gets the 3D 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) -> StateVectors
fn get_state_vectors_at_true_anomaly(&self, true_anomaly: f64) -> StateVectors
Gets the 3D 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) -> StateVectors
fn get_state_vectors_at_mean_anomaly(&self, mean_anomaly: f64) -> StateVectors
Gets the 3D 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) -> StateVectors
fn get_state_vectors_at_time(&self, time: f64) -> StateVectors
Gets the 3D 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),
) -> StateVectors
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), ) -> StateVectors
Gets the 3D 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, in meters.
§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 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::{Orbit, OrbitTrait, StateVectors};
// Elliptic (circular) case
let orbit = Orbit::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 = StateVectors {
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::{Orbit, OrbitTrait, sinhcosh, StateVectors};
// Hyperbolic case
let mut orbit = Orbit::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 = StateVectors {
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 transform_pqw_vector(&self, position: DVec2) -> DVec3
fn transform_pqw_vector(&self, position: DVec2) -> DVec3
Transforms a position from the perifocal coordinate (PQW) system into 3D, 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
Orbit struct, as it doesn’t need to recalculate the transformation
matrix needed to transform 2D vector.
Sourcefn get_approx_hyp_ecc_anomaly(&self, mean_anomaly: f64) -> f64
fn get_approx_hyp_ecc_anomaly(&self, mean_anomaly: f64) -> f64
Get an initial guess for the hyperbolic eccentric anomaly of an orbit.
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_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 should not be the cause of any performance issues.