Skip to content

Commit 50a7a3a

Browse files
committed
feat: add SSO builder and Earth ephemeris
1 parent 2876f57 commit 50a7a3a

File tree

18 files changed

+2977
-30
lines changed

18 files changed

+2977
-30
lines changed

crates/lox-core/src/anomalies.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ use lox_test_utils::approx_eq::{ApproxEq, ApproxEqResults};
2727
use thiserror::Error;
2828

2929
use crate::{
30-
Angle, AngleUnits,
3130
elements::{Eccentricity, OrbitType},
31+
units::{Angle, AngleUnits},
3232
};
3333

3434
use core::marker::PhantomData;
@@ -46,23 +46,23 @@ mod sealed {
4646
}
4747

4848
/// Marker type for true anomaly
49-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
5050
pub struct TrueKind;
5151

5252
/// Marker type for eccentric anomaly (E for elliptic, F for hyperbolic, D for parabolic)
53-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
5454
pub struct EccentricKind;
5555

5656
/// Marker type for mean anomaly
57-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
5858
pub struct MeanKind;
5959

6060
impl AnomalyKind for TrueKind {}
6161
impl AnomalyKind for EccentricKind {}
6262
impl AnomalyKind for MeanKind {}
6363

6464
/// Generic anomaly type parameterized by kind marker
65-
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
65+
#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd)]
6666
pub struct Anomaly<K: AnomalyKind> {
6767
anomaly: Angle,
6868
_kind: PhantomData<K>,

crates/lox-core/src/coords.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
// SPDX-License-Identifier: MPL-2.0
44

55
use core::f64::consts::TAU;
6+
use std::ops::{Add, Neg, Sub};
67

78
use glam::DVec3;
9+
use lox_test_utils::ApproxEq;
810
use thiserror::Error;
911

10-
use crate::{Angle, Distance, Velocity};
12+
use crate::units::{Angle, Distance, Velocity};
1113

1214
#[derive(Copy, Clone, Debug, Default, PartialEq)]
1315
pub struct AzEl(Angle, Angle);
@@ -162,7 +164,7 @@ impl LonLatAltBuilder {
162164
}
163165
}
164166

165-
#[derive(Copy, Clone, Debug, Default, PartialEq)]
167+
#[derive(Copy, Clone, Debug, Default, PartialEq, ApproxEq)]
166168
pub struct Cartesian {
167169
pos: DVec3,
168170
vel: DVec3,
@@ -270,11 +272,35 @@ impl CartesianBuilder {
270272
}
271273
}
272274

275+
impl Add for Cartesian {
276+
type Output = Self;
277+
278+
fn add(self, rhs: Self) -> Self::Output {
279+
Self::from_vecs(self.pos + rhs.pos, self.vel + rhs.vel)
280+
}
281+
}
282+
283+
impl Sub for Cartesian {
284+
type Output = Self;
285+
286+
fn sub(self, rhs: Self) -> Self::Output {
287+
Self::from_vecs(self.pos - rhs.pos, self.vel - rhs.vel)
288+
}
289+
}
290+
291+
impl Neg for Cartesian {
292+
type Output = Self;
293+
294+
fn neg(self) -> Self::Output {
295+
Self::from_vecs(-self.pos, -self.vel)
296+
}
297+
}
298+
273299
#[cfg(test)]
274300
mod tests {
275301
use rstest::rstest;
276302

277-
use crate::{AngleUnits, DistanceUnits, VelocityUnits};
303+
use crate::units::{AngleUnits, DistanceUnits, VelocityUnits};
278304

279305
use super::*;
280306

crates/lox-core/src/elements.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ use crate::anomalies::AnomalyError;
1717
use crate::anomalies::MeanAnomaly;
1818
use crate::anomalies::{EccentricAnomaly, TrueAnomaly};
1919
use crate::utils::Linspace;
20-
use crate::{Angle, AngleUnits, Distance, DistanceUnits, coords::Cartesian, glam::Azimuth};
20+
use crate::{
21+
coords::Cartesian,
22+
glam::Azimuth,
23+
units::{Angle, AngleUnits, Distance, DistanceUnits},
24+
};
2125

2226
/// The standard gravitational parameter of a celestial body µ = GM.
2327
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd, ApproxEq)]
@@ -26,17 +30,17 @@ pub struct GravitationalParameter(f64);
2630

2731
impl GravitationalParameter {
2832
/// Creates a new gravitational parameter from an `f64` value in m³/s².
29-
pub fn m3_per_s2(mu: f64) -> Self {
33+
pub const fn m3_per_s2(mu: f64) -> Self {
3034
Self(mu)
3135
}
3236

3337
/// Creates a new gravitational parameter from an `f64` value in km³/s².
34-
pub fn km3_per_s2(mu: f64) -> Self {
38+
pub const fn km3_per_s2(mu: f64) -> Self {
3539
Self(1e9 * mu)
3640
}
3741

3842
/// Returns the value of the gravitational parameters as an `f64`.
39-
pub fn as_f64(&self) -> f64 {
43+
pub const fn as_f64(&self) -> f64 {
4044
self.0
4145
}
4246
}
@@ -229,10 +233,6 @@ impl Display for ArgumentOfPeriapsis {
229233
}
230234
}
231235

232-
// enum LocalTime {
233-
// LTAN(TimeOfDay)
234-
// }
235-
236236
#[derive(Debug, Clone, Copy, PartialEq, ApproxEq)]
237237
pub struct Keplerian {
238238
semi_major_axis: SemiMajorAxis,
@@ -266,8 +266,6 @@ impl Keplerian {
266266
KeplerianBuilder::default()
267267
}
268268

269-
// pub fn from_sso(altitude: Distance, eccentricity: Eccentricity, ) -> Result<Self, ()> {}
270-
271269
pub fn semi_major_axis(&self) -> SemiMajorAxis {
272270
self.semi_major_axis
273271
}
@@ -571,7 +569,7 @@ impl KeplerianBuilder {
571569
mod tests {
572570
use lox_test_utils::assert_approx_eq;
573571

574-
use crate::VelocityUnits;
572+
use crate::units::VelocityUnits;
575573

576574
use super::*;
577575

crates/lox-core/src/f64/consts.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
* Time conversion constants
1010
*/
1111

12+
/// Number of days in a Julian year.
13+
pub const DAYS_PER_JULIAN_YEAR: f64 = 365.25;
14+
1215
/// Number of days in a Julian century.
13-
pub const DAYS_PER_JULIAN_CENTURY: f64 = 36525.0;
16+
pub const DAYS_PER_JULIAN_CENTURY: f64 = DAYS_PER_JULIAN_YEAR * 100.0;
1417

1518
/// Number of seconds in a minute.
1619
pub const SECONDS_PER_MINUTE: f64 = 60.0;
@@ -22,7 +25,7 @@ pub const SECONDS_PER_HOUR: f64 = SECONDS_PER_MINUTE * 60.0;
2225
pub const SECONDS_PER_DAY: f64 = SECONDS_PER_HOUR * 24.0;
2326

2427
/// Number of seconds in a Julian year (365.25 days).
25-
pub const SECONDS_PER_JULIAN_YEAR: f64 = SECONDS_PER_DAY * 365.25;
28+
pub const SECONDS_PER_JULIAN_YEAR: f64 = SECONDS_PER_DAY * DAYS_PER_JULIAN_YEAR;
2629

2730
/// Number of seconds in a Julian century.
2831
pub const SECONDS_PER_JULIAN_CENTURY: f64 = SECONDS_PER_JULIAN_YEAR * 100.0;

crates/lox-core/src/glam.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use glam::DVec3;
66

7-
use crate::Angle;
7+
use crate::units::Angle;
88

99
pub trait Azimuth {
1010
fn azimuth(&self) -> Angle;

crates/lox-core/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,3 @@ pub mod time;
2424
pub mod types;
2525
pub mod units;
2626
pub mod utils;
27-
28-
pub use crate::units::*;

crates/lox-core/src/time/calendar_dates.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{
1616
};
1717

1818
use crate::{
19-
f64::consts::{self, SECONDS_PER_JULIAN_CENTURY},
19+
f64::consts::{self, SECONDS_PER_JULIAN_CENTURY, SECONDS_PER_JULIAN_YEAR},
2020
i64::consts::{
2121
SECONDS_BETWEEN_J1950_AND_J2000, SECONDS_BETWEEN_JD_AND_J2000,
2222
SECONDS_BETWEEN_MJD_AND_J2000,
@@ -264,6 +264,7 @@ impl JulianDate for Date {
264264
match unit {
265265
Unit::Seconds => seconds,
266266
Unit::Days => seconds / consts::SECONDS_PER_DAY,
267+
Unit::Years => seconds / SECONDS_PER_JULIAN_YEAR,
267268
Unit::Centuries => seconds / SECONDS_PER_JULIAN_CENTURY,
268269
}
269270
}

crates/lox-core/src/time/deltas.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ impl JulianDate for TimeDelta {
432432
match unit {
433433
Unit::Seconds => seconds,
434434
Unit::Days => seconds / f64::consts::SECONDS_PER_DAY,
435+
Unit::Years => seconds / f64::consts::SECONDS_PER_JULIAN_YEAR,
435436
Unit::Centuries => seconds / f64::consts::SECONDS_PER_JULIAN_CENTURY,
436437
}
437438
}

crates/lox-core/src/time/julian_dates.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub enum Epoch {
2727
pub enum Unit {
2828
Seconds,
2929
Days,
30+
Years,
3031
Centuries,
3132
}
3233

@@ -88,6 +89,26 @@ pub trait JulianDate {
8889
self.julian_date(Epoch::J2000, Unit::Days)
8990
}
9091

92+
/// Returns the number of years since the Julian epoch as an `f64`.
93+
fn years_since_julian_epoch(&self) -> f64 {
94+
self.julian_date(Epoch::JulianDate, Unit::Years)
95+
}
96+
97+
/// Returns the number of years since the Modified Julian epoch as an `f64`.
98+
fn years_since_modified_julian_epoch(&self) -> f64 {
99+
self.julian_date(Epoch::ModifiedJulianDate, Unit::Years)
100+
}
101+
102+
/// Returns the number of years since J1950 as an `f64`.
103+
fn years_since_j1950(&self) -> f64 {
104+
self.julian_date(Epoch::J1950, Unit::Years)
105+
}
106+
107+
/// Returns the number of years since J2000 as an `f64`.
108+
fn years_since_j2000(&self) -> f64 {
109+
self.julian_date(Epoch::J2000, Unit::Years)
110+
}
111+
91112
/// Returns the number of centuries since the Julian epoch as an `f64`.
92113
fn centuries_since_julian_epoch(&self) -> f64 {
93114
self.julian_date(Epoch::JulianDate, Unit::Centuries)

crates/lox-core/src/time/time_of_day.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,19 @@ pub struct TimeOfDay {
117117
}
118118

119119
impl TimeOfDay {
120+
pub const MIDNIGHT: Self = TimeOfDay {
121+
hour: 0,
122+
minute: 0,
123+
second: 0,
124+
subsecond: Subsecond::ZERO,
125+
};
126+
127+
pub const NOON: Self = TimeOfDay {
128+
hour: 12,
129+
minute: 0,
130+
second: 0,
131+
subsecond: Subsecond::ZERO,
132+
};
120133
/// Constructs a new `TimeOfDay` instance from the given hour, minute, and second components.
121134
///
122135
/// # Errors

0 commit comments

Comments
 (0)