use super::bias;
use affn::Rotation3;
const ICRS_TO_GALACTIC: Rotation3 = Rotation3::from_matrix_unchecked([
[
-0.054_875_560_416_215_37,
-0.873_437_090_234_885,
-0.483_835_015_548_713_2,
],
[
0.494_109_427_875_583_7,
-0.444_829_629_960_011_2,
0.746_982_244_497_219,
],
[
-0.867_666_149_019_004_7,
-0.198_076_373_431_201_53,
0.455_983_776_175_066_9,
],
]);
#[inline]
pub(crate) fn icrs_to_galactic() -> Rotation3 {
ICRS_TO_GALACTIC
}
#[inline]
pub(crate) fn galactic_to_icrs() -> Rotation3 {
ICRS_TO_GALACTIC.inverse()
}
#[inline]
pub(crate) fn equatorial_j2000_to_galactic() -> Rotation3 {
icrs_to_galactic() * bias::frame_bias_j2000_to_icrs()
}
#[inline]
pub(crate) fn galactic_to_equatorial_j2000() -> Rotation3 {
equatorial_j2000_to_galactic().inverse()
}
#[inline]
pub(crate) fn ecliptic_j2000_to_galactic() -> Rotation3 {
icrs_to_galactic() * bias::ecliptic_j2000_to_icrs()
}
#[inline]
pub(crate) fn galactic_to_ecliptic_j2000() -> Rotation3 {
ecliptic_j2000_to_galactic().inverse()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn icrs_galactic_roundtrip_is_identity() {
let v = [0.3, -0.4, 0.5];
let fwd = icrs_to_galactic().apply_array(v);
let back = galactic_to_icrs().apply_array(fwd);
for k in 0..3 {
assert!((back[k] - v[k]).abs() < 1e-14);
}
}
#[test]
fn galactic_north_pole_maps_to_positive_galactic_z() {
const GALACTIC_NORTH_POLE_RA_DEG: f64 = 192.859_48;
const GALACTIC_NORTH_POLE_DEC_DEG: f64 = 27.128_25;
let ra = GALACTIC_NORTH_POLE_RA_DEG.to_radians();
let dec = GALACTIC_NORTH_POLE_DEC_DEG.to_radians();
let v = [dec.cos() * ra.cos(), dec.cos() * ra.sin(), dec.sin()];
let out = icrs_to_galactic().apply_array(v);
assert!(out[0].abs() < 1e-9);
assert!(out[1].abs() < 1e-9);
assert!((out[2] - 1.0).abs() < 1e-12);
}
#[test]
fn matrix_matches_sofa_icrs2g_reference_values() {
let m = icrs_to_galactic();
let expected = [
[
-0.054_875_560_416_215_37,
-0.873_437_090_234_885,
-0.483_835_015_548_713_2,
],
[
0.494_109_427_875_583_7,
-0.444_829_629_960_011_2,
0.746_982_244_497_219,
],
[
-0.867_666_149_019_004_7,
-0.198_076_373_431_201_53,
0.455_983_776_175_066_9,
],
];
for (actual_row, expected_row) in m.as_matrix().iter().zip(expected) {
for (actual, expected) in actual_row.iter().zip(expected_row) {
assert!((actual - expected).abs() < 1e-16);
}
}
}
}