UNPKG

10.4 kBJavaScriptView Raw
1var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2
3function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4
5/**
6 * @copyright 2013 Sonia Keys
7 * @copyright 2016 commenthol
8 * @license MIT
9 * @module elliptic
10 */
11/**
12 * Elliptic: Chapter 33, Elliptic Motion.
13 *
14 * Partial: Various formulas and algorithms are unimplemented for lack of
15 * examples or test cases.
16 */
17import apparent from './apparent';
18import base from './base';
19import coord from './coord';
20import kepler from './kepler';
21import nutation from './nutation';
22import planetposition from './planetposition';
23import solarxyz from './solarxyz';
24
25/**
26 * Position returns observed equatorial coordinates of a planet at a given time.
27 *
28 * Argument p must be a valid V87Planet object for the observed planet.
29 * Argument earth must be a valid V87Planet object for Earth.
30 *
31 * Results are right ascension and declination, α and δ in radians.
32 */
33export function position(planet, earth, jde) {
34 // (p, earth *pp.V87Planet, jde float64) (α, δ float64)
35 var x = void 0;
36 var y = void 0;
37 var z = void 0;
38 var posEarth = earth.position(jde);
39 var _ref = [posEarth.lon, posEarth.lat, posEarth.range],
40 L0 = _ref[0],
41 B0 = _ref[1],
42 R0 = _ref[2];
43
44 var _base$sincos = base.sincos(B0),
45 sB0 = _base$sincos[0],
46 cB0 = _base$sincos[1];
47
48 var _base$sincos2 = base.sincos(L0),
49 sL0 = _base$sincos2[0],
50 cL0 = _base$sincos2[1];
51
52 function pos() {
53 var τ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
54
55 var pos = planet.position(jde - τ);
56 var _ref2 = [pos.lon, pos.lat, pos.range],
57 L = _ref2[0],
58 B = _ref2[1],
59 R = _ref2[2];
60
61 var _base$sincos3 = base.sincos(B),
62 sB = _base$sincos3[0],
63 cB = _base$sincos3[1];
64
65 var _base$sincos4 = base.sincos(L),
66 sL = _base$sincos4[0],
67 cL = _base$sincos4[1];
68
69 x = R * cB * cL - R0 * cB0 * cL0;
70 y = R * cB * sL - R0 * cB0 * sL0;
71 z = R * sB - R0 * sB0;
72 }
73
74 pos();
75 var Δ = Math.sqrt(x * x + y * y + z * z); // (33.4) p. 224
76 var τ = base.lightTime(Δ);
77 // repeating with jde-τ
78 pos(τ);
79
80 var λ = Math.atan2(y, x); // (33.1) p. 223
81 var β = Math.atan2(z, Math.hypot(x, y)); // (33.2) p. 223
82
83 var _apparent$eclipticAbe = apparent.eclipticAberration(λ, β, jde),
84 Δλ = _apparent$eclipticAbe[0],
85 Δβ = _apparent$eclipticAbe[1];
86
87 var fk5 = planetposition.toFK5(λ + Δλ, β + Δβ, jde);
88 λ = fk5.lon;
89 β = fk5.lat;
90
91 var _nutation$nutation = nutation.nutation(jde),
92 Δψ = _nutation$nutation[0],
93 Δε = _nutation$nutation[1];
94
95 λ += Δψ;
96 var ε = nutation.meanObliquity(jde) + Δε;
97 return new coord.Ecliptic(λ, β).toEquatorial(ε);
98 // Meeus gives a formula for elongation but doesn't spell out how to
99 // obtaion term λ0 and doesn't give an example solution.
100}
101
102/**
103 * Elements holds keplerian elements.
104 */
105export var Elements = function () {
106 /*
107 Axis float64 // Semimajor axis, a, in AU
108 Ecc float64 // Eccentricity, e
109 Inc float64 // Inclination, i, in radians
110 ArgP float64 // Argument of perihelion, ω, in radians
111 Node float64 // Longitude of ascending node, Ω, in radians
112 TimeP float64 // Time of perihelion, T, as jde
113 */
114 function Elements(axis, ecc, inc, argP, node, timeP) {
115 _classCallCheck(this, Elements);
116
117 var o = {};
118 if ((typeof axis === 'undefined' ? 'undefined' : _typeof(axis)) === 'object') {
119 o = axis;
120 }
121 this.axis = o.axis || axis;
122 this.ecc = o.ecc || ecc;
123 this.inc = o.inc || inc;
124 this.argP = o.argP || argP;
125 this.node = o.node || node;
126 this.timeP = o.timeP || timeP;
127 }
128
129 /**
130 * Position returns observed equatorial coordinates of a body with Keplerian elements.
131 *
132 * Argument e must be a valid V87Planet object for Earth.
133 *
134 * Results are right ascension and declination α and δ, and elongation ψ,
135 * all in radians.
136 */
137
138
139 Elements.prototype.position = function position(jde, earth) {
140 var _this = this;
141
142 // (α, δ, ψ float64) {
143 // (33.6) p. 227
144 var n = base.K / this.axis / Math.sqrt(this.axis);
145 var sε = base.SOblJ2000;
146 var cε = base.COblJ2000;
147
148 var _base$sincos5 = base.sincos(this.node),
149 sΩ = _base$sincos5[0],
150 cΩ = _base$sincos5[1];
151
152 var _base$sincos6 = base.sincos(this.inc),
153 si = _base$sincos6[0],
154 ci = _base$sincos6[1];
155 // (33.7) p. 228
156
157
158 var F = cΩ;
159 var G = sΩ * cε;
160 var H = sΩ * sε;
161 var P = -sΩ * ci;
162 var Q = cΩ * ci * cε - si * sε;
163 var R = cΩ * ci * sε + si * cε;
164 // (33.8) p. 229
165 var A = Math.atan2(F, P);
166 var B = Math.atan2(G, Q);
167 var C = Math.atan2(H, R);
168 var a = Math.hypot(F, P);
169 var b = Math.hypot(G, Q);
170 var c = Math.hypot(H, R);
171
172 var f = function f(jde) {
173 // (x, y, z float64) {
174 var M = n * (jde - _this.timeP);
175 var E = void 0;
176 try {
177 E = kepler.kepler2b(_this.ecc, M, 15);
178 } catch (e) {
179 E = kepler.kepler3(_this.ecc, M);
180 }
181 var ν = kepler.trueAnomaly(E, _this.ecc);
182 var r = kepler.radius(E, _this.ecc, _this.axis);
183 // (33.9) p. 229
184 var x = r * a * Math.sin(A + _this.argP + ν);
185 var y = r * b * Math.sin(B + _this.argP + ν);
186 var z = r * c * Math.sin(C + _this.argP + ν);
187 return { x: x, y: y, z: z };
188 };
189 return astrometricJ2000(f, jde, earth);
190 };
191
192 return Elements;
193}();
194
195/**
196 * AstrometricJ2000 is a utility function for computing astrometric coordinates.
197 *
198 * It is used internally and only exported so that it can be used from
199 * multiple packages. It is not otherwise expected to be used.
200 *
201 * Argument f is a function that returns J2000 equatorial rectangular
202 * coodinates of a body.
203 *
204 * Results are J2000 right ascention, declination, and elongation.
205 */
206export function astrometricJ2000(f, jde, earth) {
207 // (f func(float64) (x, y, z float64), jde float64, e *pp.V87Planet) (α, δ, ψ float64)
208 var sol = solarxyz.positionJ2000(earth, jde);
209 var _ref3 = [sol.x, sol.y, sol.z],
210 X = _ref3[0],
211 Y = _ref3[1],
212 Z = _ref3[2];
213
214 var ξ = void 0;
215 var η = void 0;
216 var ζ = void 0;
217 var Δ = void 0;
218
219 function fn() {
220 var τ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
221
222 // (33.10) p. 229
223 var _f = f(jde - τ),
224 x = _f.x,
225 y = _f.y,
226 z = _f.z;
227
228 ξ = X + x;
229 η = Y + y;
230 ζ = Z + z;
231 Δ = Math.sqrt(ξ * ξ + η * η + ζ * ζ);
232 }
233
234 fn();
235 var τ = base.lightTime(Δ);
236 fn(τ);
237
238 var α = Math.atan2(η, ξ);
239 if (α < 0) {
240 α += 2 * Math.PI;
241 }
242 var δ = Math.asin(ζ / Δ);
243 var R0 = Math.sqrt(X * X + Y * Y + Z * Z);
244 var ψ = Math.acos((ξ * X + η * Y + ζ * Z) / R0 / Δ);
245 return new base.Coord(α, δ, undefined, ψ);
246}
247
248/**
249 * Velocity returns instantaneous velocity of a body in elliptical orbit around the Sun.
250 *
251 * Argument a is the semimajor axis of the body, r is the instaneous distance
252 * to the Sun, both in AU.
253 *
254 * Result is in Km/sec.
255 */
256export function velocity(a, r) {
257 // (a, r float64) float64
258 return 42.1219 * Math.sqrt(1 / r - 0.5 / a);
259}
260
261/**
262 * Velocity returns the velocity of a body at aphelion.
263 *
264 * Argument a is the semimajor axis of the body in AU, e is eccentricity.
265 *
266 * Result is in Km/sec.
267 */
268export function vAphelion(a, e) {
269 // (a, e float64) float64
270 return 29.7847 * Math.sqrt((1 - e) / (1 + e) / a);
271}
272
273/**
274 * Velocity returns the velocity of a body at perihelion.
275 *
276 * Argument a is the semimajor axis of the body in AU, e is eccentricity.
277 *
278 * Result is in Km/sec.
279 */
280export function vPerihelion(a, e) {
281 // (a, e float64) float64
282 return 29.7847 * Math.sqrt((1 + e) / (1 - e) / a);
283}
284
285/**
286 * Length1 returns Ramanujan's approximation for the length of an elliptical
287 * orbit.
288 *
289 * Argument a is semimajor axis, e is eccentricity.
290 *
291 * Result is in units used for semimajor axis, typically AU.
292 */
293export function length1(a, e) {
294 // (a, e float64) float64
295 var b = a * Math.sqrt(1 - e * e);
296 return Math.PI * (3 * (a + b) - Math.sqrt((a + 3 * b) * (3 * a + b)));
297}
298
299/**
300 * Length2 returns an alternate approximation for the length of an elliptical
301 * orbit.
302 *
303 * Argument a is semimajor axis, e is eccentricity.
304 *
305 * Result is in units used for semimajor axis, typically AU.
306 */
307export function length2(a, e) {
308 // (a, e float64) float64
309 var b = a * Math.sqrt(1 - e * e);
310 var s = a + b;
311 var p = a * b;
312 var A = s * 0.5;
313 var G = Math.sqrt(p);
314 var H = 2 * p / s;
315 return Math.PI * (21 * A - 2 * G - 3 * H) * 0.125;
316}
317
318/**
319 * Length3 returns the length of an elliptical orbit.
320 *
321 * Argument a is semimajor axis, e is eccentricity.
322 *
323 * Result is exact, and in units used for semimajor axis, typically AU.
324 */
325/* As Meeus notes, Length4 converges faster. There is no reason to use
326this function
327export function length3 (a, e) { // (a, e float64) float64
328 const sum0 = 1.0
329 const e2 = e * e
330 const term = e2 * 0.25
331 const sum1 = 1.0 - term
332 const nf = 1.0
333 const df = 2.0
334 while (sum1 !== sum0) {
335 term *= nf
336 nf += 2
337 df += 2
338 term *= nf * e2 / (df * df)
339 sum0 = sum1
340 sum1 -= term
341 }
342 return 2 * Math.PI * a * sum0
343} */
344
345/**
346 * Length4 returns the length of an elliptical orbit.
347 *
348 * Argument a is semimajor axis, e is eccentricity.
349 *
350 * Result is exact, and in units used for semimajor axis, typically AU.
351 */
352export function length4(a, e) {
353 // (a, e float64) float64
354 var b = a * Math.sqrt(1 - e * e);
355 var m = (a - b) / (a + b);
356 var m2 = m * m;
357 var sum0 = 1.0;
358 var term = m2 * 0.25;
359 var sum1 = 1.0 + term;
360 var nf = -1.0;
361 var df = 2.0;
362 while (sum1 !== sum0) {
363 nf += 2;
364 df += 2;
365 term *= nf * nf * m2 / (df * df);
366 sum0 = sum1;
367 sum1 += term;
368 }
369 return 2 * Math.PI * a * sum0 / (1 + m);
370}
371
372export default {
373 position: position,
374 Elements: Elements,
375 astrometricJ2000: astrometricJ2000,
376 velocity: velocity,
377 vAphelion: vAphelion,
378 vPerihelion: vPerihelion,
379 length1: length1,
380 length2: length2,
381 // length3,
382 length4: length4
383};
\No newline at end of file