lox_frames/transformations/
iau.rs1use crate::transformations::rotations::Rotation;
6use crate::transformations::{TransformProvider, TryTransform};
7use glam::{DMat3, DVec3};
8use lox_bodies::TryRotationalElements;
9use lox_time::Time;
10use lox_time::offsets::TryOffset;
11use lox_time::time_scales::Tdb;
12use lox_time::{julian_dates::JulianDate, time_scales::TimeScale};
13use std::f64::consts::{FRAC_PI_2, TAU};
14
15use crate::frames::{Iau, Icrf};
16
17pub fn icrf_to_iau(
18 right_ascension: f64,
19 declination: f64,
20 rotation_angle: f64,
21 right_ascension_rate: f64,
22 declination_rate: f64,
23 rotation_rate: f64,
24) -> Rotation {
25 let m1 = DMat3::from_rotation_z(-(right_ascension + FRAC_PI_2));
26 let m2 = DMat3::from_rotation_x(-(FRAC_PI_2 - declination));
27 let m3 = DMat3::from_rotation_z(-(rotation_angle % TAU));
28 let m = m3 * m2 * m1;
29 let v = DVec3::new(right_ascension_rate, -declination_rate, rotation_rate);
30 Rotation::new(m).with_angular_velocity(v)
31}
32
33impl<T, Scale, Origin> TryTransform<Icrf, Iau<Origin>, Scale> for T
34where
35 Scale: TimeScale + Copy,
36 Origin: TryRotationalElements + Copy,
37 T: TransformProvider + TryOffset<Scale, Tdb>,
38{
39 type Error = <Self as TryOffset<Scale, Tdb>>::Error;
40
41 fn try_transform(
42 &self,
43 _origin: Icrf,
44 target: Iau<Origin>,
45 time: Time<Scale>,
46 ) -> Result<Rotation, Self::Error> {
47 let seconds = time.try_to_scale(Tdb, self)?.seconds_since_j2000();
48
49 let (right_ascension, declination, rotation_angle) = target.rotational_elements(seconds);
50 let (right_ascension_rate, declination_rate, rotation_rate) =
51 target.rotational_element_rates(seconds);
52 Ok(icrf_to_iau(
53 right_ascension,
54 declination,
55 rotation_angle,
56 right_ascension_rate,
57 declination_rate,
58 rotation_rate,
59 ))
60 }
61}
62
63impl<T, Scale, Origin> TryTransform<Iau<Origin>, Icrf, Scale> for T
64where
65 Scale: TimeScale,
66 Origin: TryRotationalElements,
67 T: TryTransform<Icrf, Iau<Origin>, Scale> + TryOffset<Scale, Tdb>,
68{
69 type Error = <Self as TryTransform<Icrf, Iau<Origin>, Scale>>::Error;
70
71 fn try_transform(
72 &self,
73 origin: Iau<Origin>,
74 target: Icrf,
75 time: Time<Scale>,
76 ) -> Result<Rotation, Self::Error> {
77 Ok(self.try_transform(target, origin, time)?.transpose())
78 }
79}