celestial-chart 0.8.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/CHANGELOG.md +105 -0
- package/LICENSE +13 -0
- package/NOTICE.md +41 -0
- package/README.md +192 -0
- package/build/celestial.cjs +15354 -0
- package/build/celestial.js +15330 -0
- package/build/celestial.min.js +7 -0
- package/build/celestial.mjs +15333 -0
- package/celestial.css +111 -0
- package/images/dtpick.png +0 -0
- package/lib/geo-zoom.js +116 -0
- package/package.json +89 -0
- package/src/add.js +46 -0
- package/src/canvas.js +269 -0
- package/src/celestial.js +1177 -0
- package/src/config.js +537 -0
- package/src/core.js +14 -0
- package/src/d3.js +28 -0
- package/src/datetimepicker.js +233 -0
- package/src/form.js +837 -0
- package/src/get.js +210 -0
- package/src/global.js +4 -0
- package/src/horizontal.js +98 -0
- package/src/index.js +8 -0
- package/src/kepler.js +481 -0
- package/src/location.js +359 -0
- package/src/moon.js +522 -0
- package/src/projection.js +205 -0
- package/src/svg.js +879 -0
- package/src/timezones.js +71 -0
- package/src/transform.js +94 -0
- package/src/util.js +275 -0
- package/types/celestial.d.ts +545 -0
package/src/kepler.js
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { Moon } from "./moon.js";
|
|
2
|
+
import { deg2rad, halfπ, τ } from "./transform.js";
|
|
3
|
+
import { Trig, dateParse, has } from "./util.js";
|
|
4
|
+
|
|
5
|
+
/* global transform, Trig, Moon, deg2rad, dateParse, has, halfπ, τ */
|
|
6
|
+
var gmdat = {
|
|
7
|
+
"sol": 0.0002959122082855911025, // AU^3/d^2
|
|
8
|
+
"mer": 164468599544771, //km^3/d^2
|
|
9
|
+
"ven": 2425056445892137,
|
|
10
|
+
"ter": 2975536307796296,
|
|
11
|
+
"lun": 36599199229256,
|
|
12
|
+
"mar": 319711652803400,
|
|
13
|
+
"cer": 467549107200,
|
|
14
|
+
"ves": 129071530155,
|
|
15
|
+
"jup": 945905718740635000,
|
|
16
|
+
"sat": 283224952705891000,
|
|
17
|
+
"ura": 43256077238632300,
|
|
18
|
+
"nep": 51034401552155700,
|
|
19
|
+
"plu": 7327611364884,
|
|
20
|
+
"eri": 8271175680000
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
symbols = {
|
|
25
|
+
"sol":"\u2609", "mer":"\u263f", "ven":"\u2640", "ter":"\u2295", "lun":"\u25cf", "mar":"\u2642", "cer":"\u26b3",
|
|
26
|
+
"ves":"\u26b6", "jup":"\u2643", "sat":"\u2644", "ura":"\u2645", "nep":"\u2646", "plu":"\u2647", "eri":"\u26aa"
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
ε = 23.43928 * deg2rad,
|
|
30
|
+
sinε = Math.sin(ε),
|
|
31
|
+
cosε = Math.cos(ε),
|
|
32
|
+
kelements = ["a","e","i","w","M","L","W","N","n","ep","ref","lecl","becl","Tilt"];
|
|
33
|
+
/*
|
|
34
|
+
ep = epoch (iso-date)
|
|
35
|
+
N = longitude of the ascending node (deg) Ω
|
|
36
|
+
i = inclination to the refrence plane, default:ecliptic (deg)
|
|
37
|
+
w = argument of periapsis (deg) ω
|
|
38
|
+
a = semi-major axis, or mean distance from parent body (AU,km)
|
|
39
|
+
e = eccentricity (0=circle, 0-1=ellipse, 1=parabola, >1=hyperbola ) (-)
|
|
40
|
+
M = mean anomaly (0 at periapsis; increases uniformly with time) (deg)
|
|
41
|
+
n = mean daily motion = 360/P (deg/day)
|
|
42
|
+
|
|
43
|
+
W = N + w = longitude of periapsis ϖ
|
|
44
|
+
L = M + W = mean longitude
|
|
45
|
+
q = a*(1-e) = periapsis distance
|
|
46
|
+
Q = a*(1+e) = apoapsis distance
|
|
47
|
+
P = 2π * sqrt(a^3/GM) = orbital period (years)
|
|
48
|
+
T = Epoch_of_M - (M(deg)/360_deg) / P = time of periapsis
|
|
49
|
+
v = true anomaly (angle between position and periapsis) ν
|
|
50
|
+
E = eccentric anomaly
|
|
51
|
+
|
|
52
|
+
Mandatory: a, e, i, N, w|W, M|L, dM|n
|
|
53
|
+
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
var Kepler = function () {
|
|
57
|
+
var gm = gmdat.sol,
|
|
58
|
+
parentBody = "sol",
|
|
59
|
+
elem = {}, dat = {},
|
|
60
|
+
id, name, symbol;
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
function kepler(date) {
|
|
64
|
+
dates(date);
|
|
65
|
+
if (id === "sol") {
|
|
66
|
+
dat.ephemeris.x = 0;
|
|
67
|
+
dat.ephemeris.y = 0;
|
|
68
|
+
dat.ephemeris.z = 0;
|
|
69
|
+
dat.ephemeris.mag = -6;
|
|
70
|
+
return kepler;
|
|
71
|
+
}
|
|
72
|
+
coordinates();
|
|
73
|
+
return kepler;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var dates = function(date) {
|
|
77
|
+
var dt, de = dat.ephemeris = {};
|
|
78
|
+
if (date) {
|
|
79
|
+
if (date instanceof Date) { dt = new Date(date.valueOf()); }
|
|
80
|
+
else { dt = dateParse(date); }
|
|
81
|
+
}
|
|
82
|
+
if (!dt) { dt = new Date(); }
|
|
83
|
+
de.jd = JD(dt);
|
|
84
|
+
|
|
85
|
+
dt = dateParse(elem.ep);
|
|
86
|
+
if (!dt) dt = dateParse("2000-01-01");
|
|
87
|
+
de.jd0 = JD(dt);
|
|
88
|
+
de.d = de.jd - de.jd0;
|
|
89
|
+
de.cy = de.d / 36525;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
var coordinates = function() {
|
|
93
|
+
var key, de = dat.ephemeris;
|
|
94
|
+
if (id === "lun") {
|
|
95
|
+
de = moon_elements(de);
|
|
96
|
+
if (!de) return;
|
|
97
|
+
} else {
|
|
98
|
+
for (var i=0; i<kelements.length; i++) {
|
|
99
|
+
key = kelements[i];
|
|
100
|
+
if (!has(elem, key)) continue;
|
|
101
|
+
if (has(elem, "d"+key)) {
|
|
102
|
+
de[key] = elem[key] + elem["d"+key] * de.cy;
|
|
103
|
+
} else if (has(elem, key)) {
|
|
104
|
+
de[key] = elem[key];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (has(de, "M") && !has(de, "dM") && has(de, "n")) {
|
|
108
|
+
de.M += (de.n * de.d);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
derive();
|
|
112
|
+
trueAnomaly();
|
|
113
|
+
cartesian();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
kepler.cartesian = function() {
|
|
117
|
+
return dat;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
kepler.spherical = function() {
|
|
121
|
+
spherical();
|
|
122
|
+
return dat;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
kepler.equatorial = function(pos) {
|
|
126
|
+
equatorial(pos);
|
|
127
|
+
return dat;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
kepler.transpose = function() {
|
|
131
|
+
transpose(dat);
|
|
132
|
+
return dat;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
kepler.elements = function(_) {
|
|
136
|
+
var key;
|
|
137
|
+
|
|
138
|
+
if (!arguments.length || arguments[0] === undefined) return kepler;
|
|
139
|
+
|
|
140
|
+
for (var i=0; i<kelements.length; i++) {
|
|
141
|
+
key = kelements[i];
|
|
142
|
+
if (!has(_, key)) continue;
|
|
143
|
+
elem[key] = _[key];
|
|
144
|
+
|
|
145
|
+
if (key === "a" || key === "e") elem[key] *= 1.0;
|
|
146
|
+
else if (key !== "ref" && key !== "ep") elem[key] *= deg2rad;
|
|
147
|
+
|
|
148
|
+
if (has(_, "d" + key)) {
|
|
149
|
+
key = "d" + key;
|
|
150
|
+
elem[key] = _[key];
|
|
151
|
+
if (key === "da" || key === "de") elem[key] *= 1.0;
|
|
152
|
+
else elem[key] *= deg2rad;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return kepler;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
kepler.params = function(_) {
|
|
159
|
+
if (!arguments.length) return kepler;
|
|
160
|
+
for (var par in _) {
|
|
161
|
+
if (!has(_, par)) continue;
|
|
162
|
+
if (_[par] === "elements") continue;
|
|
163
|
+
dat[par] = _[par];
|
|
164
|
+
}
|
|
165
|
+
return kepler;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
kepler.parentBody = function(_) {
|
|
170
|
+
if (!arguments.length) return parentBody;
|
|
171
|
+
parentBody = _;
|
|
172
|
+
gm = gmdat[parentBody];
|
|
173
|
+
return kepler;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
kepler.id = function(_) {
|
|
177
|
+
if (!arguments.length) return id;
|
|
178
|
+
id = _;
|
|
179
|
+
symbol = symbols[_];
|
|
180
|
+
return kepler;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
kepler.Name = function(_) {
|
|
184
|
+
if (!arguments.length) return name;
|
|
185
|
+
name = _;
|
|
186
|
+
return kepler;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
kepler.symbol = function(_) {
|
|
190
|
+
if (!arguments.length) return symbol;
|
|
191
|
+
symbol = symbols[_];
|
|
192
|
+
return kepler;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
function near_parabolic(E, e) {
|
|
197
|
+
var anom2 = e > 1.0 ? E*E : -E*E,
|
|
198
|
+
term = e * anom2 * E / 6.0,
|
|
199
|
+
rval = (1.0 - e) * E - term,
|
|
200
|
+
n = 4;
|
|
201
|
+
|
|
202
|
+
while(Math.abs(term) > 1e-15) {
|
|
203
|
+
term *= anom2 / (n * (n + 1));
|
|
204
|
+
rval -= term;
|
|
205
|
+
n += 2;
|
|
206
|
+
}
|
|
207
|
+
return(rval);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function anomaly() {
|
|
211
|
+
var de = dat.ephemeris,
|
|
212
|
+
curr, err, trial, tmod,
|
|
213
|
+
e = de.e, M = de.M,
|
|
214
|
+
thresh = 1e-8,
|
|
215
|
+
offset = 0.0,
|
|
216
|
+
delta_curr = 1.9,
|
|
217
|
+
is_negative = false,
|
|
218
|
+
n_iter = 0;
|
|
219
|
+
|
|
220
|
+
if (!M) return(0.0);
|
|
221
|
+
|
|
222
|
+
if (e < 1.0) {
|
|
223
|
+
if (M < -Math.PI || M > Math.PI) {
|
|
224
|
+
tmod = Trig.normalize0(M);
|
|
225
|
+
offset = M - tmod;
|
|
226
|
+
M = tmod;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (e < 0.9) {
|
|
230
|
+
curr = Math.atan2(Math.sin(M), Math.cos(M) - e);
|
|
231
|
+
do {
|
|
232
|
+
err = (curr - e * Math.sin(curr) - M) / (1.0 - e * Math.cos(curr));
|
|
233
|
+
curr -= err;
|
|
234
|
+
} while (Math.abs(err) > thresh);
|
|
235
|
+
return curr; // + offset;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if ( M < 0.0) {
|
|
240
|
+
M = -M;
|
|
241
|
+
is_negative = true;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
curr = M;
|
|
245
|
+
thresh = thresh * Math.abs(1.0 - e);
|
|
246
|
+
/* Due to roundoff error, there's no way we can hope to */
|
|
247
|
+
/* get below a certain minimum threshhold anyway: */
|
|
248
|
+
if ( thresh < 1e-15) { thresh = 1e-15; }
|
|
249
|
+
if ( (e > 0.8 && M < Math.PI / 3.0) || e > 1.0) { /* up to 60 degrees */
|
|
250
|
+
trial = M / Math.abs( 1.0 - e);
|
|
251
|
+
|
|
252
|
+
if (trial * trial > 6.0 * Math.abs(1.0 - e)) { /* cubic term is dominant */
|
|
253
|
+
if (M < Math.PI) {
|
|
254
|
+
trial = Math.pow(6.0 * M, 1/3);
|
|
255
|
+
} else { /* hyperbolic w/ 5th & higher-order terms predominant */
|
|
256
|
+
trial = Trig.asinh( M / e);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
curr = trial;
|
|
260
|
+
}
|
|
261
|
+
if (e > 1.0 && M > 4.0) { /* hyperbolic, large-mean-anomaly case */
|
|
262
|
+
curr = Math.log(M);
|
|
263
|
+
}
|
|
264
|
+
if (e < 1.0) {
|
|
265
|
+
while(Math.abs(delta_curr) > thresh) {
|
|
266
|
+
if ( n_iter++ > 8) {
|
|
267
|
+
err = near_parabolic(curr, e) - M;
|
|
268
|
+
} else {
|
|
269
|
+
err = curr - e * Math.sin(curr) - M;
|
|
270
|
+
}
|
|
271
|
+
delta_curr = -err / (1.0 - e * Math.cos(curr));
|
|
272
|
+
curr += delta_curr;
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
while (Math.abs(delta_curr) > thresh) {
|
|
276
|
+
if (n_iter++ > 7) {
|
|
277
|
+
err = -near_parabolic(curr, e) - M;
|
|
278
|
+
} else {
|
|
279
|
+
err = e * Trig.sinh(curr) - curr - M;
|
|
280
|
+
}
|
|
281
|
+
delta_curr = -err / (e * Trig.cosh(curr) - 1.0);
|
|
282
|
+
curr += delta_curr;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return( is_negative ? offset - curr : offset + curr);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function trueAnomaly() {
|
|
289
|
+
var x, y, r0, g, t, de = dat.ephemeris;
|
|
290
|
+
|
|
291
|
+
if (de.e === 1.0) { /* parabolic */
|
|
292
|
+
t = de.jd0 - de.T;
|
|
293
|
+
g = de.w0 * t * 0.5;
|
|
294
|
+
|
|
295
|
+
y = Math.pow(g + Math.sqrt(g * g + 1.0), 1/3);
|
|
296
|
+
de.v = 2.0 * Math.atan(y - 1.0 / y);
|
|
297
|
+
} else { /* got the mean anomaly; compute eccentric, then true */
|
|
298
|
+
de.E = anomaly();
|
|
299
|
+
if (de.e > 1.0) { /* hyperbolic case */
|
|
300
|
+
x = (de.e - Trig.cosh(de.E));
|
|
301
|
+
y = Trig.sinh(de.E);
|
|
302
|
+
} else { /* elliptical case */
|
|
303
|
+
x = (Math.cos(de.E) - de.e);
|
|
304
|
+
y = Math.sin(de.E);
|
|
305
|
+
}
|
|
306
|
+
y *= Math.sqrt(Math.abs(1.0 - de.e * de.e));
|
|
307
|
+
de.v = Math.atan2(y, x);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
r0 = de.q * (1.0 + de.e);
|
|
311
|
+
de.r = r0 / (1.0 + de.e * Math.cos(de.v));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function derive() {
|
|
315
|
+
var de = dat.ephemeris;
|
|
316
|
+
if (!de.hasOwnProperty("w")) {
|
|
317
|
+
de.w = de.W - de.N;
|
|
318
|
+
}
|
|
319
|
+
if (!de.hasOwnProperty("M")) {
|
|
320
|
+
de.M = de.L - de.W;
|
|
321
|
+
}
|
|
322
|
+
if (de.e < 1.0) { de.M = Trig.normalize0(de.M); }
|
|
323
|
+
//de.P = Math.pow(Math.abs(de.a), 1.5);
|
|
324
|
+
de.P = τ * Math.sqrt(Math.pow(de.a, 3) / gm) / 365.25;
|
|
325
|
+
de.T = de.jd0 - (de.M / halfπ) / de.P;
|
|
326
|
+
|
|
327
|
+
if (de.e !== 1.0) { /* for non-parabolic orbits: */
|
|
328
|
+
de.q = de.a * (1.0 - de.e);
|
|
329
|
+
de.t0 = de.a * Math.sqrt(Math.abs(de.a) / gm);
|
|
330
|
+
} else {
|
|
331
|
+
de.w0 = (3.0 / Math.sqrt(2)) / (de.q * Math.sqrt(de.q / gm));
|
|
332
|
+
de.a = 0.0;
|
|
333
|
+
de.t0 = 0.0;
|
|
334
|
+
}
|
|
335
|
+
de.am = Math.sqrt(gm * de.q * (1.0 + de.e));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function transpose() {
|
|
339
|
+
var de = dat.ephemeris;
|
|
340
|
+
if (!de.ref || de.ref === "ecl") {
|
|
341
|
+
de.tx = de.x;
|
|
342
|
+
de.ty = de.y;
|
|
343
|
+
de.tz = de.z;
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
var a0 = de.lecl,// - Math.PI/2,
|
|
347
|
+
a1 = Math.PI/2 - de.becl,
|
|
348
|
+
angles = [0, a1, -a0];
|
|
349
|
+
transform(de, angles);
|
|
350
|
+
var tp = Trig.cartesian([de.tl, de.tb, de.r]);
|
|
351
|
+
de.tx = tp.x;
|
|
352
|
+
de.ty = tp.y;
|
|
353
|
+
de.tz = tp.z;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function equatorial(pos) {
|
|
357
|
+
var de = dat.ephemeris, pe = pos.ephemeris;
|
|
358
|
+
ε = (23.439292 - 0.0130042 * de.cy - 1.667e-7 * de.cy * de.cy + 5.028e-7 * de.cy * de.cy * de.cy) * deg2rad;
|
|
359
|
+
sinε = Math.sin(ε);
|
|
360
|
+
cosε = Math.cos(ε);
|
|
361
|
+
var o = (id === "lun") ? {x:0, y:0, z:0} : {x:pe.x, y:pe.y, z:pe.z};
|
|
362
|
+
de.xeq = de.x - o.x;
|
|
363
|
+
de.yeq = (de.y - o.y) * cosε - (de.z - o.z) * sinε;
|
|
364
|
+
de.zeq = (de.y - o.y) * sinε + (de.z - o.z) * cosε;
|
|
365
|
+
|
|
366
|
+
de.ra = Trig.normalize(Math.atan2(de.yeq, de.xeq));
|
|
367
|
+
de.dec = Math.atan2(de.zeq, Math.sqrt(de.xeq*de.xeq + de.yeq*de.yeq));
|
|
368
|
+
if (id === "lun") de = moon_corr(de, pe);
|
|
369
|
+
de.pos = [de.ra / deg2rad, de.dec / deg2rad];
|
|
370
|
+
de.rt = Math.sqrt(de.xeq*de.xeq + de.yeq*de.yeq + de.zeq*de.zeq);
|
|
371
|
+
if (id !== "sol") de.mag = magnitude();
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function magnitude() {
|
|
375
|
+
var de = dat.ephemeris,
|
|
376
|
+
rs = de.r, rt = de.rt,
|
|
377
|
+
a = Math.acos((rs*rs + rt*rt - 1) / (2 * rs * rt)),
|
|
378
|
+
q = 0.666 *((1-a/Math.PI) * Math.cos(a) + 1 / Math.PI * Math.sin(a)),
|
|
379
|
+
m = dat.H * 1 + 5 * Math.log(rs*rt) * Math.LOG10E - 2.5 * Math.log(q) * Math.LOG10E;
|
|
380
|
+
|
|
381
|
+
return m;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function cartesian() {
|
|
385
|
+
var de = dat.ephemeris,
|
|
386
|
+
u = de.v + de.w;
|
|
387
|
+
de.x = de.r * (Math.cos(de.N) * Math.cos(u) - Math.sin(de.N) * Math.sin(u) * Math.cos(de.i));
|
|
388
|
+
de.y = de.r * (Math.sin(de.N) * Math.cos(u) + Math.cos(de.N) * Math.sin(u) * Math.cos(de.i));
|
|
389
|
+
de.z = de.r * (Math.sin(u) * Math.sin(de.i));
|
|
390
|
+
return dat;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function spherical() {
|
|
394
|
+
var de = dat.ephemeris,
|
|
395
|
+
lon = Math.atan2(de.y, de.x),
|
|
396
|
+
lat = Math.atan2(de.z, Math.sqrt(de.x*de.x + de.y*de.y));
|
|
397
|
+
de.l = Trig.normalize(lon);
|
|
398
|
+
de.b = lat;
|
|
399
|
+
return dat;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function transform(angles) {
|
|
403
|
+
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function polar2cart(pos) {
|
|
407
|
+
var rclat = Math.cos(pos.lat) * pos.r;
|
|
408
|
+
pos.x = rclat * Math.cos(pos.lon);
|
|
409
|
+
pos.y = rclat * Math.sin(pos.lon);
|
|
410
|
+
pos.z = pos.r * Math.sin(pos.lat);
|
|
411
|
+
return pos;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
function JD(dt) {
|
|
416
|
+
var yr = dt.getUTCFullYear(),
|
|
417
|
+
mo = dt.getUTCMonth() + 1,
|
|
418
|
+
dy = dt.getUTCDate(),
|
|
419
|
+
frac = (dt.getUTCHours() - 12 + dt.getUTCMinutes()/60.0 + dt.getUTCSeconds()/3600.0) / 24,
|
|
420
|
+
IYMIN = -4799; /* Earliest year allowed (4800BC) */
|
|
421
|
+
|
|
422
|
+
if (yr < IYMIN) return -1;
|
|
423
|
+
var a = Math.floor((14 - mo) / 12),
|
|
424
|
+
y = yr + 4800 - a,
|
|
425
|
+
m = mo + (12 * a) - 3;
|
|
426
|
+
var jdn = dy + Math.floor((153 * m + 2)/5) + (365 * y) + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400) - 32045;
|
|
427
|
+
return jdn + frac;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function mst(lon) {
|
|
431
|
+
var l = lon || 0; // lon=0 -> gmst
|
|
432
|
+
return (18.697374558 + 24.06570982441908 * dat.ephemeris.d) * 15 + l;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
function observer(pos) {
|
|
437
|
+
var flat = 298.257223563, // WGS84 flattening of earth
|
|
438
|
+
re = 6378.137, // GRS80/WGS84 semi major axis of earth ellipsoid
|
|
439
|
+
h = pos.h || 0,
|
|
440
|
+
cart = {},
|
|
441
|
+
gmst = mst();
|
|
442
|
+
|
|
443
|
+
var cosl = Math.cos(pos.lat),
|
|
444
|
+
sinl = Math.sin(pos.lat),
|
|
445
|
+
fl = 1.0 - 1.0 / flat;
|
|
446
|
+
var fl2 = fl * fl;
|
|
447
|
+
|
|
448
|
+
var u = 1.0 / Math.sqrt (cosl * cosl + fl2 * sinl * sinl),
|
|
449
|
+
a = re * u + h,
|
|
450
|
+
b = re * fl2 * u + h,
|
|
451
|
+
r = Math.sqrt (a * a * cosl * cosl + b * b * sinl * sinl); // geocentric distance from earth center
|
|
452
|
+
|
|
453
|
+
cart.lat = Math.acos (a * cosl / r);
|
|
454
|
+
cart.lon = pos.lon;
|
|
455
|
+
cart.r = h;
|
|
456
|
+
|
|
457
|
+
if (pos.lat < 0.0) cart.lat *= -1;
|
|
458
|
+
|
|
459
|
+
polar2cart(cart);
|
|
460
|
+
|
|
461
|
+
// rotate around earth's polar axis to align coordinate system from Greenwich to vernal equinox
|
|
462
|
+
var angle = gmst * deg2rad; // sideral time gmst given in hours. Convert to radians
|
|
463
|
+
|
|
464
|
+
cart.x = cart.x * Math.cos(angle) - cart.y * Math.sin(angle);
|
|
465
|
+
cart.y = cart.x * Math.sin(angle) + cart.y * Math.cos(angle);
|
|
466
|
+
return(cart);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function moon_elements(dat) {
|
|
470
|
+
if ((typeof Moon !== "undefined")) return Moon.elements(dat);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function moon_corr(dat, pos) {
|
|
474
|
+
spherical();
|
|
475
|
+
if ((typeof Moon !== "undefined")) return Moon.corr(dat, pos);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return kepler;
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
export { Kepler };
|