Trait OrbitTrait

Source
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(&not_orbit);

Required Methods§

Source

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
);
Source

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);
Source

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,
});
Source

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)

Source

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)

Source

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

Source

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

Source

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

Source

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

Source

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”.

Source

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”.

Source

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”.

Source

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”.

Source

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.

Source

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.

Source

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.

Source

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§

Source

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.

Source

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.

Source

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.

Source

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);
Source

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);
Source

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.

Wikipedia

Source

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.”

Source

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.

Source

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

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

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.

Source

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.

Wikipedia

§Time

The time is expressed in seconds.

§Performance

This function is performant and is unlikely to be the culprit of any performance issues.

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

§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.

Source

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.

Wikipedia

§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.

Source

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));
Source

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.

Source

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);
Source

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);
Source

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.

Source

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.

Source

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.

Source

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

Source

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);
Source

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.

Source

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));
Source

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);
Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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);
Source

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));
Source

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);
Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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:

  • GM is the gravitational parameter (a.k.a. mu)
  • a is 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);
Source

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.

Source

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.”

Source

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.

Implementors§