UNPKG

9.16 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.embary = exports.neptune = exports.uranus = exports.saturn = exports.jupiter = exports.mars = exports.earth = exports.venus = exports.mercury = undefined;
7
8var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /* eslint standard/no-callback-literal:0 */
9/**
10 * @copyright 2013 Sonia Keys
11 * @copyright 2016 commenthol
12 * @license MIT
13 * @module perihelion
14 */
15/**
16 * Perihelion: Chapter 38, Planets in Perihelion and Aphelion.
17 *
18 * Functions Aphelion and Perihelion implement algorithms from the book
19 * to return approximate results.
20 *
21 * For accurate results, Meeus describes the general technique of
22 * interpolating from a precise ephemeris but does not give a complete
23 * algorithm. The algorithm implemented here for Aphelion2 and Perihelion2
24 * is to start with the approximate result and then crawl along the curve
25 * at the specified time resolution until the desired extremum is found.
26 * This algorithm slows down as higher accuracy is demanded. 1 day accuracy
27 * is generally quick for planets other than Neptune.
28 *
29 * Meeus doesn't give an algorithm to handle the double extrema of Neptune.
30 * The algorithm here is to pick starting points several years either side
31 * of the approximate date and follow the slopes inward. The consequence of
32 * starting farther from the extremum is that these functions are particularly
33 * slow for Neptune. They are offered here though as a simple implementation
34 * of Meeus's presentation in the book.
35 */
36
37
38exports.perihelion = perihelion;
39exports.aphelion = aphelion;
40exports.perihelion2 = perihelion2;
41exports.aphelion2 = aphelion2;
42
43var _base = require('./base');
44
45var _base2 = _interopRequireDefault(_base);
46
47var _interpolation = require('./interpolation');
48
49var _interpolation2 = _interopRequireDefault(_interpolation);
50
51function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
52
53/**
54 * Planet constants for first argument of Perihelion and Aphelion functions.
55 */
56var planets = {};
57var mercury = exports.mercury = planets.mercury = 0;
58var venus = exports.venus = planets.venus = 1;
59var earth = exports.earth = planets.earth = 2;
60var mars = exports.mars = planets.mars = 3;
61var jupiter = exports.jupiter = planets.jupiter = 4;
62var saturn = exports.saturn = planets.saturn = 5;
63var uranus = exports.uranus = planets.uranus = 6;
64var neptune = exports.neptune = planets.neptune = 7;
65var embary = exports.embary = planets.embary = 8;
66
67/**
68 * Perihelion returns an approximate jde of the perihelion event nearest the given time.
69 *
70 * @param {perihelion.NAME} p - planet constant from above
71 * @param {Number} y - year number indicating a time near the perihelion event.
72 * @returns {Number} jde - time of the event
73 */
74function perihelion(p, year) {
75 return ap(p, year, false, pf);
76}
77
78/**
79 * Aphelion returns an approximate jde of the aphelion event nearest the given time.
80 *
81 * @param {perihelion.NAME} p - planet constant from above
82 * @param {Number} y - year number indicating a time near the aphelion event.
83 * @returns {Number} jde - time of the event
84 */
85function aphelion(p, year) {
86 return ap(p, year, true, af);
87}
88
89var pf = function pf(x) {
90 // (x float64) float64
91 return Math.floor(x + 0.5);
92};
93
94var af = function af(x) {
95 // (x float64) float64
96 return Math.floor(x) + 0.5;
97};
98
99var ap = function ap(p, y, a, f) {
100 // (p int, y float64, a bool, f func(float64) float64) float64
101 var i = p;
102 if (i === embary) {
103 i = earth;
104 }
105 var k = f(ka[i].a * (y - ka[i].b));
106 var j = _base2.default.horner(k, c[i]);
107 if (p === earth) {
108 var _c = ep;
109 if (a) {
110 _c = ea;
111 }
112 for (var _i = 0; _i < 5; _i++) {
113 j += _c[_i] * Math.sin((ec[_i].a + ec[_i].b * k) * Math.PI / 180);
114 }
115 }
116 return j;
117};
118
119var ka = [{ a: 4.15201, b: 2000.12 }, // Mercury
120{ a: 1.62549, b: 2000.53 }, // ...
121{ a: 0.99997, b: 2000.01 }, { a: 0.53166, b: 2001.78 }, { a: 0.0843, b: 2011.2 }, { a: 0.03393, b: 2003.52 }, { a: 0.0119, b: 2051.1 }, // Neptune
122{ a: 0.00607, b: 2047.5 // EMBary
123}];
124
125var c = [[2451590.257, 87.96934963], [2451738.233, 224.7008188, -0.0000000327], [2451547.507, 365.2596358, 0.0000000156], [2452195.026, 686.9957857, -0.0000001187], [2455636.936, 4332.897065, 0.0001367], [2452830.12, 10764.21676, 0.000827], [2470213.5, 30694.8767, -0.00541], [2468895.1, 60190.33, 0.03429]];
126
127var ec = [{ a: 328.41, b: 132.788585 }, { a: 316.13, b: 584.903153 }, { a: 346.2, b: 450.380738 }, { a: 136.95, b: 659.306737 }, { a: 249.52, b: 329.653368 }];
128
129var ep = [1.278, -0.055, -0.091, -0.056, -0.045];
130var ea = [-1.352, 0.061, 0.062, 0.029, 0.031];
131
132/**
133 * Perihelion2 returns the perihelion event nearest the given time.
134 *
135 * @param {planetposition.Planet} planet - VSOP87 planet (EMBary is not allowed)
136 * @param {Number} year - (float) decimal year number near the perihelion event
137 * @param {Number} precision - desired precision of the time result, in days
138 * @param {Function} [cb] - callback function for asynchronous processing `cb([jde, r])`
139 * @returns {Array} [jde, r]
140 * {Number} jde - time of the event
141 * {Number} r - the distance of the planet from the Sun in AU.
142 */
143function perihelion2(planet, year, precision, cb) {
144 return ap2(planets[planet.name], year, precision, planet, false, pf, cb);
145}
146
147/**
148 * Aphelion2 returns the aphelion event nearest the given time.
149 *
150 * @param {planetposition.Planet} planet - VSOP87 planet (EMBary is not allowed)
151 * @param {Number} year - (float) decimal year number near the perihelion event
152 * @param {Number} precision - desired precision of the time result, in days
153 * @param {Function} [cb] - callback function for asynchronous processing `cb([jde, r])`
154 * @returns {Array} [jde, r]
155 * {Number} jde - time of the event
156 * {Number} r - the distance of the planet from the Sun in AU.
157 */
158function aphelion2(planet, year, precision, cb) {
159 return ap2(planets[planet.name], year, precision, planet, true, af, cb);
160}
161
162if (typeof setImmediate !== 'function') {
163 var _setImmediate = setTimeout; // eslint-disable-line no-unused-vars
164}
165
166var ap2 = function ap2(p, y, d, v, a, f, cb) {
167 var j1 = ap(p, y, a, f);
168 if (p !== neptune) {
169 return ap2a(j1, d, a, v, cb);
170 }
171 // handle the double extrema of Neptune
172 if (cb) {
173 ap2a(j1 - 5000, d, a, v, function (_ref) {
174 var _ref2 = _slicedToArray(_ref, 2),
175 j0 = _ref2[0],
176 r0 = _ref2[1];
177
178 ap2a(j1 + 5000, d, a, v, function (_ref3) {
179 var _ref4 = _slicedToArray(_ref3, 2),
180 j2 = _ref4[0],
181 r2 = _ref4[1];
182
183 if (r0 > r2 === a) {
184 cb([j0, r0]);
185 return;
186 }
187 cb([j2, r2]);
188 });
189 });
190 } else {
191 var _ap2a = ap2a(j1 - 5000, d, a, v),
192 _ap2a2 = _slicedToArray(_ap2a, 2),
193 j0 = _ap2a2[0],
194 r0 = _ap2a2[1];
195
196 var _ap2a3 = ap2a(j1 + 5000, d, a, v),
197 _ap2a4 = _slicedToArray(_ap2a3, 2),
198 j2 = _ap2a4[0],
199 r2 = _ap2a4[1];
200
201 if (r0 > r2 === a) {
202 return [j0, r0];
203 }
204 return [j2, r2];
205 }
206};
207
208var ap2a = function ap2a(j1, d, a, v, cb) {
209 var j0 = j1 - d;
210 var j2 = j1 + d;
211 var rr = new Array(3);
212 rr[1] = v.position2000(j1).range;
213 rr[0] = v.position2000(j0).range;
214 rr[2] = v.position2000(j2).range;
215
216 function end() {
217 var l = new _interpolation2.default.Len3(j0, j2, rr);
218
219 var _l$extremum = l.extremum(),
220 _l$extremum2 = _slicedToArray(_l$extremum, 2),
221 jde = _l$extremum2[0],
222 r = _l$extremum2[1];
223
224 return [jde, r];
225 }
226
227 function run() {
228 if (a) {
229 if (rr[1] > rr[0] && rr[1] > rr[2]) {
230 cb && cb(end());
231 return true;
232 }
233 } else {
234 if (rr[1] < rr[0] && rr[1] < rr[2]) {
235 cb && cb(end());
236 return true;
237 }
238 }
239 if (rr[0] < rr[2] === a) {
240 j0 = j1;
241 j1 = j2;
242 j2 += d;
243 rr[0] = rr[1];
244 rr[1] = rr[2];
245 rr[2] = v.position2000(j2).range;
246 } else {
247 j2 = j1;
248 j1 = j0;
249 j0 -= d;
250 rr[2] = rr[1];
251 rr[1] = rr[0];
252 rr[0] = v.position2000(j0).range;
253 }
254 if (cb) {
255 setImmediate(run, 0);
256 }
257 }
258
259 if (cb) {
260 run();
261 } else {
262 for (;;) {
263 if (run()) {
264 return end();
265 }
266 }
267 }
268};
269
270exports.default = {
271 mercury: mercury,
272 venus: venus,
273 earth: earth,
274 mars: mars,
275 jupiter: jupiter,
276 saturn: saturn,
277 uranus: uranus,
278 neptune: neptune,
279 embary: embary,
280 perihelion: perihelion,
281 aphelion: aphelion,
282 perihelion2: perihelion2,
283 aphelion2: aphelion2
284};
\No newline at end of file