use crate::consts;
use crate::AstroTime;
use crate::TimeScale;
use nalgebra as na;
pub fn pos_gcrf(time: &AstroTime) -> na::Vector3<f64> {
let t: f64 = (time.to_jd(TimeScale::TDB) - 2451545.0) / 36525.0;
#[allow(non_upper_case_globals)]
const deg2rad: f64 = std::f64::consts::PI / 180.;
let lambda_ecliptic: f64 = deg2rad
* (218.32 + 481267.8813 * t + 6.29 * f64::sin(deg2rad * (134.9 + 477198.85 * t))
- 1.27 * f64::sin(deg2rad * (259.2 - 413335.38 * t))
+ 0.66 * f64::sin(deg2rad * (235.7 + 890534.23 * t))
+ 0.21 * f64::sin(deg2rad * (269.9 + 954397.70 * t))
- 0.19 * f64::sin(deg2rad * (357.5 + 35999.05 * t))
- 0.11 * f64::sin(deg2rad * (186.6 + 966404.05 * t)));
let phi_ecliptic: f64 = deg2rad
* (5.13 * f64::sin(deg2rad * (93.3 + 483202.03 * t))
+ 0.28 * f64::sin(deg2rad * (228.2 + 960400.87 * t))
- 0.28 * f64::sin(deg2rad * (318.3 + 6003.18 * t))
- 0.17 * f64::sin(deg2rad * (217.6 - 407332.20 * t)));
let hparallax: f64 = deg2rad
* (0.9508
+ 0.0518 * f64::cos(deg2rad * (134.9 + 477198.85 * t))
+ 0.0095 * f64::cos(deg2rad * (259.2 - 413335.38 * t))
+ 0.0078 * f64::cos(deg2rad * (235.7 + 890534.23 * t))
+ 0.0028 * f64::cos(deg2rad * (269.9 + 954397.70 * t)));
let epsilon: f64 =
deg2rad * (23.439291 - 0.0130042 * t - 1.64e-7 * t * t + 5.04E-7 * t * t * t);
let rmag: f64 = consts::EARTH_RADIUS / f64::sin(hparallax);
rmag * na::Vector3::<f64>::new(
f64::cos(phi_ecliptic) * f64::cos(lambda_ecliptic),
f64::cos(epsilon) * f64::cos(phi_ecliptic) * f64::sin(lambda_ecliptic)
- f64::sin(epsilon) * f64::sin(phi_ecliptic),
f64::sin(epsilon) * f64::cos(phi_ecliptic) * f64::sin(lambda_ecliptic)
+ f64::cos(epsilon) * f64::sin(phi_ecliptic),
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn moonpos() {
let t0 = AstroTime::from_date(1994, 4, 28);
let t = AstroTime::from_mjd(t0.to_mjd(TimeScale::UTC), TimeScale::TDB);
let pos = pos_gcrf(&t);
let ref_pos = vec![-134240.626E3, -311571.590E3, -126693.785E3];
for idx in 0..3 {
let err = f64::abs(pos[idx] / ref_pos[idx] - 1.0);
assert!(err < 1.0e-6);
}
}
}