erfa_rust/
G15_safe.rs

1// G15
2//   fad03.c   → eraFad03_safe
3//   fae03.c   → eraFae03_safe
4//   faf03.c   → eraFaf03_safe
5//   faju03.c  → eraFaju03_safe
6//   fal03.c   → eraFal03_safe
7//   falp03.c  → eraFalp03_safe
8//   fama03.c  → eraFama03_safe
9//   fame03.c  → eraFame03_safe
10//   fane03.c  → eraFane03_safe
11//   faom03.c  → eraFaom03_safe
12//   fapa03.c  → eraFapa03_safe
13//   fasa03.c  → eraFasa03_safe
14//   faur03.c  → eraFaur03_safe
15//   fave03.c  → eraFave03_safe
16//   fk5hip.c  → eraFk5hip_safe
17
18use crate::G28_safe::eraRv2m_safe;
19use crate::H1_safe::{ERFA_D2PI, ERFA_DAS2R, ERFA_TURNAS};
20
21pub type ErfaResult<T> = Result<T, ()>;
22
23// Positive modulus for angles; ensures result in [0,y).
24#[inline]
25fn fmod_pos(x: f64, y: f64) -> f64 {
26    let r = x % y;
27    if r < 0.0 {
28        r + y
29    } else {
30        r
31    }
32}
33
34// Mean elongation of the Moon from the Sun (radians).
35pub fn eraFad03_safe(t: f64) -> ErfaResult<f64> {
36    let a = 1_072_260.703_692
37        + t * (1_602_961_601.2090 + t * (-6.3706 + t * (0.006_593 + t * (-0.000_031_69))));
38    let r = (a % ERFA_TURNAS) * ERFA_DAS2R;
39    Ok(r)
40}
41
42// Mean longitude of Earth (radians in [0,2π)).
43pub fn eraFae03_safe(t: f64) -> ErfaResult<f64> {
44    Ok(fmod_pos(1.753_470_314 + 628.307_584_9991 * t, ERFA_D2PI))
45}
46
47// Mean longitude of the Moon minus the ascending node (radians).
48pub fn eraFaf03_safe(t: f64) -> ErfaResult<f64> {
49    let a = 335_779.526_232
50        + t * (1_739_527_262.8478 + t * (-12.7512 + t * (-0.001_037 + t * (0.000_004_17))));
51    Ok(fmod_pos(a, ERFA_TURNAS) * ERFA_DAS2R)
52}
53
54// Mean longitude of Jupiter (radians in [0,2π)).
55pub fn eraFaju03_safe(t: f64) -> ErfaResult<f64> {
56    Ok(fmod_pos(0.599_546_497 + 52.969_096_2641 * t, ERFA_D2PI))
57}
58
59// Mean anomaly of the Moon (radians).
60pub fn eraFal03_safe(t: f64) -> ErfaResult<f64> {
61    let a = 485_868.249_036
62        + t * (1_717_915_923.2178 + t * (31.8792 + t * (0.051_635 + t * (-0.000_244_70))));
63    Ok(fmod_pos(a, ERFA_TURNAS) * ERFA_DAS2R)
64}
65
66// Mean anomaly of the Sun (radians).
67pub fn eraFalp03_safe(t: f64) -> ErfaResult<f64> {
68    let a = 1_287_104.793_048
69        + t * (129_596_581.0481 + t * (-0.5532 + t * (0.000_136 + t * (-0.000_011_49))));
70    Ok(fmod_pos(a, ERFA_TURNAS) * ERFA_DAS2R)
71}
72
73// Mean longitude of Mars (radians in [0,2π)).
74pub fn eraFama03_safe(t: f64) -> ErfaResult<f64> {
75    Ok(fmod_pos(6.203_480_913 + 334.061_242_6700 * t, ERFA_D2PI))
76}
77
78// Mean longitude of Mercury (radians in [0,2π)).
79pub fn eraFame03_safe(t: f64) -> ErfaResult<f64> {
80    Ok(fmod_pos(4.402_608_842 + 2_608.790_314_1574 * t, ERFA_D2PI))
81}
82
83// Mean longitude of Neptune (radians in [0,2π)).
84pub fn eraFane03_safe(t: f64) -> ErfaResult<f64> {
85    Ok(fmod_pos(5.311_886_287 + 3.813_303_5638 * t, ERFA_D2PI))
86}
87
88// Mean longitude of the Moons ascending node (radians).
89pub fn eraFaom03_safe(t: f64) -> ErfaResult<f64> {
90    let a = 450_160.398_036
91        + t * (-6_962_890.5431 + t * (7.4722 + t * (0.007_702 + t * (-0.000_059_39))));
92    Ok((a % ERFA_TURNAS) * ERFA_DAS2R)
93}
94
95// General accumulated precession in longitude (radians).
96pub fn eraFapa03_safe(t: f64) -> ErfaResult<f64> {
97    Ok((0.024_381_750 + 0.000_005_386_91 * t) * t)
98}
99
100// Mean longitude of Saturn (radians in [0,2π)).
101pub fn eraFasa03_safe(t: f64) -> ErfaResult<f64> {
102    Ok(fmod_pos(0.874_016_757 + 21.329_910_4960 * t, ERFA_D2PI))
103}
104
105// Mean longitude of Uranus (radians in [0,2π)).
106pub fn eraFaur03_safe(t: f64) -> ErfaResult<f64> {
107    Ok(fmod_pos(5.481_293_872 + 7.478_159_8567 * t, ERFA_D2PI))
108}
109
110// Mean longitude of Venus (radians in [0,2π)).
111pub fn eraFave03_safe(t: f64) -> ErfaResult<f64> {
112    Ok(fmod_pos(3.176_146_697 + 1_021.328_554_6211 * t, ERFA_D2PI))
113}
114
115// FK5 → Hipparcos orientation matrix and spin vector.
116pub fn eraFk5hip_safe() -> ErfaResult<([[f64; 3]; 3], [f64; 3])> {
117    let epx = -19.9e-3 * ERFA_DAS2R;
118    let epy = -9.1e-3 * ERFA_DAS2R;
119    let epz = 22.9e-3 * ERFA_DAS2R;
120
121    let omx = -0.30e-3 * ERFA_DAS2R;
122    let omy = 0.60e-3 * ERFA_DAS2R;
123    let omz = 0.70e-3 * ERFA_DAS2R;
124
125    let v = [epx, epy, epz];
126    let r5h = eraRv2m_safe(&v)?;
127    let s5h = [omx, omy, omz];
128    Ok((r5h, s5h))
129}