Skip to main content

pykep_core/astro/elements/
values.rs

1// Copyright (c) 2026 pykep-rust contributors
2// SPDX-License-Identifier: MPL-2.0
3
4use crate::Elements6;
5
6/// Classical Keplerian elements `[a, e, i, Ω, ω, ν]`.
7///
8/// `a` is the semi-major axis in the caller's length unit, `e` is
9/// dimensionless, and all four angles are radians. Ellipses use `a > 0` and
10/// `0 <= e < 1`; hyperbolae use `a < 0` and `e > 1`.
11#[derive(Clone, Copy, Debug, PartialEq)]
12pub struct ClassicalElements {
13    /// Semi-major axis.
14    pub semi_major_axis: f64,
15    /// Eccentricity.
16    pub eccentricity: f64,
17    /// Inclination in `[0, π]`.
18    pub inclination: f64,
19    /// Longitude of the ascending node.
20    pub longitude_ascending_node: f64,
21    /// Argument of periapsis.
22    pub argument_periapsis: f64,
23    /// True anomaly.
24    pub true_anomaly: f64,
25}
26
27impl ClassicalElements {
28    /// Constructs a classical-element value in `[a, e, i, Ω, ω, ν]` order.
29    #[must_use]
30    pub const fn new(
31        semi_major_axis: f64,
32        eccentricity: f64,
33        inclination: f64,
34        longitude_ascending_node: f64,
35        argument_periapsis: f64,
36        true_anomaly: f64,
37    ) -> Self {
38        Self {
39            semi_major_axis,
40            eccentricity,
41            inclination,
42            longitude_ascending_node,
43            argument_periapsis,
44            true_anomaly,
45        }
46    }
47
48    /// Returns `[a, e, i, Ω, ω, ν]`.
49    #[must_use]
50    pub const fn to_array(self) -> Elements6 {
51        [
52            self.semi_major_axis,
53            self.eccentricity,
54            self.inclination,
55            self.longitude_ascending_node,
56            self.argument_periapsis,
57            self.true_anomaly,
58        ]
59    }
60}
61
62impl From<Elements6> for ClassicalElements {
63    fn from(values: Elements6) -> Self {
64        Self::new(
65            values[0], values[1], values[2], values[3], values[4], values[5],
66        )
67    }
68}
69
70impl From<ClassicalElements> for Elements6 {
71    fn from(elements: ClassicalElements) -> Self {
72        elements.to_array()
73    }
74}
75
76/// Modified equinoctial elements `[p, f, g, h, k, L]`.
77///
78/// `p` is the positive semilatus rectum in the caller's length unit; `f`,
79/// `g`, `h`, and `k` are dimensionless; and true longitude `L` is radians.
80/// The prograde convention is singular at inclination `π`, while the
81/// retrograde convention is singular at inclination zero.
82#[derive(Clone, Copy, Debug, PartialEq)]
83pub struct ModifiedEquinoctialElements {
84    /// Semilatus rectum.
85    pub semilatus_rectum: f64,
86    /// First eccentricity component.
87    pub f: f64,
88    /// Second eccentricity component.
89    pub g: f64,
90    /// First inclination component.
91    pub h: f64,
92    /// Second inclination component.
93    pub k: f64,
94    /// True longitude.
95    pub true_longitude: f64,
96}
97
98impl ModifiedEquinoctialElements {
99    /// Constructs a modified-equinoctial value in `[p, f, g, h, k, L]` order.
100    #[must_use]
101    pub const fn new(
102        semilatus_rectum: f64,
103        f: f64,
104        g: f64,
105        h: f64,
106        k: f64,
107        true_longitude: f64,
108    ) -> Self {
109        Self {
110            semilatus_rectum,
111            f,
112            g,
113            h,
114            k,
115            true_longitude,
116        }
117    }
118
119    /// Returns `[p, f, g, h, k, L]`.
120    #[must_use]
121    pub const fn to_array(self) -> Elements6 {
122        [
123            self.semilatus_rectum,
124            self.f,
125            self.g,
126            self.h,
127            self.k,
128            self.true_longitude,
129        ]
130    }
131}
132
133impl From<Elements6> for ModifiedEquinoctialElements {
134    fn from(values: Elements6) -> Self {
135        Self::new(
136            values[0], values[1], values[2], values[3], values[4], values[5],
137        )
138    }
139}
140
141impl From<ModifiedEquinoctialElements> for Elements6 {
142    fn from(elements: ModifiedEquinoctialElements) -> Self {
143        elements.to_array()
144    }
145}