Coverage Report

Created: 2026-09-04 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/eph/moon98.rs
Line
Count
Source
1
use crate::consts::{DAU, DD2R, DJ00, DJC};
2
use crate::pnp::pfw06;
3
use crate::vm::{ir, rx, rxpv, rz, s2pv};
4
5
///  Approximate geocentric position and velocity of the Moon.
6
///
7
///  This function is part of the International Astronomical Union's
8
///  SOFA (Standards of Fundamental Astronomy) software collection.
9
///
10
///  Status:  support function.
11
///
12
///  n.b. Not IAU-endorsed and without canonical status.
13
///
14
///  Given:
15
///     date1  double         TT date part A (Notes 1,4)
16
///     date2  double         TT date part B (Notes 1,4)
17
///
18
///  Returned:
19
///     pv     [[f64; 3]; 2]  Moon p,v, GCRS (au, au/d, Note 5)
20
///
21
0
pub fn moon98(date1: f64, date2: f64) -> [[f64; 3]; 2] {
22
    /* Moon's mean longitude (wrt mean equinox and ecliptic of date) */
23
    const ELP0: f64 = 218.31665436; /* Simon et al. (1994). */
24
    const ELP1: f64 = 481267.88123421;
25
    const ELP2: f64 = -0.0015786;
26
    const ELP3: f64 = 1.0 / 538841.0;
27
    const ELP4: f64 = -1.0 / 65194000.0;
28
29
    /* Moon's mean elongation */
30
    const D0: f64 = 297.8501921;
31
    const D1: f64 = 445267.1114034;
32
    const D2: f64 = -0.0018819;
33
    const D3: f64 = 1.0 / 545868.0;
34
    const D4: f64 = 1.0 / 113065000.0;
35
36
    /* Sun's mean anomaly */
37
    const EM0: f64 = 357.5291092;
38
    const EM1: f64 = 35999.0502909;
39
    const EM2: f64 = -0.0001536;
40
    const EM3: f64 = 1.0 / 24490000.0;
41
    const EM4: f64 = 0.0;
42
43
    /* Moon's mean anomaly */
44
    const EMP0: f64 = 134.9633964;
45
    const EMP1: f64 = 477198.8675055;
46
    const EMP2: f64 = 0.0087414;
47
    const EMP3: f64 = 1.0 / 69699.0;
48
    const EMP4: f64 = -1.0 / 14712000.0;
49
50
    /* Mean distance of the Moon from its ascending node */
51
    const F0: f64 = 93.2720950;
52
    const F1: f64 = 483202.0175233;
53
    const F2: f64 = -0.0036539;
54
    const F3: f64 = 1.0 / 3526000.0;
55
    const F4: f64 = 1.0 / 863310000.0;
56
57
    /* Meeus A_1, due to Venus (deg) */
58
    const A10: f64 = 119.75;
59
    const A11: f64 = 131.849;
60
61
    /* Meeus A_2, due to Jupiter (deg) */
62
    const A20: f64 = 53.09;
63
    const A21: f64 = 479264.290;
64
65
    /* Meeus A_3, due to sidereal motion of the Moon in longitude (deg) */
66
    const A30: f64 = 313.45;
67
    const A31: f64 = 481266.484;
68
69
    /* Coefficients for Meeus additive terms (deg) */
70
    const AL1: f64 = 0.003958;
71
    const AL2: f64 = 0.001962;
72
    const AL3: f64 = 0.000318;
73
    const AB1: f64 = -0.002235;
74
    const AB2: f64 = 0.000382;
75
    const AB3: f64 = 0.000175;
76
    const AB4: f64 = 0.000175;
77
    const AB5: f64 = 0.000127;
78
    const AB6: f64 = -0.000115;
79
80
    /* Fixed term in distance (m) */
81
    const R0: f64 = 385000560.0;
82
83
    /* Coefficients for (dimensionless) E factor */
84
    const E1: f64 = -0.002516;
85
    const E2: f64 = -0.0000074;
86
87
    struct TermLR {
88
        nd: i32,
89
        nem: i32,
90
        nemp: i32,
91
        nf: i32,
92
        coefl: f64,
93
        coefr: f64,
94
    }
95
96
    const TLR: [TermLR; 60] = [
97
        TermLR { nd: 0, nem: 0, nemp: 1, nf: 0, coefl: 6.288774, coefr: -20905355.0 },
98
        TermLR { nd: 2, nem: 0, nemp: -1, nf: 0, coefl: 1.274027, coefr: -3699111.0 },
99
        TermLR { nd: 2, nem: 0, nemp: 0, nf: 0, coefl: 0.658314, coefr: -2955968.0 },
100
        TermLR { nd: 0, nem: 0, nemp: 2, nf: 0, coefl: 0.213618, coefr: -569925.0 },
101
        TermLR { nd: 0, nem: 1, nemp: 0, nf: 0, coefl: -0.185116, coefr: 48888.0 },
102
        TermLR { nd: 0, nem: 0, nemp: 0, nf: 2, coefl: -0.114332, coefr: -3149.0 },
103
        TermLR { nd: 2, nem: 0, nemp: -2, nf: 0, coefl: 0.058793, coefr: 246158.0 },
104
        TermLR { nd: 2, nem: -1, nemp: -1, nf: 0, coefl: 0.057066, coefr: -152138.0 },
105
        TermLR { nd: 2, nem: 0, nemp: 1, nf: 0, coefl: 0.053322, coefr: -170733.0 },
106
        TermLR { nd: 2, nem: -1, nemp: 0, nf: 0, coefl: 0.045758, coefr: -204586.0 },
107
        TermLR { nd: 0, nem: 1, nemp: -1, nf: 0, coefl: -0.040923, coefr: -129620.0 },
108
        TermLR { nd: 1, nem: 0, nemp: 0, nf: 0, coefl: -0.034720, coefr: 108743.0 },
109
        TermLR { nd: 0, nem: 1, nemp: 1, nf: 0, coefl: -0.030383, coefr: 104755.0 },
110
        TermLR { nd: 2, nem: 0, nemp: 0, nf: -2, coefl: 0.015327, coefr: 10321.0 },
111
        TermLR { nd: 0, nem: 0, nemp: 1, nf: 2, coefl: -0.012528, coefr: 0.0 },
112
        TermLR { nd: 0, nem: 0, nemp: 1, nf: -2, coefl: 0.010980, coefr: 79661.0 },
113
        TermLR { nd: 4, nem: 0, nemp: -1, nf: 0, coefl: 0.010675, coefr: -34782.0 },
114
        TermLR { nd: 0, nem: 0, nemp: 3, nf: 0, coefl: 0.010034, coefr: -23210.0 },
115
        TermLR { nd: 4, nem: 0, nemp: -2, nf: 0, coefl: 0.008548, coefr: -21636.0 },
116
        TermLR { nd: 2, nem: 1, nemp: -1, nf: 0, coefl: -0.007888, coefr: 24208.0 },
117
        TermLR { nd: 2, nem: 1, nemp: 0, nf: 0, coefl: -0.006766, coefr: 30824.0 },
118
        TermLR { nd: 1, nem: 0, nemp: -1, nf: 0, coefl: -0.005163, coefr: -8379.0 },
119
        TermLR { nd: 1, nem: 1, nemp: 0, nf: 0, coefl: 0.004987, coefr: -16675.0 },
120
        TermLR { nd: 2, nem: -1, nemp: 1, nf: 0, coefl: 0.004036, coefr: -12831.0 },
121
        TermLR { nd: 2, nem: 0, nemp: 2, nf: 0, coefl: 0.003994, coefr: -10445.0 },
122
        TermLR { nd: 4, nem: 0, nemp: 0, nf: 0, coefl: 0.003861, coefr: -11650.0 },
123
        TermLR { nd: 2, nem: 0, nemp: -3, nf: 0, coefl: 0.003665, coefr: 14403.0 },
124
        TermLR { nd: 0, nem: 1, nemp: -2, nf: 0, coefl: -0.002689, coefr: -7003.0 },
125
        TermLR { nd: 2, nem: 0, nemp: -1, nf: 2, coefl: -0.002602, coefr: 0.0 },
126
        TermLR { nd: 2, nem: -1, nemp: -2, nf: 0, coefl: 0.002390, coefr: 10056.0 },
127
        TermLR { nd: 1, nem: 0, nemp: 1, nf: 0, coefl: -0.002348, coefr: 6322.0 },
128
        TermLR { nd: 2, nem: -2, nemp: 0, nf: 0, coefl: 0.002236, coefr: -9884.0 },
129
        TermLR { nd: 0, nem: 1, nemp: 2, nf: 0, coefl: -0.002120, coefr: 5751.0 },
130
        TermLR { nd: 0, nem: 2, nemp: 0, nf: 0, coefl: -0.002069, coefr: 0.0 },
131
        TermLR { nd: 2, nem: -2, nemp: -1, nf: 0, coefl: 0.002048, coefr: -4950.0 },
132
        TermLR { nd: 2, nem: 0, nemp: 1, nf: -2, coefl: -0.001773, coefr: 4130.0 },
133
        TermLR { nd: 2, nem: 0, nemp: 0, nf: 2, coefl: -0.001595, coefr: 0.0 },
134
        TermLR { nd: 4, nem: -1, nemp: -1, nf: 0, coefl: 0.001215, coefr: -3958.0 },
135
        TermLR { nd: 0, nem: 0, nemp: 2, nf: 2, coefl: -0.001110, coefr: 0.0 },
136
        TermLR { nd: 3, nem: 0, nemp: -1, nf: 0, coefl: -0.000892, coefr: 3258.0 },
137
        TermLR { nd: 2, nem: 1, nemp: 1, nf: 0, coefl: -0.000810, coefr: 2616.0 },
138
        TermLR { nd: 4, nem: -1, nemp: -2, nf: 0, coefl: 0.000759, coefr: -1897.0 },
139
        TermLR { nd: 0, nem: 2, nemp: -1, nf: 0, coefl: -0.000713, coefr: -2117.0 },
140
        TermLR { nd: 2, nem: 2, nemp: -1, nf: 0, coefl: -0.000700, coefr: 2354.0 },
141
        TermLR { nd: 2, nem: 1, nemp: -2, nf: 0, coefl: 0.000691, coefr: 0.0 },
142
        TermLR { nd: 2, nem: -1, nemp: 0, nf: -2, coefl: 0.000596, coefr: 0.0 },
143
        TermLR { nd: 4, nem: 0, nemp: 1, nf: 0, coefl: 0.000549, coefr: -1423.0 },
144
        TermLR { nd: 0, nem: 0, nemp: 4, nf: 0, coefl: 0.000537, coefr: -1117.0 },
145
        TermLR { nd: 4, nem: -1, nemp: 0, nf: 0, coefl: 0.000520, coefr: -1571.0 },
146
        TermLR { nd: 1, nem: 0, nemp: -2, nf: 0, coefl: -0.000487, coefr: -1739.0 },
147
        TermLR { nd: 2, nem: 1, nemp: 0, nf: -2, coefl: -0.000399, coefr: 0.0 },
148
        TermLR { nd: 0, nem: 0, nemp: 2, nf: -2, coefl: -0.000381, coefr: -4421.0 },
149
        TermLR { nd: 1, nem: 1, nemp: 1, nf: 0, coefl: 0.000351, coefr: 0.0 },
150
        TermLR { nd: 3, nem: 0, nemp: -2, nf: 0, coefl: -0.000340, coefr: 0.0 },
151
        TermLR { nd: 4, nem: 0, nemp: -3, nf: 0, coefl: 0.000330, coefr: 0.0 },
152
        TermLR { nd: 2, nem: -1, nemp: 2, nf: 0, coefl: 0.000327, coefr: 0.0 },
153
        TermLR { nd: 0, nem: 2, nemp: 1, nf: 0, coefl: -0.000323, coefr: 1165.0 },
154
        TermLR { nd: 1, nem: 1, nemp: -1, nf: 0, coefl: 0.000299, coefr: 0.0 },
155
        TermLR { nd: 2, nem: 0, nemp: 3, nf: 0, coefl: 0.000294, coefr: 0.0 },
156
        TermLR { nd: 2, nem: 0, nemp: -1, nf: -2, coefl: 0.000000, coefr: 8752.0 },
157
    ];
158
159
    struct TermB {
160
        nd: i32,
161
        nem: i32,
162
        nemp: i32,
163
        nf: i32,
164
        coefb: f64,
165
    }
166
167
    const TB: [TermB; 60] = [
168
        TermB { nd: 0, nem: 0, nemp: 0, nf: 1, coefb: 5.128122 },
169
        TermB { nd: 0, nem: 0, nemp: 1, nf: 1, coefb: 0.280602 },
170
        TermB { nd: 0, nem: 0, nemp: 1, nf: -1, coefb: 0.277693 },
171
        TermB { nd: 2, nem: 0, nemp: 0, nf: -1, coefb: 0.173237 },
172
        TermB { nd: 2, nem: 0, nemp: -1, nf: 1, coefb: 0.055413 },
173
        TermB { nd: 2, nem: 0, nemp: -1, nf: -1, coefb: 0.046271 },
174
        TermB { nd: 2, nem: 0, nemp: 0, nf: 1, coefb: 0.032573 },
175
        TermB { nd: 0, nem: 0, nemp: 2, nf: 1, coefb: 0.017198 },
176
        TermB { nd: 2, nem: 0, nemp: 1, nf: -1, coefb: 0.009266 },
177
        TermB { nd: 0, nem: 0, nemp: 2, nf: -1, coefb: 0.008822 },
178
        TermB { nd: 2, nem: -1, nemp: 0, nf: -1, coefb: 0.008216 },
179
        TermB { nd: 2, nem: 0, nemp: -2, nf: -1, coefb: 0.004324 },
180
        TermB { nd: 2, nem: 0, nemp: 1, nf: 1, coefb: 0.004200 },
181
        TermB { nd: 2, nem: 1, nemp: 0, nf: -1, coefb: -0.003359 },
182
        TermB { nd: 2, nem: -1, nemp: -1, nf: 1, coefb: 0.002463 },
183
        TermB { nd: 2, nem: -1, nemp: 0, nf: 1, coefb: 0.002211 },
184
        TermB { nd: 2, nem: -1, nemp: -1, nf: -1, coefb: 0.002065 },
185
        TermB { nd: 0, nem: 1, nemp: -1, nf: -1, coefb: -0.001870 },
186
        TermB { nd: 4, nem: 0, nemp: -1, nf: -1, coefb: 0.001828 },
187
        TermB { nd: 0, nem: 1, nemp: 0, nf: 1, coefb: -0.001794 },
188
        TermB { nd: 0, nem: 0, nemp: 0, nf: 3, coefb: -0.001749 },
189
        TermB { nd: 0, nem: 1, nemp: -1, nf: 1, coefb: -0.001565 },
190
        TermB { nd: 1, nem: 0, nemp: 0, nf: 1, coefb: -0.001491 },
191
        TermB { nd: 0, nem: 1, nemp: 1, nf: 1, coefb: -0.001475 },
192
        TermB { nd: 0, nem: 1, nemp: 1, nf: -1, coefb: -0.001410 },
193
        TermB { nd: 0, nem: 1, nemp: 0, nf: -1, coefb: -0.001344 },
194
        TermB { nd: 1, nem: 0, nemp: 0, nf: -1, coefb: -0.001335 },
195
        TermB { nd: 0, nem: 0, nemp: 3, nf: 1, coefb: 0.001107 },
196
        TermB { nd: 4, nem: 0, nemp: 0, nf: -1, coefb: 0.001021 },
197
        TermB { nd: 4, nem: 0, nemp: -1, nf: 1, coefb: 0.000833 },
198
        TermB { nd: 0, nem: 0, nemp: 1, nf: -3, coefb: 0.000777 },
199
        TermB { nd: 4, nem: 0, nemp: -2, nf: 1, coefb: 0.000671 },
200
        TermB { nd: 2, nem: 0, nemp: 0, nf: -3, coefb: 0.000607 },
201
        TermB { nd: 2, nem: 0, nemp: 2, nf: -1, coefb: 0.000596 },
202
        TermB { nd: 2, nem: -1, nemp: 1, nf: -1, coefb: 0.000491 },
203
        TermB { nd: 2, nem: 0, nemp: -2, nf: 1, coefb: -0.000451 },
204
        TermB { nd: 0, nem: 0, nemp: 3, nf: -1, coefb: 0.000439 },
205
        TermB { nd: 2, nem: 0, nemp: 2, nf: 1, coefb: 0.000422 },
206
        TermB { nd: 2, nem: 0, nemp: -3, nf: -1, coefb: 0.000421 },
207
        TermB { nd: 2, nem: 1, nemp: -1, nf: 1, coefb: -0.000366 },
208
        TermB { nd: 2, nem: 1, nemp: 0, nf: 1, coefb: -0.000351 },
209
        TermB { nd: 4, nem: 0, nemp: 0, nf: 1, coefb: 0.000331 },
210
        TermB { nd: 2, nem: -1, nemp: 1, nf: 1, coefb: 0.000315 },
211
        TermB { nd: 2, nem: -2, nemp: 0, nf: -1, coefb: 0.000302 },
212
        TermB { nd: 0, nem: 0, nemp: 1, nf: 3, coefb: -0.000283 },
213
        TermB { nd: 2, nem: 1, nemp: 1, nf: -1, coefb: -0.000229 },
214
        TermB { nd: 1, nem: 1, nemp: 0, nf: -1, coefb: 0.000223 },
215
        TermB { nd: 1, nem: 1, nemp: 0, nf: 1, coefb: 0.000223 },
216
        TermB { nd: 0, nem: 1, nemp: -2, nf: -1, coefb: -0.000220 },
217
        TermB { nd: 2, nem: 1, nemp: -1, nf: -1, coefb: -0.000220 },
218
        TermB { nd: 1, nem: 0, nemp: 1, nf: 1, coefb: -0.000185 },
219
        TermB { nd: 2, nem: -1, nemp: -2, nf: -1, coefb: 0.000181 },
220
        TermB { nd: 0, nem: 1, nemp: 2, nf: 1, coefb: -0.000177 },
221
        TermB { nd: 4, nem: 0, nemp: -2, nf: -1, coefb: 0.000176 },
222
        TermB { nd: 4, nem: -1, nemp: -1, nf: -1, coefb: 0.000166 },
223
        TermB { nd: 1, nem: 0, nemp: 1, nf: -1, coefb: -0.000164 },
224
        TermB { nd: 4, nem: 0, nemp: 1, nf: -1, coefb: 0.000132 },
225
        TermB { nd: 1, nem: 0, nemp: -1, nf: -1, coefb: -0.000119 },
226
        TermB { nd: 4, nem: -1, nemp: 0, nf: -1, coefb: 0.000115 },
227
        TermB { nd: 2, nem: -2, nemp: 0, nf: 1, coefb: 0.000107 },
228
    ];
229
230
0
    let mut rm = [[0.0; 3]; 3];
231
232
    /* Time since J2000.0, Julian centuries. */
233
0
    let t = ((date1 - DJ00) + date2) / DJC;
234
235
    /* Fundamental arguments (Simon et al. 1994). */
236
237
    /* Moon's mean longitude. */
238
0
    let elp = DD2R * (ELP0 + (ELP1 + (ELP2 + (ELP3 + ELP4 * t) * t) * t) * t).rem_euclid(360.0);
239
0
    let delp = DD2R * (ELP1 + (ELP2 * 2.0 + (ELP3 * 3.0 + ELP4 * 4.0 * t) * t) * t);
240
241
    /* Moon's mean elongation. */
242
0
    let d = DD2R * (D0 + (D1 + (D2 + (D3 + D4 * t) * t) * t) * t).rem_euclid(360.0);
243
0
    let dd = DD2R * (D1 + (D2 * 2.0 + (D3 * 3.0 + D4 * 4.0 * t) * t) * t);
244
245
    /* Sun's mean anomaly. */
246
0
    let em = DD2R * (EM0 + (EM1 + (EM2 + (EM3 + EM4 * t) * t) * t) * t).rem_euclid(360.0);
247
0
    let dem = DD2R * (EM1 + (EM2 * 2.0 + (EM3 * 3.0 + EM4 * 4.0 * t) * t) * t);
248
249
    /* Moon's mean anomaly. */
250
0
    let emp = DD2R * (EMP0 + (EMP1 + (EMP2 + (EMP3 + EMP4 * t) * t) * t) * t).rem_euclid(360.0);
251
0
    let demp = DD2R * (EMP1 + (EMP2 * 2.0 + (EMP3 * 3.0 + EMP4 * 4.0 * t) * t) * t);
252
253
    /* Mean distance of the Moon from its ascending node. */
254
0
    let f = DD2R * (F0 + (F1 + (F2 + (F3 + F4 * t) * t) * t) * t).rem_euclid(360.0);
255
0
    let df = DD2R * (F1 + (F2 * 2.0 + (F3 * 3.0 + F4 * 4.0 * t) * t) * t);
256
257
    /* Meeus further arguments. */
258
0
    let a1 = DD2R * (A10 + A11 * t);
259
0
    let da1 = DD2R * A11;
260
0
    let a2 = DD2R * (A20 + A21 * t);
261
0
    let da2 = DD2R * A21;
262
0
    let a3 = DD2R * (A30 + A31 * t);
263
0
    let da3 = DD2R * A31;
264
265
    /* E-factor, and square. */
266
0
    let e = 1.0 + (E1 + E2 * t) * t;
267
0
    let de = E1 + 2.0 * E2 * t;
268
0
    let esq = e * e;
269
0
    let desq = 2.0 * e * de;
270
271
    /* Use the Meeus additive terms (deg) to start off the summations. */
272
0
    let elpmf = elp - f;
273
0
    let delpmf = delp - df;
274
0
    let mut vel = AL1 * a1.sin() + AL2 * elpmf.sin() + AL3 * a2.sin();
275
0
    let mut vdel = AL1 * a1.cos() * da1 + AL2 * elpmf.cos() * delpmf + AL3 * a2.cos() * da2;
276
277
0
    let mut vr = 0.0;
278
0
    let mut vdr = 0.0;
279
280
0
    let a1mf = a1 - f;
281
0
    let da1mf = da1 - df;
282
0
    let a1pf = a1 + f;
283
0
    let da1pf = da1 + df;
284
0
    let dlpmp = elp - emp;
285
0
    let slpmp = elp + emp;
286
0
    let mut vb = AB1 * elp.sin()
287
0
        + AB2 * a3.sin()
288
0
        + AB3 * a1mf.sin()
289
0
        + AB4 * a1pf.sin()
290
0
        + AB5 * dlpmp.sin()
291
0
        + AB6 * slpmp.sin();
292
0
    let mut vdb = AB1 * elp.cos() * delp
293
0
        + AB2 * a3.cos() * da3
294
0
        + AB3 * a1mf.cos() * da1mf
295
0
        + AB4 * a1pf.cos() * da1pf
296
0
        + AB5 * dlpmp.cos() * (delp - demp)
297
0
        + AB6 * slpmp.cos() * (delp + demp);
298
299
    /* ----------------- */
300
    /* Series expansions */
301
    /* ----------------- */
302
303
    /* Longitude and distance plus derivatives. */
304
0
    for n in (0..TLR.len()).rev() {
305
0
        let dn = TLR[n].nd as f64;
306
0
        let i_val = TLR[n].nem;
307
0
        let emn = i_val as f64;
308
0
        let empn = TLR[n].nemp as f64;
309
0
        let fn_val = TLR[n].nf as f64;
310
        let en;
311
        let den;
312
0
        match i_val.abs() {
313
0
            1 => {
314
0
                en = e;
315
0
                den = de;
316
0
            }
317
0
            2 => {
318
0
                en = esq;
319
0
                den = desq;
320
0
            }
321
0
            _ => {
322
0
                en = 1.0;
323
0
                den = 0.0;
324
0
            }
325
        }
326
0
        let arg = dn * d + emn * em + empn * emp + fn_val * f;
327
0
        let darg = dn * dd + emn * dem + empn * demp + fn_val * df;
328
0
        let mut farg = arg.sin();
329
0
        let mut v = farg * en;
330
0
        let mut dv = arg.cos() * darg * en + farg * den;
331
0
        let mut coeff = TLR[n].coefl;
332
0
        vel += coeff * v;
333
0
        vdel += coeff * dv;
334
0
        farg = arg.cos();
335
0
        v = farg * en;
336
0
        dv = -arg.sin() * darg * en + farg * den;
337
0
        coeff = TLR[n].coefr;
338
0
        vr += coeff * v;
339
0
        vdr += coeff * dv;
340
    }
341
0
    let el = elp + DD2R * vel;
342
0
    let del = (delp + DD2R * vdel) / DJC;
343
0
    let r = (vr + R0) / DAU;
344
0
    let dr = vdr / DAU / DJC;
345
346
    /* Latitude plus derivative. */
347
0
    for n in (0..TB.len()).rev() {
348
0
        let dn = TB[n].nd as f64;
349
0
        let i_val = TB[n].nem;
350
0
        let emn = i_val as f64;
351
0
        let empn = TB[n].nemp as f64;
352
0
        let fn_val = TB[n].nf as f64;
353
        let en;
354
        let den;
355
0
        match i_val.abs() {
356
0
            1 => {
357
0
                en = e;
358
0
                den = de;
359
0
            }
360
0
            2 => {
361
0
                en = esq;
362
0
                den = desq;
363
0
            }
364
0
            _ => {
365
0
                en = 1.0;
366
0
                den = 0.0;
367
0
            }
368
        }
369
0
        let arg = dn * d + emn * em + empn * emp + fn_val * f;
370
0
        let darg = dn * dd + emn * dem + empn * demp + fn_val * df;
371
0
        let farg = arg.sin();
372
0
        let v = farg * en;
373
0
        let dv = arg.cos() * darg * en + farg * den;
374
0
        let coeff = TB[n].coefb;
375
0
        vb += coeff * v;
376
0
        vdb += coeff * dv;
377
    }
378
0
    let b = vb * DD2R;
379
0
    let db = vdb * DD2R / DJC;
380
381
    /* ------------------------------ */
382
    /* Transformation into final form */
383
    /* ------------------------------ */
384
385
    /* Longitude, latitude to x, y, z (au). */
386
0
    let pv = s2pv(el, b, r, del, db, dr);
387
388
    /* IAU 2006 Fukushima-Williams bias+precession angles. */
389
0
    let (gamb, phib, psib, _) = pfw06(date1, date2);
390
391
    /* Mean ecliptic coordinates to GCRS rotation matrix. */
392
0
    ir(&mut rm);
393
0
    rz(psib, &mut rm);
394
0
    rx(-phib, &mut rm);
395
0
    rz(-gamb, &mut rm);
396
397
    /* Rotate the Moon position and velocity into GCRS (Note 6). */
398
0
    let mut res = [[0.0; 3]; 2];
399
0
    rxpv(&rm, &pv, &mut res);
400
401
0
    res
402
0
}