lox_frames/
frames.rs

1// SPDX-FileCopyrightText: 2025 Helge Eichhorn <git@helgeeichhorn.de>
2//
3// SPDX-License-Identifier: MPL-2.0
4
5use lox_bodies::{RotationalElements, TryRotationalElements, UndefinedOriginPropertyError};
6
7use crate::traits::{BodyFixed, QuasiInertial, ReferenceFrame};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub struct Icrf;
11
12impl ReferenceFrame for Icrf {
13    fn name(&self) -> String {
14        "International Celestial Reference Frame".to_string()
15    }
16
17    fn abbreviation(&self) -> String {
18        "ICRF".to_string()
19    }
20
21    fn is_rotating(&self) -> bool {
22        false
23    }
24}
25
26impl QuasiInertial for Icrf {}
27
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub struct Cirf;
30
31impl ReferenceFrame for Cirf {
32    fn name(&self) -> String {
33        "Celestial Intermediate Reference Frame".to_string()
34    }
35
36    fn abbreviation(&self) -> String {
37        "CIRF".to_string()
38    }
39
40    fn is_rotating(&self) -> bool {
41        false
42    }
43}
44
45#[derive(Clone, Copy, Debug, PartialEq, Eq)]
46pub struct Tirf;
47
48impl ReferenceFrame for Tirf {
49    fn name(&self) -> String {
50        "Terrestrial Intermediate Reference Frame".to_string()
51    }
52
53    fn abbreviation(&self) -> String {
54        "TIRF".to_string()
55    }
56
57    fn is_rotating(&self) -> bool {
58        true
59    }
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq)]
63pub struct Itrf;
64
65impl ReferenceFrame for Itrf {
66    fn name(&self) -> String {
67        "International Terrestrial Reference Frame".to_string()
68    }
69
70    fn abbreviation(&self) -> String {
71        "ITRF".to_string()
72    }
73
74    fn is_rotating(&self) -> bool {
75        true
76    }
77}
78
79impl BodyFixed for Itrf {}
80
81#[derive(Clone, Copy, Debug, PartialEq, Eq)]
82pub struct Iau<T: TryRotationalElements>(T);
83
84impl<T> Iau<T>
85where
86    T: RotationalElements,
87{
88    pub fn new(body: T) -> Self {
89        Self(body)
90    }
91}
92
93impl<T> Iau<T>
94where
95    T: TryRotationalElements,
96{
97    pub fn try_new(body: T) -> Result<Self, UndefinedOriginPropertyError> {
98        let _ = body.try_right_ascension(0.0)?;
99        Ok(Self(body))
100    }
101
102    pub fn body(&self) -> T
103    where
104        T: Copy,
105    {
106        self.0
107    }
108
109    pub fn rotational_elements(&self, j2000: f64) -> (f64, f64, f64) {
110        self.0.try_rotational_elements(j2000).unwrap()
111    }
112
113    pub fn rotational_element_rates(&self, j2000: f64) -> (f64, f64, f64) {
114        self.0.try_rotational_element_rates(j2000).unwrap()
115    }
116}
117
118impl<T: TryRotationalElements> BodyFixed for Iau<T> {}
119
120impl<T> ReferenceFrame for Iau<T>
121where
122    T: TryRotationalElements,
123{
124    fn name(&self) -> String {
125        let body = self.0.name();
126        match body {
127            "Sun" | "Moon" => format!("IAU Body-Fixed Reference Frame for the {body}"),
128            _ => format!("IAU Body-Fixed Reference Frame for {body}"),
129        }
130    }
131
132    fn abbreviation(&self) -> String {
133        let body = self.0.name().replace([' ', '-'], "_").to_uppercase();
134        format!("IAU_{body}")
135    }
136
137    fn is_rotating(&self) -> bool {
138        true
139    }
140}