Skip to main content

OrbitTrait

Trait OrbitTrait 

Source
pub trait OrbitTrait {
Show 115 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_pqw_basis_vector_p(&self) -> DVec3; fn get_pqw_basis_vector_q(&self) -> DVec3; fn get_pqw_basis_vector_w(&self) -> DVec3; 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_true_anomaly_at_asymptote(&self) -> f64 { ... } fn get_position_at_periapsis(&self) -> DVec3 { ... } fn get_position_at_periapsis_unchecked(&self, p_vector: DVec3) -> DVec3 { ... } fn get_position_at_apoapsis(&self) -> DVec3 { ... } fn get_position_at_apoapsis_unchecked(&self, p_vector: DVec3) -> DVec3 { ... } fn get_apoapsis(&self) -> f64 { ... } fn get_mean_motion(&self) -> f64 { ... } fn get_focal_parameter(&self) -> f64 { ... } fn get_specific_angular_momentum(&self) -> f64 { ... } fn get_specific_orbital_energy(&self) -> f64 { ... } fn get_area_sweep_rate(&self) -> f64 { ... } fn get_time_of_periapsis(&self) -> f64 { ... } fn get_time_of_apoapsis(&self) -> f64 { ... } fn get_pqw_basis_vectors(&self) -> (DVec3, DVec3, DVec3) { ... } fn get_eccentricity_vector(&self) -> DVec3 { ... } fn get_eccentricity_vector_unchecked(&self, p_vector: DVec3) -> DVec3 { ... } fn get_longitude_of_periapsis(&self) -> f64 { ... } fn get_true_longitude_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... } fn get_true_anomaly_at_asc_node(&self) -> f64 { ... } fn get_true_anomaly_at_desc_node(&self) -> f64 { ... } fn get_true_anomaly_at_asc_node_with_plane( &self, plane_normal: DVec3, ) -> f64 { ... } fn get_true_anomaly_at_desc_node_with_plane( &self, plane_normal: DVec3, ) -> 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_true_anomaly_at_altitude(&self, altitude: f64) -> f64 { ... } fn get_true_anomaly_at_altitude_unchecked( &self, semi_latus_rectum: f64, altitude: f64, eccentricity_recip: f64, ) -> f64 { ... } fn get_mean_anomaly_at_time(&self, time: f64) -> f64 { ... } fn get_mean_anomaly_at_eccentric_anomaly( &self, eccentric_anomaly: f64, ) -> f64 { ... } fn get_mean_anomaly_at_elliptic_eccentric_anomaly( &self, eccentric_anomaly: f64, sin_eccentric_anomaly: f64, ) -> f64 { ... } fn get_mean_anomaly_at_hyperbolic_eccentric_anomaly( &self, eccentric_anomaly: f64, sinh_eccentric_anomaly: f64, ) -> f64 { ... } fn get_mean_anomaly_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... } fn get_position_at_true_anomaly(&self, angle: f64) -> 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_periapsis(&self) -> f64 { ... } fn get_speed_at_apoapsis(&self) -> f64 { ... } fn get_speed_at_infinity(&self) -> f64 { ... } fn get_speed_at_time(&self, time: f64) -> f64 { ... } fn get_speed_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64 { ... } fn get_speed_at_mean_anomaly(&self, mean_anomaly: f64) -> f64 { ... } fn get_pqw_velocity_at_true_anomaly(&self, angle: f64) -> DVec2 { ... } fn get_pqw_velocity_at_periapsis(&self) -> DVec2 { ... } fn get_pqw_velocity_at_apoapsis(&self) -> DVec2 { ... } fn get_pqw_velocity_at_incoming_asymptote(&self) -> DVec2 { ... } fn get_pqw_velocity_at_outgoing_asymptote(&self) -> DVec2 { ... } fn get_pqw_velocity_at_eccentric_anomaly( &self, eccentric_anomaly: f64, ) -> DVec2 { ... } fn get_pqw_velocity_at_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_velocity_at_mean_anomaly(&self, mean_anomaly: 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_periapsis(&self) -> DVec3 { ... } fn get_velocity_at_apoapsis(&self) -> DVec3 { ... } fn get_velocity_at_incoming_asymptote(&self) -> DVec3 { ... } fn get_velocity_at_outgoing_asymptote(&self) -> DVec3 { ... } fn get_velocity_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> DVec3 { ... } fn get_velocity_at_time(&self, time: f64) -> DVec3 { ... } fn get_velocity_at_mean_anomaly(&self, mean_anomaly: 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_position_at_mean_anomaly(&self, mean_anomaly: 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 get_time_at_mean_anomaly(&self, mean_anomaly: f64) -> f64 { ... } fn get_time_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64 { ... } fn get_time_at_true_anomaly(&self, true_anomaly: f64) -> f64 { ... } fn transform_pqw_vector(&self, position: DVec2) -> DVec3 { ... } fn is_circular(&self) -> bool { ... } fn is_elliptic(&self) -> bool { ... } fn is_closed(&self) -> bool { ... } fn is_parabolic(&self) -> bool { ... } fn is_hyperbolic(&self) -> bool { ... } fn is_open(&self) -> bool { ... } fn get_orbital_period(&self) -> f64 { ... }
}
Expand description

A trait that defines the methods that a 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

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_pqw_basis_vector_p(&self) -> DVec3

Gets the p basis vector for the perifocal coordinate (PQW) system.

The p basis vector is a unit vector that points to the periapsis.

For more information about the PQW system, visit the Wikipedia article.

§Performance

For CompactOrbit, this will perform a few trigonometric operations and multiplications, and therefore is not too performant.

For Orbit, this will only need to access the cache, and therefore is much more performant.

If you want to get multiple basis vectors, use get_pqw_basis_vectors instead, as that skips some duplicated work.

§Example
use keplerian_sim::{Orbit, CompactOrbit, OrbitTrait};
use glam::DVec3;

let orbit = Orbit::default();
let p = orbit.get_pqw_basis_vector_p();
let q = orbit.get_pqw_basis_vector_q();
let w = orbit.get_pqw_basis_vector_w();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);

let compact_orbit = CompactOrbit::default();
let p = compact_orbit.get_pqw_basis_vector_p();
let q = compact_orbit.get_pqw_basis_vector_q();
let w = compact_orbit.get_pqw_basis_vector_w();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);
Source

fn get_pqw_basis_vector_q(&self) -> DVec3

Gets the q basis vector for the perifocal coordinate (PQW) system.

The q basis vector is orthogonal to the p basis vector and points 90° counterclockwise from the periapsis on the orbital plane.

For more information about the PQW system, visit the Wikipedia article.

§Performance

For CompactOrbit, this will perform a few trigonometric operations and multiplications, and therefore is not too performant.

For Orbit, this will only need to access the cache, and therefore is much more performant.

If you want to get multiple basis vectors, use get_pqw_basis_vectors instead, as that skips some duplicated work.

§Example
use keplerian_sim::{Orbit, CompactOrbit, OrbitTrait};
use glam::DVec3;

let orbit = Orbit::default();
let p = orbit.get_pqw_basis_vector_p();
let q = orbit.get_pqw_basis_vector_q();
let w = orbit.get_pqw_basis_vector_w();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);

let compact_orbit = CompactOrbit::default();
let p = compact_orbit.get_pqw_basis_vector_p();
let q = compact_orbit.get_pqw_basis_vector_q();
let w = compact_orbit.get_pqw_basis_vector_w();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);
Source

fn get_pqw_basis_vector_w(&self) -> DVec3

Gets the w basis vector for the perifocal coordinate (PQW) system.

The w basis vector is orthogonal to the orbital plane.

For more information about the PQW system, visit the Wikipedia article.

§Performance

For CompactOrbit, this will perform a few trigonometric operations and multiplications, and therefore is not too performant.

For Orbit, this will only need to compute a cross product, and therefore is much more performant.

If you want to get multiple basis vectors, use get_pqw_basis_vectors instead, as that skips some duplicated work.

§Example
use keplerian_sim::{Orbit, CompactOrbit, OrbitTrait};
use glam::DVec3;

let orbit = Orbit::default();
let p = orbit.get_pqw_basis_vector_p();
let q = orbit.get_pqw_basis_vector_q();
let w = orbit.get_pqw_basis_vector_w();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);

let compact_orbit = CompactOrbit::default();
let p = compact_orbit.get_pqw_basis_vector_p();
let q = compact_orbit.get_pqw_basis_vector_q();
let w = compact_orbit.get_pqw_basis_vector_w();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);
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, in meters.

Learn more: https://en.wikipedia.org/wiki/Ellipse#Semi-latus_rectum
https://en.wikipedia.org/wiki/Conic_section#Conic_parameters

§Performance

This function is very performant and should not be the cause of any performance issues.

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_true_anomaly_at_asymptote(&self) -> f64

Gets the true anomaly asymptote (f_∞) of the hyperbolic trajectory.

This returns a positive number between π/2 and π for open trajectories, and NaN for closed orbits.

This can be used to get the range of possible true anomalies that a hyperbolic trajectory can be in.
This function returns the maximum true anomaly, and the minimum true anomaly can be derived simply by negating the result:

f_-∞ = -f_∞

The minimum and maximum together represent the range of possible true anomalies.

§Performance

This function is moderately performant and contains only one trigonometry operation.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

// Closed (elliptic) orbit with eccentricity = 0.8
let closed = Orbit::new_flat(0.8, 1.0, 0.0, 0.0, 1.0);

// True anomaly asymptote is only defined for open orbits,
// i.e., eccentricity ≥ 1
assert!(closed.get_true_anomaly_at_asymptote().is_nan());

let parabolic = Orbit::new_flat(1.0, 1.0, 0.0, 0.0, 1.0);
assert_eq!(
    parabolic.get_true_anomaly_at_asymptote(),
    std::f64::consts::PI
);

let hyperbolic = Orbit::new_flat(2.0, 1.0, 0.0, 0.0, 1.0);
let asymptote = 2.0943951023931957;
assert_eq!(
    hyperbolic.get_true_anomaly_at_asymptote(),
    asymptote
);

// At the asymptote, the altitude is infinite.
// Note: We can't use the regular `get_altitude_at_true_anomaly` here
// because it is less accurate (since it uses cos() while the asymptote uses
// acos(), and the roundtrip causes precision loss).
// We use the unchecked version with the exact cosine value
// of the true anomaly (-1/e) to avoid float inaccuracies.
let asymptote_cos = -1.0 / hyperbolic.get_eccentricity();

// We first check that asymptote_cos is close to cos(asymptote):
assert!(
    (asymptote_cos - asymptote.cos()).abs() < 1e-15
);

// Then we can be fairly confident this will be exactly infinite:
assert!(
    hyperbolic
        .get_altitude_at_true_anomaly_unchecked(
            hyperbolic.get_semi_latus_rectum(),
            asymptote_cos
        )
        .is_infinite()
)
Source

fn get_position_at_periapsis(&self) -> DVec3

Gets the position of the orbit at periapsis.

§Performance

In the cached orbit struct (Orbit), this function is very performant and only involves three multiplications.

However, in the compact orbit struct (CompactOrbit), this is a lot slower and involves some trigonometric calculations. If you already know the P basis vector of the PQW coordinate system, you may use the unchecked version instead (get_position_at_periapsis_unchecked), which is a lot faster and would skip repeated calculations.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec3;

let orbit = Orbit::new_flat(
    0.25, // Eccentricity
    1.0, // Periapsis
    0.0, // Argument of periapsis
    0.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

assert_eq!(
    orbit.get_position_at_periapsis(),
    DVec3::new(1.0, 0.0, 0.0)
);
Source

fn get_position_at_periapsis_unchecked(&self, p_vector: DVec3) -> DVec3

Gets the position of the orbit at periapsis based on a known P basis vector.

The P basis vector is one of the basis vector from the PQW coordinate system.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

§Unchecked Operation

This function does not check that the given p_vector is a unit vector nor whether it actually is the basis vector in the PQW coordinate system.

It is expected that callers get this vector from either the transformation matrix (get_transformation_matrix), the basis vector collective getter (get_pqw_basis_vectors), or the individual basis vector getter (get_pqw_basis_vector_p).

A safe wrapper is available, but that may be slower; see the Performance section for details.

§Performance

There is no reason to use this if you are using the cached orbit struct (Orbit) as the performance is identical to the wrapper function.

However, in the compact orbit struct (CompactOrbit), this skips some expensive trigonometry operations and therefore is a lot faster than the wrapper function.

§Example
use keplerian_sim::{CompactOrbit, OrbitTrait};
use glam::DVec3;

let orbit = CompactOrbit::new_flat(
    0.25, // Eccentricity
    1.0, // Periapsis
    0.0, // Argument of periapsis
    0.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let p_vector = orbit.get_pqw_basis_vector_p();

// Use p_vector here...
// Use it again for periapsis position!

assert_eq!(
    orbit.get_position_at_periapsis_unchecked(p_vector),
    DVec3::new(1.0, 0.0, 0.0)
);
Source

fn get_position_at_apoapsis(&self) -> DVec3

Gets the position of the orbit at apoapsis.

§Performance

In the cached orbit struct (Orbit), this function is very performant and only involves three multiplications.

However, in the compact orbit struct (CompactOrbit), this is a lot slower and involves some trigonometric calculations. If you already know the P basis vector of the PQW coordinate system, you may use the unchecked version instead (get_position_at_apoapsis_unchecked), which is a lot faster and would skip repeated calculations.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec3;

let orbit = Orbit::new_flat(
    0.25, // Eccentricity
    1.0, // Periapsis
    0.0, // Argument of periapsis
    0.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

assert_eq!(
    orbit.get_position_at_apoapsis(),
    DVec3::new(-1.6666666666666665, 0.0, 0.0)
);
Source

fn get_position_at_apoapsis_unchecked(&self, p_vector: DVec3) -> DVec3

Gets the position of the orbit at apoapsis based on a known P basis vector.

The P basis vector is one of the basis vector from the PQW coordinate system.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

§Unchecked Operation

This function does not check that the given p_vector is a unit vector nor whether it actually is the basis vector in the PQW coordinate system.

It is expected that callers get this vector from either the transformation matrix (get_transformation_matrix), the basis vector collective getter (get_pqw_basis_vectors), or the individual basis vector getter (get_pqw_basis_vector_p).

A safe wrapper is available, but that may be slower; see the Performance section for details.

§Performance

There is no reason to use this if you are using the cached orbit struct (Orbit) as the performance is identical to the wrapper function.

However, in the compact orbit struct (CompactOrbit), this skips some expensive trigonometry operations and therefore is a lot faster than the wrapper function.

§Example
use keplerian_sim::{CompactOrbit, OrbitTrait};
use glam::DVec3;

let orbit = CompactOrbit::new_flat(
    0.25, // Eccentricity
    1.0, // Periapsis
    0.0, // Argument of periapsis
    0.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let p_vector = orbit.get_pqw_basis_vector_p();

// Use p_vector here...
// Use it again for apoapsis position!

assert_eq!(
    orbit.get_position_at_apoapsis_unchecked(p_vector),
    DVec3::new(-1.6666666666666665, 0.0, 0.0)
);
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_mean_motion(&self) -> f64

Gets the mean motion of the orbit, in radians per second.

Mean motion (represented by n) is the angular speed required for a body to complete one orbit, assuming constant speed in a circular orbit which completes in the same time as the variable speed, elliptical orbit of the actual body.

- Wikipedia

§Performance

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

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_flat(
    0.8, // Eccentricity
    9.4, // Periapsis
    2.0, // Argument of periapsis
    1.5, // Mean anomaly at epoch
    0.8, // Gravitational parameter
);

let orbital_period = orbit.get_orbital_period();
let mean_motion = std::f64::consts::TAU / orbital_period;

assert!((orbit.get_mean_motion() - mean_motion).abs() < f64::EPSILON);
Source

fn get_focal_parameter(&self) -> f64

Gets the focal parameter of the orbit, in meters.

This returns infinity in circular orbits (e = 0).

The focal parameter (p) is the distance from a focus to the corresponding directrix.

- Wikipedia

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_flat(
    1.0, // Eccentricity
    3.0, // Periapsis
    2.9, // Argument of periapsis
    0.8, // Mean anomaly at epoch
    1.9, // Gravitational parameter
);

// From Wikipedia's focal parameter equation for parabolas (e = 1)
// (a in this case is periapsis distance, not semi-major axis)
let expected_focal_parameter = 2.0 * orbit.get_periapsis();

assert!(
    (orbit.get_focal_parameter() - expected_focal_parameter).abs() < f64::EPSILON
);
Source

fn get_specific_angular_momentum(&self) -> f64

Gets the specific angular momentum of the orbit, in square meters per second (m^2/s).

The specific relative angular momentum of a body is the angular momentum of that body divided by its mass.

- Wikipedia

§Performance

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

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_flat(
    1.2, // Eccentricity
    2.0, // Periapsis
    3.0, // Argument of periapsis
    4.8, // Mean anomaly at epoch
    5.0, // Gravitational parameter
);

const EXPECTED_VALUE: f64 = 4.69041575982343;

let momentum =
    orbit.get_specific_angular_momentum();

assert!((momentum - EXPECTED_VALUE).abs() < f64::EPSILON);
Source

fn get_specific_orbital_energy(&self) -> f64

Gets the specific orbital energy ε of the orbit, in joules per kilogram (J/kg, equiv. to m^2 ⋅ s^-2).

For closed orbits (eccentricity < 0), ε < 0.
When eccentricity equals 1 (parabolic), ε equals 0, and when eccentricity exceeds 1 (hyperbolic), ε is positive.

The specific orbital energy ε of two orbiting bodies is the constant quotient of their mechanical energy (the sum of their mutual potential energy, ε_p, and their kinetic energy, ε_k) to their reduced mass.

- Wikipedia

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let elliptic = Orbit::new_flat(0.3, 1.0, 0.0, 0.0, 1.0);
let parabolic = Orbit::new_flat(1.0, 1.0, 0.0, 0.0, 1.0);
let hyperbolic = Orbit::new_flat(2.6, 1.0, 0.0, 0.0, 1.0);

assert!(elliptic.get_specific_orbital_energy() < 0.0);
assert!(parabolic.get_specific_orbital_energy() == 0.0);
assert!(hyperbolic.get_specific_orbital_energy() > 0.0);
Source

fn get_area_sweep_rate(&self) -> f64

Gets the area swept out by the orbit in square meters per second (m^2/s).

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_flat(
    2.9, // Eccentricity
    4.9, // Periapsis
    0.2, // Argument of periapsis
    0.9, // Mean anomaly at epoch
    9.8, // Gravitational parameter
);

const EXPECTED_RATE: f64 = 6.842477621446782;

assert!(
    (orbit.get_area_sweep_rate() - EXPECTED_RATE).abs() < f64::EPSILON
);
Source

fn get_time_of_periapsis(&self) -> f64

Gets the time when the orbit is in periapsis, in seconds since epoch.

This returns the time when mean anomaly equals zero.
This means although it will represent a time of periapsis, it doesn’t mean “next periapsis” nor “previous periapsis”, it just means “a periapsis”, at least for closed orbits (e < 1).

§Parabolic Support

This function does not support parabolic trajectories yet.
Calling this function on a parabolic trajectory results in a non-finite number.

§Performance

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

§Example
use keplerian_sim::{Orbit, OrbitTrait};

const PERIAPSIS: f64 = 1.0;

let orbit = Orbit::new_flat(
    0.3, // Eccentricity
    PERIAPSIS,
    2.9, // Argument of periapsis
    1.5, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let time_of_pe = orbit.get_time_of_periapsis();

let alt_of_pe = orbit.get_altitude_at_time(time_of_pe);

assert!(
    (alt_of_pe - PERIAPSIS).abs() < 1e-15
);
Source

fn get_time_of_apoapsis(&self) -> f64

Gets the time when the orbit is in apoapsis, in seconds since epoch.

This returns the time when mean anomaly equals pi.
This means although it will represent a time of apoapsis, it doesn’t mean “next apoapsis” nor “previous apoapsis”, it just means “an apoapsis”, at least for closed orbits (e < 1).

§Performance

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

§Example
use keplerian_sim::{Orbit, OrbitTrait};

const APOAPSIS: f64 = 2.0;
const PERIAPSIS: f64 = 1.0;

let orbit = Orbit::new_flat_with_apoapsis(
    APOAPSIS,
    PERIAPSIS,
    2.9, // Argument of periapsis
    1.5, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let time_of_ap = orbit.get_time_of_apoapsis();

let alt_of_ap = orbit.get_altitude_at_time(time_of_ap);

assert!(
    (alt_of_ap - APOAPSIS).abs() < 1e-15
);
Source

fn get_pqw_basis_vectors(&self) -> (DVec3, DVec3, DVec3)

Gets the basis vectors for the perifocal coordinate (PQW) system.

§Output

This function returns a tuple of three vectors. The vectors are the p, q, and w basis vectors, respectively.

The p basis vector is a unit vector that points to the periapsis.
The q basis vector is orthogonal to that and points 90° counterclockwise from the periapsis on the orbital plane.
The w basis vector is orthogonal to the orbital plane.

For more information about the PQW system, visit the Wikipedia article.

§Performance

For CompactOrbit, this will perform a few trigonometric operations and multiplications, and therefore is not too performant.

For Orbit, this will only need to compute a cross product, and therefore is much more performant.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec3;

let orbit = Orbit::default();
let (p, q, w) = orbit.get_pqw_basis_vectors();

assert_eq!(p, DVec3::X);
assert_eq!(q, DVec3::Y);
assert_eq!(w, DVec3::Z);
Source

fn get_eccentricity_vector(&self) -> DVec3

Gets the eccentricity vector of this orbit.

The eccentricity vector of a Kepler orbit is the dimensionless vector with direction pointing from apoapsis to periapsis and with magnitude equal to the orbit’s scalar eccentricity.

- Wikipedia

§Performance

This function is significantly faster in the cached version of the orbit struct (Orbit) than the compact version (CompactOrbit).
Consider using the cached version if this function will be called often.

Alternatively, if you want to keep using the compact version and know the periapsis unit vector, use the unchecked version: get_eccentricity_vector_unchecked

The cached version only needs to do a multiplication, and therefore is very performant.

The compact version additionally has to compute many multiplications, additions, and several trig operations.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec3;

// Parabolic orbit (e = 1)
let orbit = Orbit::new_flat(1.0, 1.0, 0.0, 0.0, 1.0);
let eccentricity_vector = orbit.get_eccentricity_vector();

assert_eq!(
    eccentricity_vector,
    DVec3::X
);
Source

fn get_eccentricity_vector_unchecked(&self, p_vector: DVec3) -> DVec3

Gets the eccentricity vector of this orbit.

The eccentricity vector of a Kepler orbit is the dimensionless vector with direction pointing from apoapsis to periapsis and with magnitude equal to the orbit’s scalar eccentricity.

- Wikipedia

§Unchecked Operation

This function does not check for the validity of the given P basis vector. The given P vector should be of length 1.

It is expected that callers get this basis vector from either the transformation matrix or the get_pqw_basis_vectors function.

If the given P vector is not of length 1, you may get nonsensical outputs.

§Performance

This function, by itself, is very performant, and should not be the cause of any performance problems.

However, for the cached orbit struct (Orbit), this function has the same performance as the safer get_eccentricity_vector function. There should be no need to use this function if you are using the cached orbit struct.

§Example
use keplerian_sim::{CompactOrbit, OrbitTrait};
use glam::DVec3;

// Parabolic orbit (e = 1)
let orbit = CompactOrbit::new_flat(1.0, 1.0, 0.0, 0.0, 1.0);

// Expensive op for compact orbit: get basis vectors
let basis_vectors = orbit.get_pqw_basis_vectors();

// Use basis vectors for something...
assert_eq!(
    basis_vectors,
    (DVec3::X, DVec3::Y, DVec3::Z)
);

// You can reuse it here! No need to recompute (as long as
// orbit hasn't changed)
let eccentricity_vector = orbit.get_eccentricity_vector_unchecked(
    // basis vectors: P, Q, and W; we get the first one (0th index)
    basis_vectors.0
);

assert_eq!(
    eccentricity_vector,
    DVec3::X
);
Source

fn get_longitude_of_periapsis(&self) -> f64

Gets the longitude of periapsis of this orbit.

The longitude of the periapsis, also called longitude of the pericenter, of an orbiting body is the longitude (measured from the point of the vernal equinox) at which the periapsis (closest approach to the central body) would occur if the body’s orbit inclination were zero.
It is usually denoted ϖ.

- Wikipedia

§Performance

This function is very performant and should not be the cause of any performance problems.

Source

fn get_true_longitude_at_true_anomaly(&self, true_anomaly: f64) -> f64

Gets the true longitude at a true anomaly in the orbit.

True longitude is the ecliptic longitude at which an orbiting body could actually be found if its inclination were zero.

- Wikipedia

§Performance

This function is very performant and should not be the cause of any performance problems.

Source

fn get_true_anomaly_at_asc_node(&self) -> f64

Gets the true anomaly at the ascending node with respect to the XY plane (at Z = 0).

An orbital node is either of the two points where an orbit intersects a plane of reference to which it is inclined.

- Wikipedia

If you want the descending node as well, it is faster to use the following formula than to call the corresponding descending node function:

f_DN = (f_AN + PI).rem_euclid(TAU)

If you want the ascending node with respect to another plane, use get_true_anomaly_at_asc_node_with_plane instead.

§True anomaly domain

In the case of open (parabolic/hyperbolic) trajectories, this function can return a true anomaly outside the valid range. This indicates that that open trajectory does not have an AN/DN crossing.

It is the caller’s job to check for itself whether this true anomaly is within the valid range. This can be done using the get_true_anomaly_at_asymptote function.

This out-of-range issue does not appear in closed (elliptic) orbits.

§Performance

This function is very performant and should not be the cause of any performance problems.

This function is significantly faster than the general-plane function get_true_anomaly_at_asc_node_with_plane as it is more specialized for this calculation.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_circular(
    1.0, // radius
    1.0, // inclination
    2.0, // longitude of AN
    0.0, // mean anomaly (irrelevant)
    1.0, // mu (irrelevant)
);

let f_an = orbit.get_true_anomaly_at_asc_node();

assert!(
    orbit.get_velocity_at_true_anomaly(f_an).z > 0.0
);

let f_dn = (f_an + std::f64::consts::PI)
    .rem_euclid(std::f64::consts::TAU);

assert!(
    orbit.get_velocity_at_true_anomaly(f_dn).z < 0.0
);
Source

fn get_true_anomaly_at_desc_node(&self) -> f64

Gets the true anomaly at the descending node with respect to the XY plane (at Z = 0).

An orbital node is either of the two points where an orbit intersects a plane of reference to which it is inclined.

- Wikipedia

If you want the ascending node as well, it is faster to use the following formula than to call the corresponding descending node function:

f_AN = (f_DN + PI).rem_euclid(TAU)

If you want the descending node with respect to another plane, use get_true_anomaly_at_desc_node_with_plane instead.

§True anomaly domain

In the case of open (parabolic/hyperbolic) trajectories, this function can return a true anomaly outside the valid range. This indicates that that open trajectory does not have an AN/DN crossing.

It is the caller’s job to check for itself whether this true anomaly is within the valid range. This can be done using the get_true_anomaly_at_asymptote function.

This out-of-range issue does not appear in closed (elliptic) orbits.

§Performance

This function is very performant and should not be the cause of any performance problems.

This function is significantly faster than the general-plane function get_true_anomaly_at_desc_node_with_plane as it is more specialized for this calculation.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_circular(
    1.0, // radius
    1.0, // inclination
    2.0, // longitude of AN
    0.0, // mean anomaly (irrelevant)
    1.0, // mu (irrelevant)
);

let f_dn = orbit.get_true_anomaly_at_desc_node();

assert!(
    orbit.get_velocity_at_true_anomaly(f_dn).z < 0.0
);

let f_an = (f_dn + std::f64::consts::PI)
    .rem_euclid(std::f64::consts::TAU);

assert!(
    orbit.get_velocity_at_true_anomaly(f_an).z > 0.0
);
Source

fn get_true_anomaly_at_asc_node_with_plane(&self, plane_normal: DVec3) -> f64

Gets the true anomaly of an ascending node, given a reference plane’s normal vector.

This can be used to get the ascending node compared to another orbit, similar to the AN/DN labels that appear in Kerbal Space Program after you pick a target vessel/body.

You will get a NaN if the plane normals of the two orbits match exactly. In that scenario there is no ascending nor descending node.

To do that, you can get the plane normal of the other orbit using get_pqw_basis_vectors, then feed that into the original orbit’s ascending node getter.

§Unchecked Operation

It is the caller’s job to make sure that the given plane normal is of length 1.
If the given plane normal is not of length 1, you may get nonsensical outputs.

§Performance

This function is moderately faster in the cached version of the orbit struct (Orbit) than the compact version (CompactOrbit).
Consider using the cached version if this function will be called often.

The cached version only needs to do a cross-product, and therefore is very performant.

The compact version additionally has to compute many multiplications, additions, and several trig operations.

Note that if you want to get both the ascending node and descending node, you can use the equality below to compute the descending node from the ascending node. This is far more performant than calling this function and get_true_anomaly_at_desc_node_with_plane separately.

f_DN = (f_AN + PI).rem_euclid(TAU)

Also, if you only need the ascending node with respect to the XY plane (with a +Z normal vector), consider using the specialized get_true_anomaly_at_asc_node function instead as it is much more performant.

§True anomaly domain

In the case of open (parabolic/hyperbolic) trajectories, this function can return a true anomaly outside the valid range. This indicates that that open trajectory does not have an AN/DN crossing.

It is the caller’s job to check for itself whether this true anomaly is within the valid range. This can be done using the get_true_anomaly_at_asymptote function.

This out-of-range issue does not appear in closed (elliptic) orbits.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use core::f64::consts::{PI, TAU};

fn assert_almost_eq(a: f64, b: f64) {
    assert!((a - b).abs() < 1e-13, "{a} != {b}");
}

let this_orbit = Orbit::new(
    0.8, // Eccentricity
    28.4, // Periapsis
    1.98, // Inclination
    2.91, // Argument of periapsis
    0.50, // Longitude of ascending node (rel. to XY plane)
    2.9, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let other_orbit = Orbit::new(
    0.6, // Eccentricity
    11.0, // Periapsis
    3.01, // Inclination
    1.59, // Argument of periapsis
    0.44, // Longitude of ascending node (rel. to XY plane)
    1.25, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let this_normal = this_orbit.get_pqw_basis_vectors().2;
let other_normal = other_orbit.get_pqw_basis_vectors().2;

let this_an = this_orbit.get_true_anomaly_at_asc_node_with_plane(other_normal);
let this_dn = (this_an + PI).rem_euclid(TAU);
assert_almost_eq(this_an, 0.2224161750528122);
assert_almost_eq(this_dn, 3.3640088286426053);

let other_an = other_orbit.get_true_anomaly_at_asc_node_with_plane(this_normal);
let other_dn = (other_an + PI).rem_euclid(TAU);
assert_almost_eq(other_an, 4.628980494949403);
assert_almost_eq(other_dn, 1.4873878413596096);
Source

fn get_true_anomaly_at_desc_node_with_plane(&self, plane_normal: DVec3) -> f64

Gets the true anomaly of a descending node, given a reference plane’s normal vector.

This can be used to get the descending node compared to another orbit, similar to the AN/DN labels that appear in Kerbal Space Program after you pick a target vessel/body.

You will get a NaN if the plane normals of the two orbits match exactly. In that scenario there is no ascending nor descending node.

To do that, you can get the plane normal of the other orbit using get_pqw_basis_vectors, then feed that into the original orbit’s descending node getter.

§Unchecked Operation

It is the caller’s job to make sure that the given plane normal is of length 1.
If the given plane normal is not of length 1, you may get nonsensical outputs.

§Performance

This function is moderately faster in the cached version of the orbit struct (Orbit) than the compact version (CompactOrbit).
Consider using the cached version if this function will be called often.

Note that if you want to get both the ascending node and descending node, you can use the equality below to compute the descending node from the ascending node. This is far more performant than calling this function and get_true_anomaly_at_asc_node_with_plane separately.

f_AN = (f_DN + PI).rem_euclid(TAU)

Also, if you only need the descending node with respect to the XY plane (with a +Z normal vector), consider using the specialized get_true_anomaly_at_desc_node function instead as it is much more performant.

§True anomaly domain

In the case of open (parabolic/hyperbolic) trajectories, this function can return a true anomaly outside the valid range. This indicates that that open trajectory does not have an AN/DN crossing.

It is the caller’s job to check for itself whether this true anomaly is within the valid range. This can be done using the get_true_anomaly_at_asymptote function.

This out-of-range issue does not appear in closed (elliptic) orbits.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use core::f64::consts::{PI, TAU};

fn assert_almost_eq(a: f64, b: f64) {
    assert!((a - b).abs() < 1e-13, "{a} != {b}");
}

let this_orbit = Orbit::new(
    0.8, // Eccentricity
    28.4, // Periapsis
    1.98, // Inclination
    2.91, // Argument of periapsis
    0.50, // Longitude of ascending node (rel. to XY plane)
    2.9, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let other_orbit = Orbit::new(
    0.6, // Eccentricity
    11.0, // Periapsis
    3.01, // Inclination
    1.59, // Argument of periapsis
    0.44, // Longitude of ascending node (rel. to XY plane)
    1.25, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let this_normal = this_orbit.get_pqw_basis_vectors().2;
let other_normal = other_orbit.get_pqw_basis_vectors().2;

let this_dn = this_orbit.get_true_anomaly_at_desc_node_with_plane(other_normal);
let this_an = (this_dn + PI).rem_euclid(TAU);
assert_almost_eq(this_an, 0.2224161750528122);
assert_almost_eq(this_dn, 3.3640088286426053);

let other_dn = other_orbit.get_true_anomaly_at_desc_node_with_plane(this_normal);
let other_an = (other_dn + PI).rem_euclid(TAU);
assert_almost_eq(other_an, 4.628980494949403);
assert_almost_eq(other_dn, 1.4873878413596096);
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 in this case.

§Performance

The method to get the eccentric anomaly from the mean anomaly uses numerical approach methods, and so it is not performant.
It is recommended to cache this value if you can.

The eccentric anomaly is an angular parameter that defines the position of a body that is moving along an elliptic Kepler orbit.

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_true_anomaly_at_altitude(&self, altitude: f64) -> f64

Gets the true anomaly where a certain altitude is reached.

Returns NaN if the orbit is circular or there are no solutions.

§Altitude

The altitude is measured in meters, and measured from the center of the parent body (origin).

The altitude given to this function should be between the periapsis (minimum) and the apoapsis (maximum).
Anything out of range will return NaN.

In the case of hyperbolic orbits, there is no maximum, but the altitude should be positive and more than the periapsis.
Although there technically is a mathematical solution for “negative altitudes” between negative infinity and the apoapsis (which in this case is negative), they may not be very useful in most scenarios.

§Domain

This function returns a float between 0 and π, unless if it returns NaN.
Do note that, although this is the principal solution, other solutions exist, and may be desired. There exists an alternate solution when you negate the principal solution, and the solutions repeat every 2π.

§Example

If there is a principal solution at 1, that means there is an alternate solution at -1, and there are also solutions 2π + 1, 2π - 1, 4π + 1, 4π - 1, etc.

§Performance

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

However, if you already computed the semi-latus rectum or the reciprocal of the eccentricity, you may use the unchecked version of this function for a small performance boost:
get_true_anomaly_at_altitude_unchecked

Source

fn get_true_anomaly_at_altitude_unchecked( &self, semi_latus_rectum: f64, altitude: f64, eccentricity_recip: f64, ) -> f64

Gets the true anomaly where a certain altitude is reached.

Returns NaN if the orbit is circular or there are no solutions.

§Altitude

The altitude is measured in meters, and measured from the center of the parent body (origin).

The altitude given to this function should be between the periapsis (minimum) and the apoapsis (maximum).
Anything out of range will return NaN.

In the case of hyperbolic orbits, there is no maximum, but the altitude should be positive and more than the periapsis.
Although there technically is a mathematical solution for “negative altitudes” between negative infinity and the apoapsis (which in this case is negative), they may not be very useful in most scenarios.

§Unchecked Operation

This function does not check the validity of the inputted values. Nonsensical/invalid inputs may result in nonsensical/invalid outputs.

§Domain

This function returns a float between 0 and π, unless if it returns NaN.
Do note that, although this is the principal solution, other solutions exist, and may be desired. There exists an alternate solution when you negate the principal solution, and the solutions repeat every 2π.

§Example

If there is a principal solution at 1, that means there is an alternate solution at -1, and there are also solutions 2π + 1, 2π - 1, 4π + 1, 4π - 1, etc.

§Performance

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

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 the calculation is a lot faster than the velocity calculation.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Angle

The angle is expressed in radians, and ranges from 0 to tau. Anything out of range will get wrapped around.

§Performance

This function is performant, however, if you already know the altitude at the angle, you can use the get_speed_at_altitude function instead to skip some calculations.

§Example
use keplerian_sim::{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 the calculation is a lot faster than the velocity calculation.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Unchecked Operation

This function does no checks on the validity of the value given in the altitude parameter, namely whether or not this altitude is possible in the given orbit.
If invalid values are passed in, you will receive a possibly-nonsensical value as output.

§Altitude

The altitude is expressed in meters, and is the distance to the center of the orbit.

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{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_periapsis(&self) -> f64

Gets the speed at the periapsis of the orbit.

The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

const PERIAPSIS: f64 = 100.0;

let mut orbit = Orbit::default();
orbit.set_periapsis(PERIAPSIS);
orbit.set_eccentricity(0.5);

let naive_getter = orbit.get_speed_at_altitude(PERIAPSIS);
let dedicated_getter = orbit.get_speed_at_periapsis();

assert!((naive_getter - dedicated_getter).abs() < 1e-14);
Source

fn get_speed_at_apoapsis(&self) -> f64

Gets the speed at the apoapsis of the orbit.

The speed is derived from the vis-viva equation, and so the calculation is a lot faster than the velocity calculation.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Open orbits (eccentricity >= 1)

This function does not handle open orbits specially, and will return a non-physical value. You might want to use the getter for the speed at infinity: get_speed_at_infinity

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

const APOAPSIS: f64 = 200.0;
const PERIAPSIS: f64 = 100.0;

let orbit = Orbit::new_flat_with_apoapsis(
    APOAPSIS,
    PERIAPSIS,
    0.0, // Argument of periapsis
    0.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

let naive_getter = orbit.get_speed_at_altitude(APOAPSIS);
let dedicated_getter = orbit.get_speed_at_apoapsis();

assert!((naive_getter - dedicated_getter).abs() < 1e-14);
Source

fn get_speed_at_infinity(&self) -> f64

Gets the hyperbolic excess speed (v_∞) of the trajectory.

Under simplistic assumptions a body traveling along [a hyperbolic] trajectory will coast towards infinity, settling to a final excess velocity relative to the central body.

- Wikipedia

In other words, as the time of a hyperbolic trajectory approaches infinity, the speed approaches a certain speed, called the hyperbolic excess speed.

§Unchecked Operation

This function does not check that the orbit is open.
This function will return NaN for closed orbits (e < 1).

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Performance

This function is very performant and should not be the cause of any performance issues.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_flat(
    1.0, // Eccentricity
    1.0, // Periapsis
    0.0, // Argument of periapsis
    0.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

assert_eq!(orbit.get_speed_at_infinity(), 0.0);
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 the calculation is a lot faster than the velocity calculation.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Performance

This function is not too performant as it uses a few trigonometric operations.
It is recommended to cache this value if you can.

Alternatively, if you already know the true anomaly, then you should use the get_speed_at_true_anomaly function instead.

Source

fn get_speed_at_mean_anomaly(&self, mean_anomaly: f64) -> f64

Gets the speed at a given mean anomaly in the orbit.

§Performance

The time will be converted into an eccentric anomaly, which uses numerical methods and so is not very performant. It is recommended to cache this value if you can.

Alternatively, if you know the eccentric anomaly or the true anomaly, then you should use the get_speed_at_eccentric_anomaly and get_speed_at_true_anomaly functions instead.
Those do not use numerical methods and therefore are a lot faster.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

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_periapsis(&self) -> DVec2

Gets the velocity at the periapsis of the orbit in the perifocal coordinate system.

§Perifocal Coordinate System

This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

If you want to get the vector in the regular coordinate system instead, use get_velocity_at_periapsis instead.

§Performance

This function is very performant and should not be the cause of any performance issues.

Alternatively, if you only want to know the speed, use get_speed_at_periapsis instead.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec2;

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);

let vel = orbit.get_pqw_velocity_at_periapsis();

assert_eq!(
    vel,
    DVec2::new(0.0, orbit.get_speed_at_periapsis())
);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

Source

fn get_pqw_velocity_at_apoapsis(&self) -> DVec2

Gets the velocity at the apoapsis of the orbit in the perifocal coordinate system.

§Perifocal Coordinate System

This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

If you want to get the vector in the regular coordinate system instead, use get_velocity_at_apoapsis instead.

§Open orbits (eccentricity >= 1)

This function does not handle open orbits specially, and will return a non-physical value. You might want to use the getters for the velocity at the incoming and outgoing asymptotes:

§Performance

This function is very performant and should not be the cause of any performance issues.

Alternatively, if you only want to know the speed, use get_speed_at_apoapsis instead.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec2;

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);

let vel = orbit.get_pqw_velocity_at_apoapsis();

assert_eq!(
    vel,
    DVec2::new(0.0, -orbit.get_speed_at_apoapsis())
);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

Source

fn get_pqw_velocity_at_incoming_asymptote(&self) -> DVec2

Gets the velocity at the incoming asymptote of the trajectory in the perifocal coordinate system.

§Perifocal Coordinate System

This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

If you want to get the vector in the regular coordinate system instead, use get_velocity_at_incoming_asymptote instead.

§Unchecked Operation

This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).

§Performance

This function is very performant and should not be the cause of any performance issues.

Alternatively, if you only want to know the speed, use get_speed_at_infinity instead.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec2;

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);

let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_pqw_velocity_at_incoming_asymptote();

assert!((vel.length() - speed).abs() < 1e-15);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

Source

fn get_pqw_velocity_at_outgoing_asymptote(&self) -> DVec2

Gets the velocity at the outgoing asymptote of the trajectory in the perifocal coordinate system.

§Perifocal Coordinate System

This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

If you want to get the vector in the regular coordinate system instead, use get_velocity_at_outgoing_asymptote instead.

§Unchecked Operation

This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).

§Performance

This function is very performant and should not be the cause of any performance issues.

Alternatively, if you only want to know the speed, use get_speed_at_infinity instead.

§Example
use keplerian_sim::{Orbit, OrbitTrait};
use glam::DVec2;

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);

let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_pqw_velocity_at_outgoing_asymptote();

assert!((vel.length() - speed).abs() < 1e-15);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

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.
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_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec2

Gets the velocity at a given mean anomaly in the orbit in the perifocal coordinate system.

§Perifocal Coordinate System

This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

If you want to get the vector in the regular coordinate system instead, use get_velocity_at_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 method involves converting the mean anomaly into an eccentric anomaly, which uses numerical methods and so is not performant.
It is recommended to cache this value if you can. If you want to just get the speed, consider using the get_speed_at_mean_anomaly function instead.

Alternatively, if you already know the eccentric anomaly or true anomaly values, use the get_pqw_velocity_at_eccentric_anomaly and get_pqw_velocity_at_true_anomaly functions instead.
Those functions do not use numerical methods and are therefore a lot faster.

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.
The altitude is measured in meters, and measured from the center of the parent body (origin).

§sincos_angle

A tuple containing the sine and cosine (respectively) of the true anomaly of the point in the orbit.

§Perifocal Coordinate System

This function returns a vector in the perifocal coordinate (PQW) system, where the first element points to the periapsis, and the second element has a true anomaly 90 degrees past the periapsis. The third element points perpendicular to the orbital plane, and is always zero in this case, and so it is omitted.

Learn more about the PQW system: https://en.wikipedia.org/wiki/Perifocal_coordinate_system

To convert from the PQW coordinates to regular 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 less work and therefore are a lot faster.

If you want to get both the position and velocity vectors, you can use the get_state_vectors_at_true_anomaly function instead. It prevents redundant calculations and is therefore faster than calling the position and velocity functions separately.

§Angle

The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.

§Example
use keplerian_sim::{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_periapsis(&self) -> DVec3

Gets the velocity at the periapsis of the orbit.

§Performance

This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.

Alternatively, if you only want to know the speed, use get_speed_at_periapsis instead.

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);

let speed = orbit.get_speed_at_periapsis();
let vel = orbit.get_velocity_at_periapsis();

assert!((vel.length() - speed).abs() < 1e-15);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

Source

fn get_velocity_at_apoapsis(&self) -> DVec3

Gets the velocity at the apoapsis of the orbit.

§Performance

This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.

Alternatively, if you only want to know the speed, use get_speed_at_apoapsis instead.

§Open orbits (eccentricity >= 1)

This function does not handle open orbits specially, and will return a non-physical value. You might want to use the getters for the velocity at the incoming and outgoing asymptotes:

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(0.5);

let speed = orbit.get_speed_at_apoapsis();
let vel = orbit.get_velocity_at_apoapsis();

assert!((vel.length() - speed).abs() < 1e-15);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

Source

fn get_velocity_at_incoming_asymptote(&self) -> DVec3

Gets the velocity at the incoming asymptote of the trajectory.

§Performance

This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.

Alternatively, if you only want to know the speed, use get_speed_at_infinity instead.

§Unchecked Operation

This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);

let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_velocity_at_incoming_asymptote();

assert!((vel.length() - speed).abs() < 1e-15);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

Source

fn get_velocity_at_outgoing_asymptote(&self) -> DVec3

Gets the velocity at the outgoing asymptote of the trajectory.

§Performance

This function is not too performant as it uses some trigonometric operations. It is recommended to cache this value if you can.

Alternatively, if you only want to know the speed, use get_speed_at_infinity instead.

§Unchecked Operation

This function does not check that the orbit is open.
This function will return a NaN vector for closed orbits (e < 1).

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let mut orbit = Orbit::default();
orbit.set_periapsis(100.0);
orbit.set_eccentricity(1.5);

let speed = orbit.get_speed_at_infinity();
let vel = orbit.get_velocity_at_outgoing_asymptote();

assert!((vel.length() - speed).abs() < 1e-15);
§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

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_velocity_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec3

Gets the velocity at a given mean anomaly in the orbit.

§Speed vs. Velocity

Speed is not to be confused with velocity.
Speed tells you how fast something is moving, while velocity tells you how fast and in what direction it’s moving in.

§Parabolic Support

This function doesn’t consider parabolic trajectories yet.
NaNs or parabolic trajectories may be returned.

§Performance

This method involves converting the mean anomaly into an eccentric anomaly, which uses numerical methods and so is not performant.
It is recommended to cache this value if you can. If you want to just get the speed, consider using the get_speed_at_mean_anomaly function instead.

Alternatively, if you already know the eccentric anomaly or true anomaly values, use the get_velocity_at_eccentric_anomaly and get_velocity_at_true_anomaly functions instead.
Those functions do not use numerical methods and are therefore a lot faster.

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.

Note that some angles, even within 0 to tau, are impossible for hyperbolic orbits and may result in invalid values. Check for the range of angles for a hyperbolic orbit using get_true_anomaly_at_asymptote.

§Altitude

The altitude is measured in meters, and measured from the center of the parent body (origin).

§Performance

This function is performant, however, if you already know the orbit’s semi-latus rectum or the cosine of the true anomaly, you can use the get_altitude_at_true_anomaly_unchecked function to skip a few steps in the calculation.

§Example
use keplerian_sim::{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.

§Altitude

The altitude is measured in meters, and measured from the center of the parent body (origin).

§Angle

The angle is expressed in radians, and ranges from 0 to tau.
Anything out of range will get wrapped around.

Note that some angles, even within 0 to tau, are impossible for hyperbolic orbits and may result in invalid values. Check for the range of angles for a hyperbolic orbit using get_true_anomaly_at_asymptote.

§Performance

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

§Example
use keplerian_sim::{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.

§Altitude

The altitude is measured in meters, and measured from the center of the parent body (origin).

§Performance

This function is not too performant as it uses a few trigonometric operations. It is recommended to cache this value if you can.

Alternatively, if you already know the true anomaly, use the get_altitude_at_true_anomaly function instead.

§Example
use keplerian_sim::{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.

§Altitude

The altitude is measured in meters, and measured from the center of the parent body (origin).

§Performance

This involves calculating the true anomaly at a given time, and so is not very performant.
It is recommended to cache this value when possible.

Alternatively, if you already know the eccentric anomaly or the true anomaly, consider using the get_altitude_at_eccentric_anomaly and get_altitude_at_true_anomaly functions instead.
Those do not use numerical methods and therefore are a lot faster.

§Parabolic Support

This function returns infinity for parabolic orbits due to how the equation for true anomaly works.

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_position_at_mean_anomaly(&self, mean_anomaly: f64) -> DVec3

Gets the 3D position at a given mean anomaly in the orbit.

§Performance

This involves calculating the true anomaly at a given time, and so is not very performant.
It is recommended to cache this value when possible.

This function benefits significantly from being in the cached version of the orbit struct.

Alternatively, if you already know the true anomaly, consider using the get_position_at_true_anomaly function instead.
That does not use numerical methods and therefore is a lot faster.

If you want to get both the position and velocity vectors, you can use the get_state_vectors_at_mean_anomaly function instead. It prevents redundant calculations and is therefore faster than calling the position and velocity functions separately.

§Parabolic Support

This function returns non-finite numbers for parabolic orbits due to how the equation for true anomaly works.

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.
The altitude is measured in meters, and measured from the center of the parent body (origin).

§q_mult

This parameter is a multiplier for the second element in the velocity PQW vector.
For elliptic orbits, it should be calculated by the formula sqrt(1 - e^2), where e is the eccentricity of the orbit.
For hyperbolic orbits, it should be calculated by the formula sqrt(e^2 - 1), where e is the eccentricity of the orbit.
Alternatively, for the general case, you can use the formula sqrt(abs(1 - e^2)).

§trig_ecc_anom

For elliptic orbits, this parameter should be a tuple containing the sine and cosine values of the eccentric anomaly, respectively.
For hyperbolic orbits, this parameter should be a tuple containing the hyperbolic sine and hyperbolic cosine values of the eccentric anomaly, respectively.

§sincos_angle

This parameter should be calculated by passing the true anomaly into f64::sin_cos():

let true_anomaly: f64 = 1.25; // Example value
let sincos_angle = true_anomaly.sin_cos();
§Performance

This function, by itself, is very performant and should not be the cause of any performance issues.

§Parabolic Support

This function doesn’t support parabolic trajectories yet.
NaNs or nonsensical values may be returned.

§Example
use keplerian_sim::{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 get_time_at_mean_anomaly(&self, mean_anomaly: f64) -> f64

Gets the time of the orbit at a certain mean anomaly.

§Time

The time is measured in seconds.

§Performance

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

§Example
use keplerian_sim::{Orbit, OrbitTrait};

let orbit = Orbit::new_flat(
    2.1, // Eccentricity
    5.0, // Periapsis
    2.9, // Argument of periapsis
    1.0, // Mean anomaly at epoch
    1.0, // Gravitational parameter
);

const TIME: f64 = 2.0;

let mean_anomaly = orbit.get_mean_anomaly_at_time(TIME);
let time_result = orbit.get_time_at_mean_anomaly(mean_anomaly);

const TOLERANCE: f64 = 1e-15;

assert!(
    (time_result - TIME).abs() < TOLERANCE
);
Source

fn get_time_at_eccentric_anomaly(&self, eccentric_anomaly: f64) -> f64

Gets the time of the orbit at a certain eccentric anomaly.

§Time

The time is measured in seconds.

§Performance

This function is not too performant as it performs some trigonometry.
Alternatively, if you already have the mean anomaly, you can instead use that along with get_time_at_mean_anomaly. Or if you know sin(eccentric_anomaly) or sinh(eccentric_anomaly) beforehand, you may use get_mean_anomaly_at_elliptic_eccentric_anomaly and get_mean_anomaly_at_hyperbolic_eccentric_anomaly instead, for closed and hyperbolic orbits respectively.

Those functions do not do trigonometry and are therefore a lot faster.

Source

fn get_time_at_true_anomaly(&self, true_anomaly: f64) -> f64

Gets the time of the orbit at a certain true anomaly.

§Time

The time is measured in seconds.

§Performance

This function is not too performant as it performs some trigonometry. Alternatively, if you already have the mean anomaly, you can instead use that along with get_time_at_mean_anomaly.
Or if you already have the eccentric anomaly, you can instead use that along with get_time_at_eccentric_anomaly.

Those functions are faster as they do less trigonometry (and in the case of the first one: no trig whatsoever).

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 is_circular(&self) -> bool

Gets whether or not the orbit is circular.

A circular orbit has an eccentricity of 0.

Source

fn is_elliptic(&self) -> bool

Gets whether or not the orbit is strictly elliptic.

A strictly elliptic orbit has an eccentricity between 0 and 1.

For getting whether or not the orbit is circular or elliptic, use is_closed

Source

fn is_closed(&self) -> bool

Gets whether or not the orbit is closed.

A closed orbit can be either circular or elliptic, i.e. has an eccentricity of less than 1.

For getting whether or not the orbit is circular (e = 0), use is_circular.

For getting whether or not the orbit is strictly elliptic (0 < e < 1), use is_elliptic.

Source

fn is_parabolic(&self) -> bool

Gets whether or not the trajectory is parabolic.

A parabolic trajectory has an eccentricity of exactly 1.

Source

fn is_hyperbolic(&self) -> bool

Gets whether or not the trajectory is hyperbolic.

A hyperbolic trajectory has an eccentricity of greater than 1.

For getting whether or not the trajectory is open — i.e., has an eccentricity of at least 1 — use is_open.

Source

fn is_open(&self) -> bool

Gets whether or not the trajectory is open.

An open trajectory has an eccentricity of at least 1, i.e., is either a parabolic trajectory or a hyperbolic trajectory.

For getting whether or not a trajectory is parabolic (e = 1), use is_parabolic.

For getting whether or not a trajectory is hyperbolic (e > 1), use is_hyperbolic.

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 is unlikely to be the cause of any performance issues.

Implementors§