mod frame_rotations;
pub mod inertial;
pub mod random;
use crate::constants::ASEC2RAD;
use crate::time::Time;
use nalgebra::Matrix3;
use once_cell::sync::Lazy;
pub trait Frame {
fn rotation_at(&self, t: &Time) -> Matrix3<f64>;
}
pub struct IcrsFrame;
impl Frame for IcrsFrame {
fn rotation_at(&self, _t: &Time) -> Matrix3<f64> {
Matrix3::identity()
}
}
pub struct TrueEquatorFrame;
impl Frame for TrueEquatorFrame {
fn rotation_at(&self, t: &Time) -> Matrix3<f64> {
t.m_matrix()
}
}
pub struct EclipticJ2000Frame;
impl Frame for EclipticJ2000Frame {
fn rotation_at(&self, _t: &Time) -> Matrix3<f64> {
*ECLIPJ2000_MATRIX
}
}
pub struct EclipticOfDateFrame;
impl Frame for EclipticOfDateFrame {
fn rotation_at(&self, t: &Time) -> Matrix3<f64> {
let mean_obliq = crate::nutationlib::mean_obliquity(t.tdb());
let (_d_psi, d_eps) = crate::nutationlib::iau2000a_nutation(t.tt());
let true_obliq = mean_obliq + d_eps;
let (s, c) = (-true_obliq).sin_cos();
#[rustfmt::skip]
let rx = Matrix3::new(
1.0, 0.0, 0.0,
0.0, c, -s,
0.0, s, c,
);
rx * t.m_matrix()
}
}
pub struct GalacticFrame;
impl Frame for GalacticFrame {
fn rotation_at(&self, _t: &Time) -> Matrix3<f64> {
*GALACTIC_MATRIX
}
}
pub static ICRS: IcrsFrame = IcrsFrame;
pub static TRUE_EQUATOR_OF_DATE: TrueEquatorFrame = TrueEquatorFrame;
pub static ECLIPTIC_J2000: EclipticJ2000Frame = EclipticJ2000Frame;
pub static ECLIPTIC_OF_DATE: EclipticOfDateFrame = EclipticOfDateFrame;
pub static GALACTIC: GalacticFrame = GalacticFrame;
pub static ECLIPJ2000_MATRIX: Lazy<Matrix3<f64>> = Lazy::new(|| {
frame_rotations::INERTIAL_FRAMES
.get("ECLIPJ2000")
.copied()
.unwrap_or_else(Matrix3::identity)
});
pub static ECLIPJ2000_MATRIX_INV: Lazy<Matrix3<f64>> =
Lazy::new(|| ECLIPJ2000_MATRIX.try_inverse().unwrap());
static GALACTIC_MATRIX: Lazy<Matrix3<f64>> = Lazy::new(|| {
frame_rotations::INERTIAL_FRAMES
.get("GALACTIC")
.copied()
.unwrap_or_else(Matrix3::identity)
});
pub static ICRS_TO_J2000: Lazy<Matrix3<f64>> = Lazy::new(|| {
let xi0 = -0.0166170 * ASEC2RAD;
let eta0 = -0.0068192 * ASEC2RAD;
let da0 = -0.01460 * ASEC2RAD;
let yx = -da0;
let zx = xi0;
let xy = da0;
let zy = eta0;
let xz = -xi0;
let yz = -eta0;
let xx = 1.0 - 0.5 * (yx * yx + zx * zx);
let yy = 1.0 - 0.5 * (yx * yx + zy * zy);
let zz = 1.0 - 0.5 * (zy * zy + zx * zx);
Matrix3::new(xx, xy, xz, yx, yy, yz, zx, zy, zz)
});