@openwaters/almanac 0.0.0-bootstrap

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/moon.js ADDED
@@ -0,0 +1,310 @@
1
+ // L1 lunar theory: MOON2 (Improved Lunar Ephemeris 1954 / Brown, as published in
2
+ // Montenbruck & Pfleger, "Astronomy on the Personal Computer").
3
+ //
4
+ // Translated from the cosinekitty/astronomy upstream, pinned sha
5
+ // 865d3da7d8112bbc7911238052c6af4aaf877181, source/js/astronomy.ts. The term
6
+ // tables below are copied verbatim from that file; operation order is preserved
7
+ // so a Swift port agrees bit-for-bit.
8
+ //
9
+ // INTERNAL: not part of the curated public API (see index.ts).
10
+ import { ARC, EARTH_EQUATORIAL_RADIUS_AU, PI2, PrecessDirection, eclipticToEquatorial, frac, gyration, meanObliquityDeg, precession } from './nutation.js';
11
+ /**
12
+ * UPSTREAM: `CalcMoon`, astronomy.ts lines 1494-1793 — the full MOON2 series.
13
+ * Returns ecliptic longitude/latitude of date (radians) and distance (AU).
14
+ */
15
+ export function calcMoon(tt) {
16
+ const T = tt / 36525;
17
+ function DeclareArray1(xmin, xmax) {
18
+ const array = [];
19
+ let i;
20
+ for (i = 0; i <= xmax - xmin; ++i) {
21
+ array.push(0);
22
+ }
23
+ return { min: xmin, array: array };
24
+ }
25
+ function DeclareArray2(xmin, xmax, ymin, ymax) {
26
+ const array = [];
27
+ for (let i = 0; i <= xmax - xmin; ++i) {
28
+ array.push(DeclareArray1(ymin, ymax));
29
+ }
30
+ return { min: xmin, array: array };
31
+ }
32
+ function ArrayGet2(a, x, y) {
33
+ const m = a.array[x - a.min];
34
+ return m.array[y - m.min];
35
+ }
36
+ function ArraySet2(a, x, y, v) {
37
+ const m = a.array[x - a.min];
38
+ m.array[y - m.min] = v;
39
+ }
40
+ let S, MAX, ARG, FAC, I, J, T2, DGAM, DLAM, N, GAM1C, SINPI, L0, L, LS, F, D, DL0, DL, DLS, DF, DD, DS;
41
+ let coArray = DeclareArray2(-6, 6, 1, 4);
42
+ let siArray = DeclareArray2(-6, 6, 1, 4);
43
+ function CO(x, y) {
44
+ return ArrayGet2(coArray, x, y);
45
+ }
46
+ function SI(x, y) {
47
+ return ArrayGet2(siArray, x, y);
48
+ }
49
+ function SetCO(x, y, v) {
50
+ return ArraySet2(coArray, x, y, v);
51
+ }
52
+ function SetSI(x, y, v) {
53
+ return ArraySet2(siArray, x, y, v);
54
+ }
55
+ function AddThe(c1, s1, c2, s2, func) {
56
+ func(c1 * c2 - s1 * s2, s1 * c2 + c1 * s2);
57
+ }
58
+ function Sine(phi) {
59
+ return Math.sin(PI2 * phi);
60
+ }
61
+ T2 = T * T;
62
+ DLAM = 0;
63
+ DS = 0;
64
+ GAM1C = 0;
65
+ SINPI = 3422.7000;
66
+ var S1 = Sine(0.19833 + 0.05611 * T);
67
+ var S2 = Sine(0.27869 + 0.04508 * T);
68
+ var S3 = Sine(0.16827 - 0.36903 * T);
69
+ var S4 = Sine(0.34734 - 5.37261 * T);
70
+ var S5 = Sine(0.10498 - 5.37899 * T);
71
+ var S6 = Sine(0.42681 - 0.41855 * T);
72
+ var S7 = Sine(0.14943 - 5.37511 * T);
73
+ DL0 = 0.84 * S1 + 0.31 * S2 + 14.27 * S3 + 7.26 * S4 + 0.28 * S5 + 0.24 * S6;
74
+ DL = 2.94 * S1 + 0.31 * S2 + 14.27 * S3 + 9.34 * S4 + 1.12 * S5 + 0.83 * S6;
75
+ DLS = -6.40 * S1 - 1.89 * S6;
76
+ DF = 0.21 * S1 + 0.31 * S2 + 14.27 * S3 - 88.70 * S4 - 15.30 * S5 + 0.24 * S6 - 1.86 * S7;
77
+ DD = DL0 - DLS;
78
+ DGAM = (-3332E-9 * Sine(0.59734 - 5.37261 * T)
79
+ - 539E-9 * Sine(0.35498 - 5.37899 * T)
80
+ - 64E-9 * Sine(0.39943 - 5.37511 * T));
81
+ L0 = PI2 * frac(0.60643382 + 1336.85522467 * T - 0.00000313 * T2) + DL0 / ARC;
82
+ L = PI2 * frac(0.37489701 + 1325.55240982 * T + 0.00002565 * T2) + DL / ARC;
83
+ LS = PI2 * frac(0.99312619 + 99.99735956 * T - 0.00000044 * T2) + DLS / ARC;
84
+ F = PI2 * frac(0.25909118 + 1342.22782980 * T - 0.00000892 * T2) + DF / ARC;
85
+ D = PI2 * frac(0.82736186 + 1236.85308708 * T - 0.00000397 * T2) + DD / ARC;
86
+ for (I = 1; I <= 4; ++I) {
87
+ switch (I) {
88
+ case 1:
89
+ ARG = L;
90
+ MAX = 4;
91
+ FAC = 1.000002208;
92
+ break;
93
+ case 2:
94
+ ARG = LS;
95
+ MAX = 3;
96
+ FAC = 0.997504612 - 0.002495388 * T;
97
+ break;
98
+ case 3:
99
+ ARG = F;
100
+ MAX = 4;
101
+ FAC = 1.000002708 + 139.978 * DGAM;
102
+ break;
103
+ case 4:
104
+ ARG = D;
105
+ MAX = 6;
106
+ FAC = 1.0;
107
+ break;
108
+ default: throw `Internal error: I = ${I}`; // persuade TypeScript that ARG, ... are all initialized before use.
109
+ }
110
+ SetCO(0, I, 1);
111
+ SetCO(1, I, Math.cos(ARG) * FAC);
112
+ SetSI(0, I, 0);
113
+ SetSI(1, I, Math.sin(ARG) * FAC);
114
+ for (J = 2; J <= MAX; ++J) {
115
+ AddThe(CO(J - 1, I), SI(J - 1, I), CO(1, I), SI(1, I), (c, s) => (SetCO(J, I, c), SetSI(J, I, s)));
116
+ }
117
+ for (J = 1; J <= MAX; ++J) {
118
+ SetCO(-J, I, CO(J, I));
119
+ SetSI(-J, I, -SI(J, I));
120
+ }
121
+ }
122
+ function Term(p, q, r, s) {
123
+ var result = { x: 1, y: 0 };
124
+ var I = [0, p, q, r, s]; // I[0] is not used; it is a placeholder
125
+ for (var k = 1; k <= 4; ++k)
126
+ if (I[k] !== 0)
127
+ AddThe(result.x, result.y, CO(I[k], k), SI(I[k], k), (c, s) => (result.x = c, result.y = s));
128
+ return result;
129
+ }
130
+ function AddSol(coeffl, coeffs, coeffg, coeffp, p, q, r, s) {
131
+ var result = Term(p, q, r, s);
132
+ DLAM += coeffl * result.y;
133
+ DS += coeffs * result.y;
134
+ GAM1C += coeffg * result.x;
135
+ SINPI += coeffp * result.x;
136
+ }
137
+ AddSol(13.9020, 14.0600, -0.0010, 0.2607, 0, 0, 0, 4);
138
+ AddSol(0.4030, -4.0100, 0.3940, 0.0023, 0, 0, 0, 3);
139
+ AddSol(2369.9120, 2373.3600, 0.6010, 28.2333, 0, 0, 0, 2);
140
+ AddSol(-125.1540, -112.7900, -0.7250, -0.9781, 0, 0, 0, 1);
141
+ AddSol(1.9790, 6.9800, -0.4450, 0.0433, 1, 0, 0, 4);
142
+ AddSol(191.9530, 192.7200, 0.0290, 3.0861, 1, 0, 0, 2);
143
+ AddSol(-8.4660, -13.5100, 0.4550, -0.1093, 1, 0, 0, 1);
144
+ AddSol(22639.5000, 22609.0700, 0.0790, 186.5398, 1, 0, 0, 0);
145
+ AddSol(18.6090, 3.5900, -0.0940, 0.0118, 1, 0, 0, -1);
146
+ AddSol(-4586.4650, -4578.1300, -0.0770, 34.3117, 1, 0, 0, -2);
147
+ AddSol(3.2150, 5.4400, 0.1920, -0.0386, 1, 0, 0, -3);
148
+ AddSol(-38.4280, -38.6400, 0.0010, 0.6008, 1, 0, 0, -4);
149
+ AddSol(-0.3930, -1.4300, -0.0920, 0.0086, 1, 0, 0, -6);
150
+ AddSol(-0.2890, -1.5900, 0.1230, -0.0053, 0, 1, 0, 4);
151
+ AddSol(-24.4200, -25.1000, 0.0400, -0.3000, 0, 1, 0, 2);
152
+ AddSol(18.0230, 17.9300, 0.0070, 0.1494, 0, 1, 0, 1);
153
+ AddSol(-668.1460, -126.9800, -1.3020, -0.3997, 0, 1, 0, 0);
154
+ AddSol(0.5600, 0.3200, -0.0010, -0.0037, 0, 1, 0, -1);
155
+ AddSol(-165.1450, -165.0600, 0.0540, 1.9178, 0, 1, 0, -2);
156
+ AddSol(-1.8770, -6.4600, -0.4160, 0.0339, 0, 1, 0, -4);
157
+ AddSol(0.2130, 1.0200, -0.0740, 0.0054, 2, 0, 0, 4);
158
+ AddSol(14.3870, 14.7800, -0.0170, 0.2833, 2, 0, 0, 2);
159
+ AddSol(-0.5860, -1.2000, 0.0540, -0.0100, 2, 0, 0, 1);
160
+ AddSol(769.0160, 767.9600, 0.1070, 10.1657, 2, 0, 0, 0);
161
+ AddSol(1.7500, 2.0100, -0.0180, 0.0155, 2, 0, 0, -1);
162
+ AddSol(-211.6560, -152.5300, 5.6790, -0.3039, 2, 0, 0, -2);
163
+ AddSol(1.2250, 0.9100, -0.0300, -0.0088, 2, 0, 0, -3);
164
+ AddSol(-30.7730, -34.0700, -0.3080, 0.3722, 2, 0, 0, -4);
165
+ AddSol(-0.5700, -1.4000, -0.0740, 0.0109, 2, 0, 0, -6);
166
+ AddSol(-2.9210, -11.7500, 0.7870, -0.0484, 1, 1, 0, 2);
167
+ AddSol(1.2670, 1.5200, -0.0220, 0.0164, 1, 1, 0, 1);
168
+ AddSol(-109.6730, -115.1800, 0.4610, -0.9490, 1, 1, 0, 0);
169
+ AddSol(-205.9620, -182.3600, 2.0560, 1.4437, 1, 1, 0, -2);
170
+ AddSol(0.2330, 0.3600, 0.0120, -0.0025, 1, 1, 0, -3);
171
+ AddSol(-4.3910, -9.6600, -0.4710, 0.0673, 1, 1, 0, -4);
172
+ AddSol(0.2830, 1.5300, -0.1110, 0.0060, 1, -1, 0, 4);
173
+ AddSol(14.5770, 31.7000, -1.5400, 0.2302, 1, -1, 0, 2);
174
+ AddSol(147.6870, 138.7600, 0.6790, 1.1528, 1, -1, 0, 0);
175
+ AddSol(-1.0890, 0.5500, 0.0210, 0.0000, 1, -1, 0, -1);
176
+ AddSol(28.4750, 23.5900, -0.4430, -0.2257, 1, -1, 0, -2);
177
+ AddSol(-0.2760, -0.3800, -0.0060, -0.0036, 1, -1, 0, -3);
178
+ AddSol(0.6360, 2.2700, 0.1460, -0.0102, 1, -1, 0, -4);
179
+ AddSol(-0.1890, -1.6800, 0.1310, -0.0028, 0, 2, 0, 2);
180
+ AddSol(-7.4860, -0.6600, -0.0370, -0.0086, 0, 2, 0, 0);
181
+ AddSol(-8.0960, -16.3500, -0.7400, 0.0918, 0, 2, 0, -2);
182
+ AddSol(-5.7410, -0.0400, 0.0000, -0.0009, 0, 0, 2, 2);
183
+ AddSol(0.2550, 0.0000, 0.0000, 0.0000, 0, 0, 2, 1);
184
+ AddSol(-411.6080, -0.2000, 0.0000, -0.0124, 0, 0, 2, 0);
185
+ AddSol(0.5840, 0.8400, 0.0000, 0.0071, 0, 0, 2, -1);
186
+ AddSol(-55.1730, -52.1400, 0.0000, -0.1052, 0, 0, 2, -2);
187
+ AddSol(0.2540, 0.2500, 0.0000, -0.0017, 0, 0, 2, -3);
188
+ AddSol(0.0250, -1.6700, 0.0000, 0.0031, 0, 0, 2, -4);
189
+ AddSol(1.0600, 2.9600, -0.1660, 0.0243, 3, 0, 0, 2);
190
+ AddSol(36.1240, 50.6400, -1.3000, 0.6215, 3, 0, 0, 0);
191
+ AddSol(-13.1930, -16.4000, 0.2580, -0.1187, 3, 0, 0, -2);
192
+ AddSol(-1.1870, -0.7400, 0.0420, 0.0074, 3, 0, 0, -4);
193
+ AddSol(-0.2930, -0.3100, -0.0020, 0.0046, 3, 0, 0, -6);
194
+ AddSol(-0.2900, -1.4500, 0.1160, -0.0051, 2, 1, 0, 2);
195
+ AddSol(-7.6490, -10.5600, 0.2590, -0.1038, 2, 1, 0, 0);
196
+ AddSol(-8.6270, -7.5900, 0.0780, -0.0192, 2, 1, 0, -2);
197
+ AddSol(-2.7400, -2.5400, 0.0220, 0.0324, 2, 1, 0, -4);
198
+ AddSol(1.1810, 3.3200, -0.2120, 0.0213, 2, -1, 0, 2);
199
+ AddSol(9.7030, 11.6700, -0.1510, 0.1268, 2, -1, 0, 0);
200
+ AddSol(-0.3520, -0.3700, 0.0010, -0.0028, 2, -1, 0, -1);
201
+ AddSol(-2.4940, -1.1700, -0.0030, -0.0017, 2, -1, 0, -2);
202
+ AddSol(0.3600, 0.2000, -0.0120, -0.0043, 2, -1, 0, -4);
203
+ AddSol(-1.1670, -1.2500, 0.0080, -0.0106, 1, 2, 0, 0);
204
+ AddSol(-7.4120, -6.1200, 0.1170, 0.0484, 1, 2, 0, -2);
205
+ AddSol(-0.3110, -0.6500, -0.0320, 0.0044, 1, 2, 0, -4);
206
+ AddSol(0.7570, 1.8200, -0.1050, 0.0112, 1, -2, 0, 2);
207
+ AddSol(2.5800, 2.3200, 0.0270, 0.0196, 1, -2, 0, 0);
208
+ AddSol(2.5330, 2.4000, -0.0140, -0.0212, 1, -2, 0, -2);
209
+ AddSol(-0.3440, -0.5700, -0.0250, 0.0036, 0, 3, 0, -2);
210
+ AddSol(-0.9920, -0.0200, 0.0000, 0.0000, 1, 0, 2, 2);
211
+ AddSol(-45.0990, -0.0200, 0.0000, -0.0010, 1, 0, 2, 0);
212
+ AddSol(-0.1790, -9.5200, 0.0000, -0.0833, 1, 0, 2, -2);
213
+ AddSol(-0.3010, -0.3300, 0.0000, 0.0014, 1, 0, 2, -4);
214
+ AddSol(-6.3820, -3.3700, 0.0000, -0.0481, 1, 0, -2, 2);
215
+ AddSol(39.5280, 85.1300, 0.0000, -0.7136, 1, 0, -2, 0);
216
+ AddSol(9.3660, 0.7100, 0.0000, -0.0112, 1, 0, -2, -2);
217
+ AddSol(0.2020, 0.0200, 0.0000, 0.0000, 1, 0, -2, -4);
218
+ AddSol(0.4150, 0.1000, 0.0000, 0.0013, 0, 1, 2, 0);
219
+ AddSol(-2.1520, -2.2600, 0.0000, -0.0066, 0, 1, 2, -2);
220
+ AddSol(-1.4400, -1.3000, 0.0000, 0.0014, 0, 1, -2, 2);
221
+ AddSol(0.3840, -0.0400, 0.0000, 0.0000, 0, 1, -2, -2);
222
+ AddSol(1.9380, 3.6000, -0.1450, 0.0401, 4, 0, 0, 0);
223
+ AddSol(-0.9520, -1.5800, 0.0520, -0.0130, 4, 0, 0, -2);
224
+ AddSol(-0.5510, -0.9400, 0.0320, -0.0097, 3, 1, 0, 0);
225
+ AddSol(-0.4820, -0.5700, 0.0050, -0.0045, 3, 1, 0, -2);
226
+ AddSol(0.6810, 0.9600, -0.0260, 0.0115, 3, -1, 0, 0);
227
+ AddSol(-0.2970, -0.2700, 0.0020, -0.0009, 2, 2, 0, -2);
228
+ AddSol(0.2540, 0.2100, -0.0030, 0.0000, 2, -2, 0, -2);
229
+ AddSol(-0.2500, -0.2200, 0.0040, 0.0014, 1, 3, 0, -2);
230
+ AddSol(-3.9960, 0.0000, 0.0000, 0.0004, 2, 0, 2, 0);
231
+ AddSol(0.5570, -0.7500, 0.0000, -0.0090, 2, 0, 2, -2);
232
+ AddSol(-0.4590, -0.3800, 0.0000, -0.0053, 2, 0, -2, 2);
233
+ AddSol(-1.2980, 0.7400, 0.0000, 0.0004, 2, 0, -2, 0);
234
+ AddSol(0.5380, 1.1400, 0.0000, -0.0141, 2, 0, -2, -2);
235
+ AddSol(0.2630, 0.0200, 0.0000, 0.0000, 1, 1, 2, 0);
236
+ AddSol(0.4260, 0.0700, 0.0000, -0.0006, 1, 1, -2, -2);
237
+ AddSol(-0.3040, 0.0300, 0.0000, 0.0003, 1, -1, 2, 0);
238
+ AddSol(-0.3720, -0.1900, 0.0000, -0.0027, 1, -1, -2, 2);
239
+ AddSol(0.4180, 0.0000, 0.0000, 0.0000, 0, 0, 4, 0);
240
+ AddSol(-0.3300, -0.0400, 0.0000, 0.0000, 3, 0, 2, 0);
241
+ function ADDN(coeffn, p, q, r, s) {
242
+ return coeffn * Term(p, q, r, s).y;
243
+ }
244
+ N = 0;
245
+ N += ADDN(-526.069, 0, 0, 1, -2);
246
+ N += ADDN(-3.352, 0, 0, 1, -4);
247
+ N += ADDN(+44.297, +1, 0, 1, -2);
248
+ N += ADDN(-6.000, +1, 0, 1, -4);
249
+ N += ADDN(+20.599, -1, 0, 1, 0);
250
+ N += ADDN(-30.598, -1, 0, 1, -2);
251
+ N += ADDN(-24.649, -2, 0, 1, 0);
252
+ N += ADDN(-2.000, -2, 0, 1, -2);
253
+ N += ADDN(-22.571, 0, +1, 1, -2);
254
+ N += ADDN(+10.985, 0, -1, 1, -2);
255
+ DLAM += (+0.82 * Sine(0.7736 - 62.5512 * T) + 0.31 * Sine(0.0466 - 125.1025 * T)
256
+ + 0.35 * Sine(0.5785 - 25.1042 * T) + 0.66 * Sine(0.4591 + 1335.8075 * T)
257
+ + 0.64 * Sine(0.3130 - 91.5680 * T) + 1.14 * Sine(0.1480 + 1331.2898 * T)
258
+ + 0.21 * Sine(0.5918 + 1056.5859 * T) + 0.44 * Sine(0.5784 + 1322.8595 * T)
259
+ + 0.24 * Sine(0.2275 - 5.7374 * T) + 0.28 * Sine(0.2965 + 2.6929 * T)
260
+ + 0.33 * Sine(0.3132 + 6.3368 * T));
261
+ S = F + DS / ARC;
262
+ let lat_seconds = (1.000002708 + 139.978 * DGAM) * (18518.511 + 1.189 + GAM1C) * Math.sin(S) - 6.24 * Math.sin(3 * S) + N;
263
+ return {
264
+ geoEclipLon: PI2 * frac((L0 + DLAM / ARC) / PI2),
265
+ geoEclipLat: (Math.PI / (180 * 3600)) * lat_seconds,
266
+ distanceAu: (ARC * EARTH_EQUATORIAL_RADIUS_AU) / (0.999953253 * SINPI)
267
+ };
268
+ }
269
+ /**
270
+ * UPSTREAM: `GeoMoon`, astronomy.ts lines 3049-3068, followed by the
271
+ * `gyration(..., From2000)` that `Equator(ofdate=true)` (line 2803) applies.
272
+ *
273
+ * `GeoVector(Body.Moon, ...)` returns `GeoMoon` unchanged whatever the
274
+ * `aberration` flag: the Moon shares the Earth's orbital velocity, so its
275
+ * geocentric aberration and its 1.3-second light time both fall far below the
276
+ * precision of this lunar theory.
277
+ *
278
+ * The precession round trip (into J2000, then back out inside `gyration`) is
279
+ * upstream's own composition and is kept so the Swift port can be a
280
+ * line-for-line translation.
281
+ *
282
+ * @returns geocentric position in AU, J2000 mean equator (EQJ) — the `mpos2`
283
+ * intermediate below, exported for the L2 topocentric path (Task 11), which
284
+ * needs the body vector in the same EQJ frame as the observer's geocentric
285
+ * position before subtracting the two.
286
+ */
287
+ export function moonGeoVectorEqj(tt) {
288
+ const moon = calcMoon(tt);
289
+ // Convert geocentric ecliptic spherical coords to cartesian coords.
290
+ const dist_cos_lat = moon.distanceAu * Math.cos(moon.geoEclipLat);
291
+ const gepos = {
292
+ x: dist_cos_lat * Math.cos(moon.geoEclipLon),
293
+ y: dist_cos_lat * Math.sin(moon.geoEclipLon),
294
+ z: moon.distanceAu * Math.sin(moon.geoEclipLat)
295
+ };
296
+ // Convert ecliptic coordinates to equatorial coordinates, both in mean equinox of date.
297
+ const mpos1 = eclipticToEquatorial(meanObliquityDeg(tt), gepos);
298
+ // Convert from mean equinox of date to J2000...
299
+ return precession(mpos1, tt, PrecessDirection.Into2000);
300
+ }
301
+ /**
302
+ * UPSTREAM: `GeoMoon` (astronomy.ts 3049-3068) followed by the
303
+ * `gyration(..., From2000)` that `Equator(ofdate=true)` (line 2803) applies.
304
+ *
305
+ * @returns geocentric position in AU, true equator & equinox of date.
306
+ */
307
+ export function moonGeoVector(tt) {
308
+ // ...out to the true equator and equinox of date (precession + nutation).
309
+ return gyration(moonGeoVectorEqj(tt), tt, PrecessDirection.From2000);
310
+ }
@@ -0,0 +1,65 @@
1
+ /** UPSTREAM: constants, astronomy.ts lines 42-72 and 123-140. */
2
+ export declare const DEG2RAD = 0.017453292519943295;
3
+ export declare const RAD2DEG = 57.29577951308232;
4
+ export declare const ASEC2RAD = 0.00000484813681109536;
5
+ export declare const PI2: number;
6
+ /** arcseconds per radian */
7
+ export declare const ARC: number;
8
+ export declare const KM_PER_AU = 149597870.69098932;
9
+ export declare const C_AUDAY = 173.1446326846693;
10
+ export declare const EARTH_EQUATORIAL_RADIUS_KM = 6378.1366;
11
+ export declare const EARTH_EQUATORIAL_RADIUS_AU: number;
12
+ /** UPSTREAM: WGS-84 flattening, astronomy.ts lines 137-138 (terra, geo_pos). */
13
+ export declare const EARTH_FLATTENING = 0.996647180302104;
14
+ export declare const EARTH_FLATTENING_SQUARED: number;
15
+ /** A Cartesian position in AU. */
16
+ export interface Vec3 {
17
+ x: number;
18
+ y: number;
19
+ z: number;
20
+ }
21
+ /** Equatorial direction + range derived from a {@link Vec3}. */
22
+ export interface EquatorialFromVector {
23
+ raDeg: number;
24
+ decDeg: number;
25
+ distanceAu: number;
26
+ }
27
+ /**
28
+ * Direction of a frame rotation, matching upstream's `PrecessDirection` enum
29
+ * (astronomy.ts ~line 1920): `From2000` takes EQJ → of-date, `Into2000` the inverse.
30
+ */
31
+ export declare enum PrecessDirection {
32
+ Into2000 = 0,
33
+ From2000 = 1
34
+ }
35
+ /** UPSTREAM: `Frac`, astronomy.ts line 235. */
36
+ export declare function frac(x: number): number;
37
+ /** UPSTREAM: `mean_obliq`, astronomy.ts lines 1437-1447. Degrees. */
38
+ export declare function meanObliquityDeg(tt: number): number;
39
+ /** UPSTREAM: `EarthTiltInfo`, astronomy.ts lines 1449-1457. dpsi/deps arcsec, mobl/tobl degrees. */
40
+ export interface EarthTilt {
41
+ dpsi: number;
42
+ deps: number;
43
+ ee: number;
44
+ mobl: number;
45
+ tobl: number;
46
+ }
47
+ /** UPSTREAM: `e_tilt`, astronomy.ts lines 1460-1475 (including its one-entry cache). */
48
+ export declare function earthTilt(tt: number): EarthTilt;
49
+ /** UPSTREAM: `obl_ecl2equ_vec`, astronomy.ts lines 1477-1486. */
50
+ export declare function eclipticToEquatorial(oblDegrees: number, pos: Vec3): Vec3;
51
+ /** UPSTREAM: `precession`, astronomy.ts lines 1936-1939. */
52
+ export declare function precession(pos: Vec3, tt: number, dir: PrecessDirection): Vec3;
53
+ /** UPSTREAM: `nutation`, astronomy.ts lines 2165-2168. */
54
+ export declare function applyNutation(pos: Vec3, tt: number, dir: PrecessDirection): Vec3;
55
+ /**
56
+ * UPSTREAM: `gyration`, astronomy.ts lines 2218-2225. Precession and nutation
57
+ * composed; the order flips with direction because they are mutual inverses.
58
+ */
59
+ export declare function gyration(pos: Vec3, tt: number, dir: PrecessDirection): Vec3;
60
+ /**
61
+ * UPSTREAM: `vector2radec`, astronomy.ts lines 2501-2516 — with right ascension
62
+ * in degrees over [0, 360) rather than upstream's hours, per the spec's
63
+ * Coordinate semantics.
64
+ */
65
+ export declare function equatorialFromVector(pos: Vec3): EquatorialFromVector;
@@ -0,0 +1,255 @@
1
+ // L1 frames layer: IAU 2000B nutation, mean obliquity, and the precession /
2
+ // nutation rotations that carry a vector between the J2000 mean equator (EQJ)
3
+ // and the true equator & equinox of date.
4
+ //
5
+ // Translated from the cosinekitty/astronomy upstream, pinned sha
6
+ // 865d3da7d8112bbc7911238052c6af4aaf877181, source/js/astronomy.ts. Operation
7
+ // order and coefficient values are preserved verbatim so that a Swift port of
8
+ // this file agrees bit-for-bit.
9
+ //
10
+ // INTERNAL: not part of the curated public API (see index.ts).
11
+ /** UPSTREAM: constants, astronomy.ts lines 42-72 and 123-140. */
12
+ export const DEG2RAD = 0.017453292519943296;
13
+ export const RAD2DEG = 57.295779513082321;
14
+ export const ASEC2RAD = 4.848136811095359935899141e-6;
15
+ const ASEC180 = 180 * 60 * 60;
16
+ const ASEC360 = 2 * ASEC180;
17
+ export const PI2 = 2 * Math.PI;
18
+ /** arcseconds per radian */
19
+ export const ARC = 3600 * (180 / Math.PI);
20
+ export const KM_PER_AU = 1.4959787069098932e8;
21
+ export const C_AUDAY = 173.1446326846693;
22
+ export const EARTH_EQUATORIAL_RADIUS_KM = 6378.1366;
23
+ export const EARTH_EQUATORIAL_RADIUS_AU = EARTH_EQUATORIAL_RADIUS_KM / KM_PER_AU;
24
+ /** UPSTREAM: WGS-84 flattening, astronomy.ts lines 137-138 (terra, geo_pos). */
25
+ export const EARTH_FLATTENING = 0.996647180302104;
26
+ export const EARTH_FLATTENING_SQUARED = EARTH_FLATTENING * EARTH_FLATTENING;
27
+ /**
28
+ * Direction of a frame rotation, matching upstream's `PrecessDirection` enum
29
+ * (astronomy.ts ~line 1920): `From2000` takes EQJ → of-date, `Into2000` the inverse.
30
+ */
31
+ export var PrecessDirection;
32
+ (function (PrecessDirection) {
33
+ PrecessDirection[PrecessDirection["Into2000"] = 0] = "Into2000";
34
+ PrecessDirection[PrecessDirection["From2000"] = 1] = "From2000";
35
+ })(PrecessDirection || (PrecessDirection = {}));
36
+ /** UPSTREAM: `Frac`, astronomy.ts line 235. */
37
+ export function frac(x) {
38
+ return x - Math.floor(x);
39
+ }
40
+ /**
41
+ * UPSTREAM: `iau2000b`, astronomy.ts lines 1392-1435. The IAU 2000B nutation
42
+ * series truncated to its five largest terms; returns arcseconds.
43
+ */
44
+ function iau2000b(tt) {
45
+ function mod(x) {
46
+ return (x % ASEC360) * ASEC2RAD;
47
+ }
48
+ const t = tt / 36525;
49
+ const elp = mod(1287104.79305 + t * 129596581.0481);
50
+ const f = mod(335779.526232 + t * 1739527262.8478);
51
+ const d = mod(1072260.70369 + t * 1602961601.2090);
52
+ const om = mod(450160.398036 - t * 6962890.5431);
53
+ let sarg = Math.sin(om);
54
+ let carg = Math.cos(om);
55
+ let dp = (-172064161.0 - 174666.0 * t) * sarg + 33386.0 * carg;
56
+ let de = (92052331.0 + 9086.0 * t) * carg + 15377.0 * sarg;
57
+ let arg = 2.0 * (f - d + om);
58
+ sarg = Math.sin(arg);
59
+ carg = Math.cos(arg);
60
+ dp += (-13170906.0 - 1675.0 * t) * sarg - 13696.0 * carg;
61
+ de += (5730336.0 - 3015.0 * t) * carg - 4587.0 * sarg;
62
+ arg = 2.0 * (f + om);
63
+ sarg = Math.sin(arg);
64
+ carg = Math.cos(arg);
65
+ dp += (-2276413.0 - 234.0 * t) * sarg + 2796.0 * carg;
66
+ de += (978459.0 - 485.0 * t) * carg + 1374.0 * sarg;
67
+ arg = 2.0 * om;
68
+ sarg = Math.sin(arg);
69
+ carg = Math.cos(arg);
70
+ dp += (2074554.0 + 207.0 * t) * sarg - 698.0 * carg;
71
+ de += (-897492.0 + 470.0 * t) * carg - 291.0 * sarg;
72
+ sarg = Math.sin(elp);
73
+ carg = Math.cos(elp);
74
+ dp += (1475877.0 - 3633.0 * t) * sarg + 11817.0 * carg;
75
+ de += (73871.0 - 184.0 * t) * carg - 1924.0 * sarg;
76
+ return {
77
+ dpsi: -0.000135 + (dp * 1.0e-7),
78
+ deps: +0.000388 + (de * 1.0e-7)
79
+ };
80
+ }
81
+ /** UPSTREAM: `mean_obliq`, astronomy.ts lines 1437-1447. Degrees. */
82
+ export function meanObliquityDeg(tt) {
83
+ const t = tt / 36525;
84
+ const asec = (((((-0.0000000434 * t
85
+ - 0.000000576) * t
86
+ + 0.00200340) * t
87
+ - 0.0001831) * t
88
+ - 46.836769) * t + 84381.406);
89
+ return asec / 3600.0;
90
+ }
91
+ let cacheETilt;
92
+ let cacheETiltTt = NaN;
93
+ /** UPSTREAM: `e_tilt`, astronomy.ts lines 1460-1475 (including its one-entry cache). */
94
+ export function earthTilt(tt) {
95
+ if (!cacheETilt || !(Math.abs(cacheETiltTt - tt) <= 1.0e-6)) {
96
+ const nut = iau2000b(tt);
97
+ const meanOb = meanObliquityDeg(tt);
98
+ const trueOb = meanOb + (nut.deps / 3600);
99
+ cacheETiltTt = tt;
100
+ cacheETilt = {
101
+ dpsi: nut.dpsi,
102
+ deps: nut.deps,
103
+ ee: nut.dpsi * Math.cos(meanOb * DEG2RAD) / 15,
104
+ mobl: meanOb,
105
+ tobl: trueOb
106
+ };
107
+ }
108
+ return cacheETilt;
109
+ }
110
+ /** UPSTREAM: `obl_ecl2equ_vec`, astronomy.ts lines 1477-1486. */
111
+ export function eclipticToEquatorial(oblDegrees, pos) {
112
+ const obl = oblDegrees * DEG2RAD;
113
+ const cosObl = Math.cos(obl);
114
+ const sinObl = Math.sin(obl);
115
+ return {
116
+ x: pos.x,
117
+ y: pos.y * cosObl - pos.z * sinObl,
118
+ z: pos.y * sinObl + pos.z * cosObl
119
+ };
120
+ }
121
+ /** UPSTREAM: `rotate`, astronomy.ts lines 1928-1934 (note the transposed indexing). */
122
+ function rotate(rot, vec) {
123
+ return {
124
+ x: rot[0][0] * vec.x + rot[1][0] * vec.y + rot[2][0] * vec.z,
125
+ y: rot[0][1] * vec.x + rot[1][1] * vec.y + rot[2][1] * vec.z,
126
+ z: rot[0][2] * vec.x + rot[1][2] * vec.y + rot[2][2] * vec.z
127
+ };
128
+ }
129
+ /** UPSTREAM: `precession_rot`, astronomy.ts lines 1946-2012. */
130
+ function precessionRot(tt, dir) {
131
+ const t = tt / 36525;
132
+ let eps0 = 84381.406;
133
+ let psia = (((((-0.0000000951 * t
134
+ + 0.000132851) * t
135
+ - 0.00114045) * t
136
+ - 1.0790069) * t
137
+ + 5038.481507) * t);
138
+ let omegaa = (((((+0.0000003337 * t
139
+ - 0.000000467) * t
140
+ - 0.00772503) * t
141
+ + 0.0512623) * t
142
+ - 0.025754) * t + eps0);
143
+ let chia = (((((-0.0000000560 * t
144
+ + 0.000170663) * t
145
+ - 0.00121197) * t
146
+ - 2.3814292) * t
147
+ + 10.556403) * t);
148
+ eps0 *= ASEC2RAD;
149
+ psia *= ASEC2RAD;
150
+ omegaa *= ASEC2RAD;
151
+ chia *= ASEC2RAD;
152
+ const sa = Math.sin(eps0);
153
+ const ca = Math.cos(eps0);
154
+ const sb = Math.sin(-psia);
155
+ const cb = Math.cos(-psia);
156
+ const sc = Math.sin(-omegaa);
157
+ const cc = Math.cos(-omegaa);
158
+ const sd = Math.sin(chia);
159
+ const cd = Math.cos(chia);
160
+ const xx = cd * cb - sb * sd * cc;
161
+ const yx = cd * sb * ca + sd * cc * cb * ca - sa * sd * sc;
162
+ const zx = cd * sb * sa + sd * cc * cb * sa + ca * sd * sc;
163
+ const xy = -sd * cb - sb * cd * cc;
164
+ const yy = -sd * sb * ca + cd * cc * cb * ca - sa * cd * sc;
165
+ const zy = -sd * sb * sa + cd * cc * cb * sa + ca * cd * sc;
166
+ const xz = sb * sc;
167
+ const yz = -sc * cb * ca - sa * cc;
168
+ const zz = -sc * cb * sa + cc * ca;
169
+ if (dir === PrecessDirection.Into2000) {
170
+ // Perform rotation from epoch to J2000.0.
171
+ return [
172
+ [xx, yx, zx],
173
+ [xy, yy, zy],
174
+ [xz, yz, zz]
175
+ ];
176
+ }
177
+ // Perform rotation from J2000.0 to epoch.
178
+ return [
179
+ [xx, xy, xz],
180
+ [yx, yy, yz],
181
+ [zx, zy, zz]
182
+ ];
183
+ }
184
+ /** UPSTREAM: `precession`, astronomy.ts lines 1936-1939. */
185
+ export function precession(pos, tt, dir) {
186
+ return rotate(precessionRot(tt, dir), pos);
187
+ }
188
+ /** UPSTREAM: `nutation_rot`, astronomy.ts lines 2175-2216. */
189
+ function nutationRot(tt, dir) {
190
+ const tilt = earthTilt(tt);
191
+ const oblm = tilt.mobl * DEG2RAD;
192
+ const oblt = tilt.tobl * DEG2RAD;
193
+ const psi = tilt.dpsi * ASEC2RAD;
194
+ const cobm = Math.cos(oblm);
195
+ const sobm = Math.sin(oblm);
196
+ const cobt = Math.cos(oblt);
197
+ const sobt = Math.sin(oblt);
198
+ const cpsi = Math.cos(psi);
199
+ const spsi = Math.sin(psi);
200
+ const xx = cpsi;
201
+ const yx = -spsi * cobm;
202
+ const zx = -spsi * sobm;
203
+ const xy = spsi * cobt;
204
+ const yy = cpsi * cobm * cobt + sobm * sobt;
205
+ const zy = cpsi * sobm * cobt - cobm * sobt;
206
+ const xz = spsi * sobt;
207
+ const yz = cpsi * cobm * sobt - sobm * cobt;
208
+ const zz = cpsi * sobm * sobt + cobm * cobt;
209
+ if (dir === PrecessDirection.From2000) {
210
+ // convert J2000 to of-date
211
+ return [
212
+ [xx, xy, xz],
213
+ [yx, yy, yz],
214
+ [zx, zy, zz]
215
+ ];
216
+ }
217
+ // convert of-date to J2000
218
+ return [
219
+ [xx, yx, zx],
220
+ [xy, yy, zy],
221
+ [xz, yz, zz]
222
+ ];
223
+ }
224
+ /** UPSTREAM: `nutation`, astronomy.ts lines 2165-2168. */
225
+ export function applyNutation(pos, tt, dir) {
226
+ return rotate(nutationRot(tt, dir), pos);
227
+ }
228
+ /**
229
+ * UPSTREAM: `gyration`, astronomy.ts lines 2218-2225. Precession and nutation
230
+ * composed; the order flips with direction because they are mutual inverses.
231
+ */
232
+ export function gyration(pos, tt, dir) {
233
+ return (dir === PrecessDirection.Into2000) ?
234
+ precession(applyNutation(pos, tt, dir), tt, dir) :
235
+ applyNutation(precession(pos, tt, dir), tt, dir);
236
+ }
237
+ /**
238
+ * UPSTREAM: `vector2radec`, astronomy.ts lines 2501-2516 — with right ascension
239
+ * in degrees over [0, 360) rather than upstream's hours, per the spec's
240
+ * Coordinate semantics.
241
+ */
242
+ export function equatorialFromVector(pos) {
243
+ const xyproj = pos.x * pos.x + pos.y * pos.y;
244
+ const dist = Math.sqrt(xyproj + pos.z * pos.z);
245
+ if (xyproj === 0) {
246
+ if (pos.z === 0)
247
+ throw new Error('Indeterminate sky coordinates');
248
+ return { raDeg: 0, decDeg: (pos.z < 0) ? -90 : +90, distanceAu: dist };
249
+ }
250
+ let raDeg = RAD2DEG * Math.atan2(pos.y, pos.x);
251
+ if (raDeg < 0)
252
+ raDeg += 360;
253
+ const decDeg = RAD2DEG * Math.atan2(pos.z, Math.sqrt(xyproj));
254
+ return { raDeg, decDeg, distanceAu: dist };
255
+ }
@@ -0,0 +1,34 @@
1
+ /** Apparent geocentric position of the Sun: equator of date, RA in [0, 360). */
2
+ export interface SunPosition {
3
+ raDeg: number;
4
+ decDeg: number;
5
+ distanceAu: number;
6
+ }
7
+ /** Apparent geocentric position of the Moon: equator of date, RA in [0, 360). */
8
+ export interface MoonPosition {
9
+ raDeg: number;
10
+ decDeg: number;
11
+ distanceKm: number;
12
+ }
13
+ /**
14
+ * INTERNAL: apparent Sun for a TT instant, expressed as days since the J2000
15
+ * epoch in Terrestrial Time. This is the entry point the TT-labeled position
16
+ * fixtures compare against — going through `sunPosition` would first convert
17
+ * UTC → TT with a ΔT model, putting a timescale approximation between the
18
+ * ephemeris and the reference data.
19
+ */
20
+ export declare function sunApparentAtTT(tt: number): SunPosition;
21
+ /** INTERNAL: apparent Moon for a TT instant. See {@link sunApparentAtTT}. */
22
+ export declare function moonApparentAtTT(tt: number): MoonPosition;
23
+ /**
24
+ * Apparent geocentric position of the Sun — right ascension and declination on
25
+ * the true equator and equinox of date (precession, nutation and aberration
26
+ * applied), plus the light-time-corrected distance in AU.
27
+ */
28
+ export declare function sunPosition(time: Date): SunPosition;
29
+ /**
30
+ * Apparent geocentric position of the Moon — right ascension and declination on
31
+ * the true equator and equinox of date (precession and nutation applied), plus
32
+ * the Earth-Moon centre distance in kilometres.
33
+ */
34
+ export declare function moonPosition(time: Date): MoonPosition;