1use 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}