use std::ops::Rem;
use crate::consts::{D2PI, DAS2R, DJ00, DJC};
use crate::vm::anpm;
struct Coeff {
nl: i32,
nlp: i32,
nf: i32,
nd: i32,
nom: i32,
sp: f64,
spt: f64,
ce: f64,
cet: f64,
}
impl Coeff {
const fn new(
nl: i32,
nlp: i32,
nf: i32,
nd: i32,
nom: i32,
sp: f64,
spt: f64,
ce: f64,
cet: f64,
) -> Self {
Self {
nl,
nlp,
nf,
nd,
nom,
sp,
spt,
ce,
cet,
}
}
}
const X: [Coeff; 106] = [
Coeff::new(0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9),
Coeff::new(0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5),
Coeff::new(-2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0),
Coeff::new(2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0),
Coeff::new(-2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0),
Coeff::new(1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0),
Coeff::new(0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0),
Coeff::new(2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1),
Coeff::new(0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1),
Coeff::new(0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6),
Coeff::new(0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3),
Coeff::new(0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0),
Coeff::new(2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0),
Coeff::new(0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0),
Coeff::new(0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0),
Coeff::new(0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0),
Coeff::new(0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0),
Coeff::new(0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0),
Coeff::new(-2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0),
Coeff::new(0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0),
Coeff::new(2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0),
Coeff::new(0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0),
Coeff::new(1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0),
Coeff::new(2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0),
Coeff::new(-1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5),
Coeff::new(1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0),
Coeff::new(0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0),
Coeff::new(1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1),
Coeff::new(1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0),
Coeff::new(-1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0),
Coeff::new(0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0),
Coeff::new(1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0),
Coeff::new(-1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0),
Coeff::new(-1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0),
Coeff::new(1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0),
Coeff::new(0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0),
Coeff::new(2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0),
Coeff::new(1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0),
Coeff::new(2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0),
Coeff::new(0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0),
Coeff::new(-1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0),
Coeff::new(-1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0),
Coeff::new(1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0),
Coeff::new(-1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0),
Coeff::new(1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0),
Coeff::new(0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0),
Coeff::new(1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0),
Coeff::new(1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0),
Coeff::new(2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0),
Coeff::new(0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0),
Coeff::new(0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0),
Coeff::new(1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0),
Coeff::new(0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0),
Coeff::new(1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0),
Coeff::new(2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0),
Coeff::new(0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0),
Coeff::new(1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0),
Coeff::new(1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0),
Coeff::new(1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0),
Coeff::new(1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0),
Coeff::new(-1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0),
Coeff::new(-2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0),
Coeff::new(3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0),
Coeff::new(0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0),
Coeff::new(1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0),
Coeff::new(-1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0),
Coeff::new(2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0),
Coeff::new(1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0),
Coeff::new(3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0),
Coeff::new(-1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0),
Coeff::new(1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(-2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0),
Coeff::new(-1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0),
Coeff::new(2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0),
Coeff::new(1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0),
Coeff::new(-2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0),
Coeff::new(-1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0),
Coeff::new(1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0),
Coeff::new(2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0),
Coeff::new(2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0),
Coeff::new(1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0),
Coeff::new(3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0),
Coeff::new(1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0),
Coeff::new(-1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0),
Coeff::new(1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0),
Coeff::new(1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0),
Coeff::new(2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0),
Coeff::new(0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0),
];
pub fn nut80(date1: f64, date2: f64) -> (f64, f64) {
const U2R: f64 = DAS2R / 1e4;
const NT: usize = X.len();
let t = ((date1 - DJ00) + date2) / DJC;
let el = anpm(
(485866.733 + (715922.633 + (31.310 + 0.064 * t) * t) * t) * DAS2R
+ (1325.0 * t).rem(1.0) * D2PI,
);
let elp = anpm(
(1287099.804 + (1292581.224 + (-0.577 - 0.012 * t) * t) * t) * DAS2R
+ (99.0 * t).rem(1.0) * D2PI,
);
let f = anpm(
(335778.877 + (295263.137 + (-13.257 + 0.011 * t) * t) * t) * DAS2R
+ (1342.0 * t).rem(1.0) * D2PI,
);
let d = anpm(
(1072261.307 + (1105601.328 + (-6.891 + 0.019 * t) * t) * t) * DAS2R
+ (1236.0 * t).rem(1.0) * D2PI,
);
let om = anpm(
(450160.280 + (-482890.539 + (7.455 + 0.008 * t) * t) * t) * DAS2R
+ (-5.0 * t).rem(1.0) * D2PI,
);
let mut dp = 0.0;
let mut de = 0.0;
let (mut arg, mut s, mut c);
for j in (0..NT).rev() {
arg = X[j].nl as f64 * el
+ X[j].nlp as f64 * elp
+ X[j].nf as f64 * f
+ X[j].nd as f64 * d
+ X[j].nom as f64 * om;
s = X[j].sp + X[j].spt * t;
c = X[j].ce + X[j].cet * t;
if s != 0.0 {
dp += s * arg.sin();
}
if c != 0.0 {
de += c * arg.cos();
}
}
let dpsi = dp * U2R;
let deps = de * U2R;
(dpsi, deps)
}