tonus 0.1.0
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/BIBLIOGRAPHY.md +99 -0
- package/LICENSE +29 -0
- package/README.md +108 -0
- package/dist/data/cal.d.ts +10 -0
- package/dist/data/cal.js +3862 -0
- package/dist/data/commune.d.ts +17 -0
- package/dist/data/commune.js +1333 -0
- package/dist/data/gr.d.ts +5 -0
- package/dist/data/gr.js +13449 -0
- package/dist/data/kyriale.d.ts +11 -0
- package/dist/data/kyriale.js +971 -0
- package/dist/data/la.d.ts +5 -0
- package/dist/data/la.js +14229 -0
- package/dist/data/lh.d.ts +5 -0
- package/dist/data/lh.js +3619 -0
- package/dist/data/lu.d.ts +5 -0
- package/dist/data/lu.js +23779 -0
- package/dist/data/masses.d.ts +18 -0
- package/dist/data/masses.js +297 -0
- package/dist/data/office-roman.d.ts +19 -0
- package/dist/data/office-roman.js +13792 -0
- package/dist/data/office.d.ts +12 -0
- package/dist/data/office.js +13052 -0
- package/dist/data/propers.d.ts +13 -0
- package/dist/data/propers.js +7584 -0
- package/dist/data/psalms.d.ts +4 -0
- package/dist/data/psalms.js +10 -0
- package/dist/data/psalms.json +22918 -0
- package/dist/data/tones.d.ts +20 -0
- package/dist/data/tones.js +153 -0
- package/dist/data/types.d.ts +3 -0
- package/dist/data/types.js +2 -0
- package/dist/engines/cal/calendar.d.ts +21 -0
- package/dist/engines/cal/calendar.js +265 -0
- package/dist/engines/cal/date.d.ts +31 -0
- package/dist/engines/cal/date.js +141 -0
- package/dist/engines/cal/types.d.ts +66 -0
- package/dist/engines/cal/types.js +189 -0
- package/dist/engines/chant/chant.d.ts +10 -0
- package/dist/engines/chant/chant.js +135 -0
- package/dist/engines/chant/hour.d.ts +8 -0
- package/dist/engines/chant/hour.js +135 -0
- package/dist/engines/chant/intone.d.ts +8 -0
- package/dist/engines/chant/intone.js +84 -0
- package/dist/engines/chant/ordinary.d.ts +7 -0
- package/dist/engines/chant/ordinary.js +232 -0
- package/dist/engines/chant/propers.d.ts +8 -0
- package/dist/engines/chant/propers.js +107 -0
- package/dist/engines/chant/psalm.d.ts +7 -0
- package/dist/engines/chant/psalm.js +60 -0
- package/dist/engines/chant/syllabify.d.ts +20 -0
- package/dist/engines/chant/syllabify.js +192 -0
- package/dist/engines/chant/types.d.ts +76 -0
- package/dist/engines/chant/types.js +34 -0
- package/dist/engines/epoch.d.ts +2 -0
- package/dist/engines/epoch.js +14 -0
- package/dist/engines/harmonia/api.d.ts +35 -0
- package/dist/engines/harmonia/api.js +90 -0
- package/dist/engines/harmonia/aspects.d.ts +8 -0
- package/dist/engines/harmonia/aspects.js +15 -0
- package/dist/engines/harmonia/data/doctrines.d.ts +16 -0
- package/dist/engines/harmonia/data/doctrines.js +154 -0
- package/dist/engines/harmonia/data/vowels.d.ts +10 -0
- package/dist/engines/harmonia/data/vowels.js +21 -0
- package/dist/engines/harmonia/presence.d.ts +13 -0
- package/dist/engines/harmonia/presence.js +48 -0
- package/dist/engines/harmonia/tabula.d.ts +28 -0
- package/dist/engines/harmonia/tabula.js +32 -0
- package/dist/engines/harmonia/voice.d.ts +19 -0
- package/dist/engines/harmonia/voice.js +51 -0
- package/dist/engines/imprint.d.ts +30 -0
- package/dist/engines/imprint.js +152 -0
- package/dist/engines/planet/appearance.d.ts +40 -0
- package/dist/engines/planet/appearance.js +84 -0
- package/dist/engines/planet/aspects.d.ts +5 -0
- package/dist/engines/planet/aspects.js +41 -0
- package/dist/engines/planet/math.d.ts +13 -0
- package/dist/engines/planet/math.js +56 -0
- package/dist/engines/planet/orbital.d.ts +25 -0
- package/dist/engines/planet/orbital.js +223 -0
- package/dist/engines/planet/planet.d.ts +13 -0
- package/dist/engines/planet/planet.js +198 -0
- package/dist/engines/planet/position.d.ts +62 -0
- package/dist/engines/planet/position.js +156 -0
- package/dist/engines/planet/types.d.ts +61 -0
- package/dist/engines/planet/types.js +14 -0
- package/dist/engines/score/api.d.ts +54 -0
- package/dist/engines/score/api.js +87 -0
- package/dist/engines/score/articulation.d.ts +6 -0
- package/dist/engines/score/articulation.js +112 -0
- package/dist/engines/score/emitters/midi.d.ts +65 -0
- package/dist/engines/score/emitters/midi.js +158 -0
- package/dist/engines/score/emitters/musicxml.d.ts +18 -0
- package/dist/engines/score/emitters/musicxml.js +166 -0
- package/dist/engines/score/infer.d.ts +4 -0
- package/dist/engines/score/infer.js +77 -0
- package/dist/engines/score/ir.d.ts +4 -0
- package/dist/engines/score/ir.js +177 -0
- package/dist/engines/score/meta.d.ts +19 -0
- package/dist/engines/score/meta.js +34 -0
- package/dist/engines/score/neume.d.ts +3 -0
- package/dist/engines/score/neume.js +26 -0
- package/dist/engines/score/parse.d.ts +3 -0
- package/dist/engines/score/parse.js +359 -0
- package/dist/engines/score/phrasing.d.ts +24 -0
- package/dist/engines/score/phrasing.js +257 -0
- package/dist/engines/score/prosody.d.ts +35 -0
- package/dist/engines/score/prosody.js +109 -0
- package/dist/engines/score/tabula.d.ts +70 -0
- package/dist/engines/score/tabula.js +109 -0
- package/dist/engines/score/types.d.ts +159 -0
- package/dist/engines/score/types.js +2 -0
- package/dist/engines/temper/api.d.ts +60 -0
- package/dist/engines/temper/api.js +130 -0
- package/dist/engines/temper/data/constants.d.ts +27 -0
- package/dist/engines/temper/data/constants.js +150 -0
- package/dist/engines/temper/data/guido.d.ts +14 -0
- package/dist/engines/temper/data/guido.js +29 -0
- package/dist/engines/temper/data/modes.d.ts +38 -0
- package/dist/engines/temper/data/modes.js +158 -0
- package/dist/engines/temper/gabc.d.ts +5 -0
- package/dist/engines/temper/gabc.js +53 -0
- package/dist/engines/temper/gamut.d.ts +9 -0
- package/dist/engines/temper/gamut.js +24 -0
- package/dist/engines/temper/guido.d.ts +16 -0
- package/dist/engines/temper/guido.js +48 -0
- package/dist/engines/temper/interval.d.ts +15 -0
- package/dist/engines/temper/interval.js +31 -0
- package/dist/engines/temper/modes.d.ts +6 -0
- package/dist/engines/temper/modes.js +13 -0
- package/dist/engines/temper/neume.d.ts +14 -0
- package/dist/engines/temper/neume.js +59 -0
- package/dist/engines/temper/pitch.d.ts +40 -0
- package/dist/engines/temper/pitch.js +129 -0
- package/dist/engines/temper/scale.d.ts +37 -0
- package/dist/engines/temper/scale.js +217 -0
- package/dist/engines/temper/step.d.ts +23 -0
- package/dist/engines/temper/step.js +53 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +27 -0
- package/package.json +60 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
export const ORBITAL_ELEMENTS = new Map([
|
|
2
|
+
[
|
|
3
|
+
"Mercury",
|
|
4
|
+
{
|
|
5
|
+
name: "Mercury",
|
|
6
|
+
symbol: "☿",
|
|
7
|
+
datasets: [
|
|
8
|
+
[
|
|
9
|
+
[0.38709927, 0.00000037],
|
|
10
|
+
[0.20563593, 0.00001906],
|
|
11
|
+
[7.00497902, -0.00594749],
|
|
12
|
+
[252.2503235, 149472.67411175],
|
|
13
|
+
[77.45779628, 0.16047689],
|
|
14
|
+
[48.33076593, -0.12534081],
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
[0.38709843, 0],
|
|
18
|
+
[0.20563661, 0.00002123],
|
|
19
|
+
[7.00559432, -0.00590158],
|
|
20
|
+
[252.25166724, 149472.67486623],
|
|
21
|
+
[77.45771895, 0.15940013],
|
|
22
|
+
[48.33961819, -0.12214182],
|
|
23
|
+
],
|
|
24
|
+
],
|
|
25
|
+
radius: 2439.4,
|
|
26
|
+
rotation_period: 58.6462,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"Venus",
|
|
31
|
+
{
|
|
32
|
+
name: "Venus",
|
|
33
|
+
symbol: "♀",
|
|
34
|
+
datasets: [
|
|
35
|
+
[
|
|
36
|
+
[0.72333566, 0.0000039],
|
|
37
|
+
[0.00676399, -0.00005107],
|
|
38
|
+
[3.39467605, -0.0007889],
|
|
39
|
+
[181.9790995, 58517.81538729],
|
|
40
|
+
[131.60246718, 0.00268329],
|
|
41
|
+
[76.67984255, -0.27769418],
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
[0.72332102, -0.00000026],
|
|
45
|
+
[-0.00005107, 0.01673163],
|
|
46
|
+
[3.39777545, 0.00043494],
|
|
47
|
+
[181.9797085, 58517.8156026],
|
|
48
|
+
[131.76755713, 0.05679648],
|
|
49
|
+
[76.67261496, -0.27274174],
|
|
50
|
+
],
|
|
51
|
+
],
|
|
52
|
+
radius: 6051.8,
|
|
53
|
+
rotation_period: -243.018,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
"Earth",
|
|
58
|
+
{
|
|
59
|
+
name: "Earth",
|
|
60
|
+
symbol: "♁",
|
|
61
|
+
datasets: [
|
|
62
|
+
[
|
|
63
|
+
[1.00000261, 0.00000562],
|
|
64
|
+
[0.01671123, -0.00004392],
|
|
65
|
+
[-0.00001531, -0.01294668],
|
|
66
|
+
[100.46457166, 35999.37244981],
|
|
67
|
+
[102.93768193, 0.32327364],
|
|
68
|
+
[0, 0],
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
[1.00000018, 1.52371243],
|
|
72
|
+
[0.01673163, -0.00003661],
|
|
73
|
+
[-0.00054346, -0.01337178],
|
|
74
|
+
[100.46691572, 35999.37306329],
|
|
75
|
+
[102.93005885, 0.3179526],
|
|
76
|
+
[-5.11260389, -0.24123856],
|
|
77
|
+
],
|
|
78
|
+
],
|
|
79
|
+
radius: 6371.0084,
|
|
80
|
+
rotation_period: 0.99726968,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
"Mars",
|
|
85
|
+
{
|
|
86
|
+
name: "Mars",
|
|
87
|
+
symbol: "♂",
|
|
88
|
+
datasets: [
|
|
89
|
+
[
|
|
90
|
+
[1.52371034, 0.00001847],
|
|
91
|
+
[0.0933941, 0.00007882],
|
|
92
|
+
[1.84969142, -0.00813131],
|
|
93
|
+
[-4.55343205, 19140.30268499],
|
|
94
|
+
[-23.94362959, 0.44441088],
|
|
95
|
+
[49.55953891, -0.29257343],
|
|
96
|
+
],
|
|
97
|
+
[
|
|
98
|
+
[1.52371243, 0.00000097],
|
|
99
|
+
[0.09336511, 0.00009149],
|
|
100
|
+
[1.85181869, -0.00724757],
|
|
101
|
+
[-4.56813164, 19140.29934243],
|
|
102
|
+
[-23.91744784, 0.45223625],
|
|
103
|
+
[49.71320984, -0.26852431],
|
|
104
|
+
],
|
|
105
|
+
],
|
|
106
|
+
radius: 3389.5,
|
|
107
|
+
rotation_period: 1.02595676,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"Jupiter",
|
|
112
|
+
{
|
|
113
|
+
name: "Jupiter",
|
|
114
|
+
symbol: "♃",
|
|
115
|
+
datasets: [
|
|
116
|
+
[
|
|
117
|
+
[5.202887, -0.00011607],
|
|
118
|
+
[0.04838624, -0.00013253],
|
|
119
|
+
[1.30439695, -0.00183714],
|
|
120
|
+
[34.39644051, 3034.74612775],
|
|
121
|
+
[14.72847983, 0.21252668],
|
|
122
|
+
[100.47390909, 0.20469106],
|
|
123
|
+
],
|
|
124
|
+
[
|
|
125
|
+
[5.20248019, -0.00002864],
|
|
126
|
+
[0.0485359, 0.00018026],
|
|
127
|
+
[1.29861416, -0.00322699],
|
|
128
|
+
[34.33479152, 3034.90371757],
|
|
129
|
+
[14.27495244, 0.18199196],
|
|
130
|
+
[100.29282654, 0.13024619],
|
|
131
|
+
],
|
|
132
|
+
[0.00012452, 0.0606406, -0.35635438, 38.35125],
|
|
133
|
+
],
|
|
134
|
+
radius: 69911,
|
|
135
|
+
rotation_period: 0.41354,
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
"Saturn",
|
|
140
|
+
{
|
|
141
|
+
name: "Saturn",
|
|
142
|
+
symbol: "♄",
|
|
143
|
+
datasets: [
|
|
144
|
+
[
|
|
145
|
+
[9.53667594, -0.0012506],
|
|
146
|
+
[0.05386179, -0.00050991],
|
|
147
|
+
[2.48599187, 0.00193609],
|
|
148
|
+
[49.95424423, 1222.49362201],
|
|
149
|
+
[92.59887831, -0.41897216],
|
|
150
|
+
[113.66242448, -0.28867794],
|
|
151
|
+
],
|
|
152
|
+
[
|
|
153
|
+
[9.54149883, -0.00003065],
|
|
154
|
+
[0.05550825, -0.00032044],
|
|
155
|
+
[2.49424102, 0.00451969],
|
|
156
|
+
[50.07571329, 1222.11494724],
|
|
157
|
+
[92.86136063, 0.54179478],
|
|
158
|
+
[113.639987, -0.25015002],
|
|
159
|
+
],
|
|
160
|
+
[0.00025899, -0.13434469, 0.87320147, 38.35125],
|
|
161
|
+
],
|
|
162
|
+
radius: 58232,
|
|
163
|
+
rotation_period: 0.44401,
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
[
|
|
167
|
+
"Uranus",
|
|
168
|
+
{
|
|
169
|
+
name: "Uranus",
|
|
170
|
+
symbol: "♅",
|
|
171
|
+
datasets: [
|
|
172
|
+
[
|
|
173
|
+
[19.18916464, -0.00196176],
|
|
174
|
+
[0.04725744, -0.00004397],
|
|
175
|
+
[0.77263783, -0.00242939],
|
|
176
|
+
[313.23810451, 428.48202785],
|
|
177
|
+
[170.9542763, 0.40805281],
|
|
178
|
+
[74.01692503, 0.04240589],
|
|
179
|
+
],
|
|
180
|
+
[
|
|
181
|
+
[19.18797948, -0.00020455],
|
|
182
|
+
[0.0468574, -0.0000155],
|
|
183
|
+
[0.77298127, -0.00180155],
|
|
184
|
+
[314.20276625, 428.49512595],
|
|
185
|
+
[172.43404441, 0.09266985],
|
|
186
|
+
[73.96250215, 0.05739699],
|
|
187
|
+
],
|
|
188
|
+
[0.00058331, -0.97731848, 0.17689245, 7.67025],
|
|
189
|
+
],
|
|
190
|
+
radius: 25362,
|
|
191
|
+
rotation_period: -0.718,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
[
|
|
195
|
+
"Neptune",
|
|
196
|
+
{
|
|
197
|
+
name: "Neptune",
|
|
198
|
+
symbol: "♆",
|
|
199
|
+
datasets: [
|
|
200
|
+
[
|
|
201
|
+
[30.06992276, 0.00026291],
|
|
202
|
+
[0.00859048, 0.00005105],
|
|
203
|
+
[1.77004347, 0.00035372],
|
|
204
|
+
[-55.12002969, 218.45945325],
|
|
205
|
+
[44.96476227, -0.32241464],
|
|
206
|
+
[131.78422574, -0.00508664],
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
[30.06952752, 0.00006447],
|
|
210
|
+
[0.00895439, 0.00000818],
|
|
211
|
+
[1.7700552, 0.000224],
|
|
212
|
+
[304.22289287, 218.46515314],
|
|
213
|
+
[46.68158724, 0.01009938],
|
|
214
|
+
[131.78635853, -0.00606302],
|
|
215
|
+
],
|
|
216
|
+
[-0.00041348, 0.68346318, -0.10162547, 7.67025],
|
|
217
|
+
],
|
|
218
|
+
radius: 24622,
|
|
219
|
+
rotation_period: 0.67125,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
]);
|
|
223
|
+
//# sourceMappingURL=orbital.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Cosmos, CosmosQuery } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ephemeris lookup (`tonus.caelum`). Computes geocentric and heliocentric
|
|
4
|
+
* positions, zodiac signs, retrogradation, and aspects for the classical
|
|
5
|
+
* bodies at an instant (JPL Keplerian elements, 3000 BC – 3000 AD). A
|
|
6
|
+
* `from`/`to` range returns a stepped series.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getCosmos(query: CosmosQuery & {
|
|
9
|
+
from: Date;
|
|
10
|
+
to: Date;
|
|
11
|
+
}): Cosmos[];
|
|
12
|
+
export declare function getCosmos(query?: CosmosQuery): Cosmos;
|
|
13
|
+
//# sourceMappingURL=planet.d.ts.map
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// engines/planet/planet — planetary snapshot builder
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { angleDelta, wrapAngle } from "./math.js";
|
|
5
|
+
import { getState, sunPos, moonPos, planetPos } from "./position.js";
|
|
6
|
+
import { sunAppearance, moonAppearance, planetAppearance } from "./appearance.js";
|
|
7
|
+
import { detectAspects } from "./aspects.js";
|
|
8
|
+
import { ORBITAL_ELEMENTS } from "./orbital.js";
|
|
9
|
+
import { latinName } from "./types.js";
|
|
10
|
+
import { DEFAULT_EPOCH } from "../epoch.js";
|
|
11
|
+
const MS_PER_DAY = 86400000;
|
|
12
|
+
const ALL_BODIES = ["Sun", "Moon", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn"];
|
|
13
|
+
const SIGNS = [
|
|
14
|
+
"Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
|
|
15
|
+
"Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces",
|
|
16
|
+
];
|
|
17
|
+
const zodiac = (lon) => Math.floor(wrapAngle(lon) / 30) % 12;
|
|
18
|
+
const sign = (lon) => SIGNS[zodiac(lon)];
|
|
19
|
+
function computeSpeed(geoLon, name, ts) {
|
|
20
|
+
const nextState = getState(ts + MS_PER_DAY);
|
|
21
|
+
const nextSun = sunPos(nextState);
|
|
22
|
+
let nextLon;
|
|
23
|
+
if (name === "Sun") {
|
|
24
|
+
nextLon = nextSun.geo.lon;
|
|
25
|
+
}
|
|
26
|
+
else if (name === "Moon") {
|
|
27
|
+
nextLon = moonPos(nextState, nextSun).geo.lon;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
nextLon = planetPos(name, nextState, nextSun).geo.lon;
|
|
31
|
+
}
|
|
32
|
+
return angleDelta(geoLon, nextLon);
|
|
33
|
+
}
|
|
34
|
+
function buildSun(ts) {
|
|
35
|
+
const state = getState(ts);
|
|
36
|
+
const pos = sunPos(state);
|
|
37
|
+
const app = sunAppearance(pos.geo.dist);
|
|
38
|
+
const speed = computeSpeed(pos.geo.lon, "Sun", ts);
|
|
39
|
+
return {
|
|
40
|
+
name: "Sun",
|
|
41
|
+
nomen: latinName("Sun"),
|
|
42
|
+
symbol: "☉",
|
|
43
|
+
helio: { lon: pos.helio.lon, lat: pos.helio.lat, dist: pos.helio.dist },
|
|
44
|
+
geo: pos.geo,
|
|
45
|
+
speed,
|
|
46
|
+
retrograde: speed < 0,
|
|
47
|
+
magnitude: app.magnitude,
|
|
48
|
+
elongation: 0,
|
|
49
|
+
phase: 1,
|
|
50
|
+
apparentDiameter: app.apparentDiameter,
|
|
51
|
+
zodiac: zodiac(pos.geo.lon),
|
|
52
|
+
sign: sign(pos.geo.lon),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function buildMoon(ts) {
|
|
56
|
+
const state = getState(ts);
|
|
57
|
+
const sun = sunPos(state);
|
|
58
|
+
const pos = moonPos(state, sun);
|
|
59
|
+
const app = moonAppearance({
|
|
60
|
+
sunLongitude: sun.geo.lon,
|
|
61
|
+
moonLongitude: pos.geo.lon,
|
|
62
|
+
moonLatitude: pos.geo.lat,
|
|
63
|
+
distEarthRadii: pos.distEarthRadii,
|
|
64
|
+
});
|
|
65
|
+
const speed = computeSpeed(pos.geo.lon, "Moon", ts);
|
|
66
|
+
return {
|
|
67
|
+
name: "Moon",
|
|
68
|
+
nomen: latinName("Moon"),
|
|
69
|
+
symbol: "☾",
|
|
70
|
+
helio: { lon: 0, lat: 0, dist: 0 },
|
|
71
|
+
geo: {
|
|
72
|
+
lon: pos.geo.lon,
|
|
73
|
+
lat: pos.geo.lat,
|
|
74
|
+
dist: pos.geo.dist,
|
|
75
|
+
equatorial: pos.geo.equatorial,
|
|
76
|
+
},
|
|
77
|
+
speed,
|
|
78
|
+
retrograde: speed < 0,
|
|
79
|
+
magnitude: -12.6,
|
|
80
|
+
elongation: app.elongation,
|
|
81
|
+
phase: app.phase,
|
|
82
|
+
apparentDiameter: app.apparentDiameter,
|
|
83
|
+
zodiac: zodiac(pos.geo.lon),
|
|
84
|
+
sign: sign(pos.geo.lon),
|
|
85
|
+
distEarthRadii: pos.distEarthRadii,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function buildPlanet(name, ts) {
|
|
89
|
+
const state = getState(ts);
|
|
90
|
+
const sun = sunPos(state);
|
|
91
|
+
const pos = planetPos(name, state, sun);
|
|
92
|
+
const elem = ORBITAL_ELEMENTS.get(name);
|
|
93
|
+
const app = planetAppearance({
|
|
94
|
+
name,
|
|
95
|
+
heliocentricDistance: pos.helio.dist,
|
|
96
|
+
geocentricDistance: pos.geo.dist,
|
|
97
|
+
geocentricLongitude: pos.geo.lon,
|
|
98
|
+
geocentricLatitude: pos.geo.lat,
|
|
99
|
+
sunDistance: sun.geo.dist,
|
|
100
|
+
J: state.J,
|
|
101
|
+
});
|
|
102
|
+
const speed = computeSpeed(pos.geo.lon, name, ts);
|
|
103
|
+
return {
|
|
104
|
+
name,
|
|
105
|
+
nomen: latinName(name),
|
|
106
|
+
symbol: elem.symbol,
|
|
107
|
+
helio: { lon: pos.helio.lon, lat: pos.helio.lat, dist: pos.helio.dist },
|
|
108
|
+
geo: {
|
|
109
|
+
lon: pos.geo.lon, lat: pos.geo.lat, dist: pos.geo.dist,
|
|
110
|
+
equatorial: pos.geo.equatorial,
|
|
111
|
+
},
|
|
112
|
+
speed,
|
|
113
|
+
retrograde: speed < 0,
|
|
114
|
+
magnitude: app.magnitude,
|
|
115
|
+
elongation: app.elongation,
|
|
116
|
+
phase: app.phase,
|
|
117
|
+
apparentDiameter: app.apparentDiameter,
|
|
118
|
+
zodiac: zodiac(pos.helio.lon),
|
|
119
|
+
sign: sign(pos.helio.lon),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function buildEarth(ts) {
|
|
123
|
+
const state = getState(ts);
|
|
124
|
+
const sun = sunPos(state);
|
|
125
|
+
const pos = planetPos("Earth", state, sun);
|
|
126
|
+
const elem = ORBITAL_ELEMENTS.get("Earth");
|
|
127
|
+
const speed = computeSpeed(pos.geo.lon, "Earth", ts);
|
|
128
|
+
return {
|
|
129
|
+
name: "Earth",
|
|
130
|
+
nomen: latinName("Earth"),
|
|
131
|
+
symbol: elem.symbol,
|
|
132
|
+
helio: { lon: pos.helio.lon, lat: pos.helio.lat, dist: pos.helio.dist },
|
|
133
|
+
geo: {
|
|
134
|
+
lon: pos.geo.lon, lat: pos.geo.lat, dist: pos.geo.dist,
|
|
135
|
+
equatorial: pos.geo.equatorial,
|
|
136
|
+
},
|
|
137
|
+
speed,
|
|
138
|
+
retrograde: speed < 0,
|
|
139
|
+
magnitude: 0,
|
|
140
|
+
elongation: 0,
|
|
141
|
+
phase: 1,
|
|
142
|
+
apparentDiameter: 0,
|
|
143
|
+
zodiac: zodiac(pos.helio.lon),
|
|
144
|
+
sign: sign(pos.helio.lon),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const BODY_BUILDERS = {
|
|
148
|
+
Sun: buildSun,
|
|
149
|
+
Moon: buildMoon,
|
|
150
|
+
Mercury: (ts) => buildPlanet("Mercury", ts),
|
|
151
|
+
Venus: (ts) => buildPlanet("Venus", ts),
|
|
152
|
+
Earth: buildEarth,
|
|
153
|
+
Mars: (ts) => buildPlanet("Mars", ts),
|
|
154
|
+
Jupiter: (ts) => buildPlanet("Jupiter", ts),
|
|
155
|
+
Saturn: (ts) => buildPlanet("Saturn", ts),
|
|
156
|
+
};
|
|
157
|
+
const MAX_FRAMES = 10000;
|
|
158
|
+
function snapshotAt(date, requested, orbLimit) {
|
|
159
|
+
const ts = date.getTime();
|
|
160
|
+
const bodies = requested.map((name) => BODY_BUILDERS[name](ts));
|
|
161
|
+
const geoLons = {};
|
|
162
|
+
for (const body of bodies) {
|
|
163
|
+
if (body.name !== "Earth")
|
|
164
|
+
geoLons[body.name] = body.geo.lon;
|
|
165
|
+
}
|
|
166
|
+
const aspects = detectAspects(geoLons, { orbLimit });
|
|
167
|
+
return { date, bodies, aspects };
|
|
168
|
+
}
|
|
169
|
+
export function getCosmos(query = {}) {
|
|
170
|
+
const requested = query.bodies ?? ALL_BODIES;
|
|
171
|
+
if (query.from != null || query.to != null) {
|
|
172
|
+
if (query.from == null || query.to == null) {
|
|
173
|
+
throw new RangeError("caelum range requires both from and to");
|
|
174
|
+
}
|
|
175
|
+
if (query.to.getTime() < query.from.getTime()) {
|
|
176
|
+
throw new RangeError("caelum range: to must be >= from");
|
|
177
|
+
}
|
|
178
|
+
const step = query.step ?? 1;
|
|
179
|
+
if (step <= 0) {
|
|
180
|
+
throw new RangeError("caelum range: step must be > 0");
|
|
181
|
+
}
|
|
182
|
+
const stepMs = step * MS_PER_DAY;
|
|
183
|
+
const startTs = query.from.getTime();
|
|
184
|
+
const endTs = query.to.getTime();
|
|
185
|
+
const frameCount = Math.floor((endTs - startTs) / stepMs) + 1;
|
|
186
|
+
if (frameCount > MAX_FRAMES) {
|
|
187
|
+
throw new RangeError(`caelum range would produce ${frameCount} frames (max ${MAX_FRAMES})`);
|
|
188
|
+
}
|
|
189
|
+
const frames = [];
|
|
190
|
+
for (let ts = startTs; ts <= endTs; ts += stepMs) {
|
|
191
|
+
frames.push(snapshotAt(new Date(ts), requested, query.orbLimit));
|
|
192
|
+
}
|
|
193
|
+
return frames;
|
|
194
|
+
}
|
|
195
|
+
const date = query.date ?? query.feast?.date ?? DEFAULT_EPOCH;
|
|
196
|
+
return snapshotAt(date, requested, query.orbLimit);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=planet.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export declare const EARTH_RADIUS_AU: number;
|
|
2
|
+
export interface AstroState {
|
|
3
|
+
JD: number;
|
|
4
|
+
TT: number;
|
|
5
|
+
TS: number;
|
|
6
|
+
J: number;
|
|
7
|
+
T: number;
|
|
8
|
+
eps: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function getState(ts: number): AstroState;
|
|
11
|
+
export interface ComputedPos {
|
|
12
|
+
geo: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
z: number;
|
|
16
|
+
lon: number;
|
|
17
|
+
lat: number;
|
|
18
|
+
dist: number;
|
|
19
|
+
equatorial: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
z: number;
|
|
23
|
+
ra: number;
|
|
24
|
+
dec: number;
|
|
25
|
+
dist: number;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface SunPos extends ComputedPos {
|
|
30
|
+
helio: {
|
|
31
|
+
lon: number;
|
|
32
|
+
lat: number;
|
|
33
|
+
dist: number;
|
|
34
|
+
};
|
|
35
|
+
orbit: {
|
|
36
|
+
L: number;
|
|
37
|
+
M: number;
|
|
38
|
+
omega: number;
|
|
39
|
+
e: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface PlanetPos extends ComputedPos {
|
|
43
|
+
helio: {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
z: number;
|
|
47
|
+
lon: number;
|
|
48
|
+
lat: number;
|
|
49
|
+
dist: number;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export interface MoonPos extends ComputedPos {
|
|
53
|
+
helio: Record<string, never>;
|
|
54
|
+
geo: ComputedPos["geo"] & {
|
|
55
|
+
distEarthRadii: number;
|
|
56
|
+
};
|
|
57
|
+
distEarthRadii: number;
|
|
58
|
+
}
|
|
59
|
+
export declare function sunPos(state: AstroState): SunPos;
|
|
60
|
+
export declare function moonPos(state: AstroState, sun: SunPos): MoonPos;
|
|
61
|
+
export declare function planetPos(name: string, state: AstroState, sun: SunPos): PlanetPos;
|
|
62
|
+
//# sourceMappingURL=position.d.ts.map
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// engines/planet/position — Julian date, astro state, helio/geo position engine
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { sinDeg, cosDeg, atan2Deg, kepler, wrapAngle, toAu, toCartesian, toSpherical, toEquatorial } from "./math.js";
|
|
5
|
+
import { ORBITAL_ELEMENTS } from "./orbital.js";
|
|
6
|
+
const MS_PER_DAY = 86400000;
|
|
7
|
+
// Precomputed Earth radius in AU (used for Moon distance conversion)
|
|
8
|
+
const EARTH_ELEM = ORBITAL_ELEMENTS.get("Earth");
|
|
9
|
+
export const EARTH_RADIUS_AU = toAu(EARTH_ELEM.radius);
|
|
10
|
+
function meanObliquity(T) {
|
|
11
|
+
const eps0 = 23 + 26 / 60 + 21.406 / 3600;
|
|
12
|
+
const sec = -46.836769 * T -
|
|
13
|
+
0.0001831 * T ** 2 +
|
|
14
|
+
0.0020034 * T ** 3 -
|
|
15
|
+
0.000000576 * T ** 4 -
|
|
16
|
+
0.0000000434 * T ** 5;
|
|
17
|
+
return eps0 + sec / 3600;
|
|
18
|
+
}
|
|
19
|
+
export function getState(ts) {
|
|
20
|
+
const JD = 2440587.5 + ts / MS_PER_DAY;
|
|
21
|
+
const _T = (JD - 2451545) / 36525;
|
|
22
|
+
const dT = 64.7 + 64.7 * _T - 0.6 * _T * _T; // seconds
|
|
23
|
+
const TT = JD + dT / 86400;
|
|
24
|
+
const J = TT - 2451545.0;
|
|
25
|
+
const T = J / 36525;
|
|
26
|
+
const eps = meanObliquity(T);
|
|
27
|
+
return { JD, TT, TS: ts, J, T, eps };
|
|
28
|
+
}
|
|
29
|
+
// ── Sun position ──
|
|
30
|
+
export function sunPos(state) {
|
|
31
|
+
const { J, eps } = state;
|
|
32
|
+
const omega = 282.9404 + 4.70935e-5 * J;
|
|
33
|
+
const e = 0.016709 - 1.151e-9 * J;
|
|
34
|
+
const M = 356.047 + 0.9856002585 * J;
|
|
35
|
+
const E = M + (180 / Math.PI) * e * sinDeg(M) * (1 + e * cosDeg(M));
|
|
36
|
+
const xp = cosDeg(E) - e;
|
|
37
|
+
const yp = Math.sqrt(1 - e * e) * sinDeg(E);
|
|
38
|
+
const dist = Math.sqrt(xp * xp + yp * yp);
|
|
39
|
+
const v = atan2Deg(yp, xp);
|
|
40
|
+
const lambda = v + omega;
|
|
41
|
+
const L = omega + M;
|
|
42
|
+
const x = dist * cosDeg(lambda);
|
|
43
|
+
const y = dist * sinDeg(lambda);
|
|
44
|
+
const z = 0;
|
|
45
|
+
const [xe, ye, ze] = toEquatorial(x, y, z, eps);
|
|
46
|
+
const [ra, dec, rho] = toSpherical(xe, ye, ze);
|
|
47
|
+
return {
|
|
48
|
+
helio: { lon: wrapAngle(lambda), lat: 0, dist },
|
|
49
|
+
orbit: { L: wrapAngle(L), M: wrapAngle(M), omega, e },
|
|
50
|
+
geo: {
|
|
51
|
+
x, y, z,
|
|
52
|
+
lon: wrapAngle(lambda), lat: 0, dist,
|
|
53
|
+
equatorial: { x: xe, y: ye, z: ze, ra: wrapAngle(ra), dec, dist: rho },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// ── Moon position ──
|
|
58
|
+
export function moonPos(state, sun) {
|
|
59
|
+
const { J, eps } = state;
|
|
60
|
+
const Omega = wrapAngle(125.1228 - 0.0529538083 * J);
|
|
61
|
+
const I = 5.1454;
|
|
62
|
+
const omega = wrapAngle(318.0634 + 0.1643573223 * J);
|
|
63
|
+
const a = 60.2666; // Earth radii
|
|
64
|
+
const e = 0.0549;
|
|
65
|
+
const M = wrapAngle(115.3654 + 13.0649929509 * J);
|
|
66
|
+
const E = M + (180 / Math.PI) * e * sinDeg(M) * (1 + e * cosDeg(M));
|
|
67
|
+
const xh = a * (cosDeg(E) - e);
|
|
68
|
+
const yh = a * Math.sqrt(1 - e * e) * sinDeg(E);
|
|
69
|
+
const cO = cosDeg(Omega), sO = sinDeg(Omega);
|
|
70
|
+
const cw = cosDeg(omega), sw = sinDeg(omega);
|
|
71
|
+
const cI = cosDeg(I), sI = sinDeg(I);
|
|
72
|
+
const x = (cw * cO - sw * sO * cI) * xh + (-sw * cO - cw * sO * cI) * yh;
|
|
73
|
+
const y = (cw * sO + sw * cO * cI) * xh + (-sw * sO + cw * cO * cI) * yh;
|
|
74
|
+
const z = sw * sI * xh + cw * sI * yh;
|
|
75
|
+
const [lonE, latE, distE] = toSpherical(x, y, z);
|
|
76
|
+
const Lm = wrapAngle(Omega + omega + M);
|
|
77
|
+
const Ms = sun.orbit.M;
|
|
78
|
+
const Ls = sun.orbit.L;
|
|
79
|
+
const D = wrapAngle(Lm - Ls);
|
|
80
|
+
const F = wrapAngle(Lm - Omega);
|
|
81
|
+
// Lunar perturbations
|
|
82
|
+
const lonPerturb = -1.274 * sinDeg(M - 2 * D) + 0.658 * sinDeg(2 * D) - 0.186 * sinDeg(Ms) -
|
|
83
|
+
0.059 * sinDeg(2 * M - 2 * D) - 0.057 * sinDeg(M - 2 * D + Ms) +
|
|
84
|
+
0.053 * sinDeg(M + 2 * D) + 0.046 * sinDeg(2 * D - Ms) +
|
|
85
|
+
0.041 * sinDeg(M - Ms) - 0.035 * sinDeg(D) - 0.031 * sinDeg(M + Ms) -
|
|
86
|
+
0.015 * sinDeg(2 * F - 2 * D) + 0.011 * sinDeg(M - 4 * D);
|
|
87
|
+
const latPerturb = -0.173 * sinDeg(F - 2 * D) - 0.055 * sinDeg(M - F - 2 * D) -
|
|
88
|
+
0.046 * sinDeg(M + F - 2 * D) + 0.033 * sinDeg(F + 2 * D) +
|
|
89
|
+
0.017 * sinDeg(2 * M + F);
|
|
90
|
+
const distPerturb = -0.58 * cosDeg(M - 2 * D) - 0.46 * cosDeg(2 * D);
|
|
91
|
+
const lon = wrapAngle(lonE + lonPerturb);
|
|
92
|
+
const lat = latE + latPerturb;
|
|
93
|
+
const rER = distE + distPerturb; // Earth radii
|
|
94
|
+
const [xc, yc, zc] = toCartesian(lon, lat, rER);
|
|
95
|
+
const xAu = xc * EARTH_RADIUS_AU;
|
|
96
|
+
const yAu = yc * EARTH_RADIUS_AU;
|
|
97
|
+
const zAu = zc * EARTH_RADIUS_AU;
|
|
98
|
+
const distAu = rER * EARTH_RADIUS_AU;
|
|
99
|
+
const [xe, ye, ze] = toEquatorial(xAu, yAu, zAu, eps);
|
|
100
|
+
const [ra, dec, rho] = toSpherical(xe, ye, ze);
|
|
101
|
+
return {
|
|
102
|
+
helio: {},
|
|
103
|
+
distEarthRadii: rER,
|
|
104
|
+
geo: {
|
|
105
|
+
x: xAu, y: yAu, z: zAu,
|
|
106
|
+
lon, lat, dist: distAu,
|
|
107
|
+
distEarthRadii: rER,
|
|
108
|
+
equatorial: { x: xe, y: ye, z: ze, ra: wrapAngle(ra), dec, dist: rho },
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ── Planet position ──
|
|
113
|
+
export function planetPos(name, state, sun) {
|
|
114
|
+
const body = ORBITAL_ELEMENTS.get(name);
|
|
115
|
+
if (!body)
|
|
116
|
+
throw new Error(`Unknown body: ${name}`);
|
|
117
|
+
const { J, T, eps } = state;
|
|
118
|
+
const oe = body.datasets;
|
|
119
|
+
// Use higher-precision dataset (1800–2050) if in range, otherwise long-range dataset
|
|
120
|
+
const dataset = J > -73048.5 && J < 18626.5 ? oe[1] : oe[0];
|
|
121
|
+
const [a, e, I, L, wBar, Omega] = dataset.map(([x0, x1]) => x0 + x1 * T);
|
|
122
|
+
const omega = wBar - Omega; // argument of periapsis
|
|
123
|
+
let M = L - wBar; // mean anomaly
|
|
124
|
+
// Perturbation correction for outer planets
|
|
125
|
+
if (oe[2]) {
|
|
126
|
+
const [b, c, s, f] = oe[2];
|
|
127
|
+
M += b * T * T + c * cosDeg(f * T) + s * sinDeg(f * T);
|
|
128
|
+
}
|
|
129
|
+
const E = kepler(M, e);
|
|
130
|
+
const xh = a * (cosDeg(E) - e);
|
|
131
|
+
const yh = a * Math.sqrt(1 - e * e) * sinDeg(E);
|
|
132
|
+
const cO = cosDeg(Omega), sO = sinDeg(Omega);
|
|
133
|
+
const cw = cosDeg(omega), sw = sinDeg(omega);
|
|
134
|
+
const cI = cosDeg(I), sI = sinDeg(I);
|
|
135
|
+
// Ecliptic heliocentric Cartesian
|
|
136
|
+
const x = (cw * cO - sw * sO * cI) * xh + (-sw * cO - cw * sO * cI) * yh;
|
|
137
|
+
const y = (cw * sO + sw * cO * cI) * xh + (-sw * sO + cw * cO * cI) * yh;
|
|
138
|
+
const z = sw * sI * xh + cw * sI * yh;
|
|
139
|
+
const [helioLon, helioLat, helioR] = toSpherical(x, y, z);
|
|
140
|
+
// Geocentric (add Sun's geocentric position vector to flip to Earth-centered)
|
|
141
|
+
const xg = x + sun.geo.x;
|
|
142
|
+
const yg = y + sun.geo.y;
|
|
143
|
+
const zg = z + sun.geo.z;
|
|
144
|
+
const [geoLon, geoLat, geoDist] = toSpherical(xg, yg, zg);
|
|
145
|
+
const [xe, ye, ze] = toEquatorial(xg, yg, zg, eps);
|
|
146
|
+
const [ra, dec, rho] = toSpherical(xe, ye, ze);
|
|
147
|
+
return {
|
|
148
|
+
helio: { x, y, z, lon: wrapAngle(helioLon), lat: helioLat, dist: helioR },
|
|
149
|
+
geo: {
|
|
150
|
+
x: xg, y: yg, z: zg,
|
|
151
|
+
lon: wrapAngle(geoLon), lat: geoLat, dist: geoDist,
|
|
152
|
+
equatorial: { x: xe, y: ye, z: ze, ra: wrapAngle(ra), dec, dist: rho },
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=position.js.map
|