UNPKG

11.4 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.lightTime = lightTime;
7exports.JulianYearToJDE = JulianYearToJDE;
8exports.JDEToJulianYear = JDEToJulianYear;
9exports.BesselianYearToJDE = BesselianYearToJDE;
10exports.JDEToBesselianYear = JDEToBesselianYear;
11exports.J2000Century = J2000Century;
12exports.illuminated = illuminated;
13exports.Coord = Coord;
14exports.limb = limb;
15exports.pmod = pmod;
16exports.horner = horner;
17exports.floorDiv = floorDiv;
18exports.cmp = cmp;
19exports.sincos = sincos;
20exports.toRad = toRad;
21exports.toDeg = toDeg;
22exports.modf = modf;
23exports.round = round;
24exports.errorCode = errorCode;
25/**
26 * @copyright 2013 Sonia Keys
27 * @copyright 2016 commenthol
28 * @license MIT
29 * @module base
30 */
31/**
32 * Base: Functions and other definitions useful with multiple packages.
33 *
34 * Base contains various definitions and support functions useful in multiple
35 * chapters.
36 *
37 * Bessellian and Julian Year
38 *
39 * Chapter 21, Precession actually contains these definitions. They are moved
40 * here because of their general utility.
41 *
42 * Chapter 22, Nutation contains the function for Julian centuries since J2000.
43 *
44 * Phase angle functions
45 *
46 * Two functions, Illuminated and Limb, concern the illumnated phase of a body
47 * and are given in two chapters, 41 an 48. They are collected here because
48 * the identical functions apply in both chapters.
49 *
50 * General purpose math functions
51 *
52 * SmallAngle is recommended in chapter 17, p. 109.
53 *
54 * PMod addresses the issue on p. 7, chapter 1, in the section "Trigonometric
55 * functions of large angles", but the function is not written to be specific
56 * to angles and so has more general utility.
57 *
58 * Horner is described on p. 10, chapter 1.
59 *
60 * FloorDiv and FloorDiv64 are optimizations for the INT function described
61 * on p. 60, chapter 7.
62*/
63
64// ---- constants ----
65
66/** K is the Gaussian gravitational constant. */
67var K = exports.K = 0.01720209895;
68// K from ch 33, p. 228, for example
69
70/** AU is one astronomical unit in km. */
71var AU = exports.AU = 149597870;
72// from Appendix I, p, 407.
73
74/** SOblJ2000 sine obliquity at J2000. */
75var SOblJ2000 = exports.SOblJ2000 = 0.397777156;
76/** COblJ2000 cosine obliquity at J2000. */
77var COblJ2000 = exports.COblJ2000 = 0.917482062;
78// SOblJ2000, COblJ2000 from ch 33, p. 228, for example
79
80/**
81 * lightTime returns time for light to travel a given distance.
82 * `dist` is distance in to earth in AU. √(x² + y² + z²)
83 * Result in seconds of time.
84 * @param {Number} dist - distance in to earth in AU
85 * @returns {Number} time for light to travel a given distance in seconds
86 */
87function lightTime(dist) {
88 // Formula given as (33.3) p. 224.
89 return 0.0057755183 * dist;
90}
91
92// ---- julian ----
93
94/**
95 * Julian and Besselian years described in chapter 21, Precession.
96 * T, Julian centuries since J2000 described in chapter 22, Nutation.
97 */
98
99/** JMod is the Julian date of the modified Julian date epoch. */
100var JMod = exports.JMod = 2400000.5;
101
102/** J2000 is the Julian date corresponding to January 1.5, year 2000. */
103var J2000 = exports.J2000 = 2451545.0;
104
105// Julian days of common epochs.
106// B1900, B1950 from p. 133
107/** Julian days of Julian epoch 1900 */
108var J1900 = exports.J1900 = 2415020.0;
109/** Julian days of Besselian epoch 1900 */
110var B1900 = exports.B1900 = 2415020.3135;
111/** Julian days of Besselian epoch 1950 */
112var B1950 = exports.B1950 = 2433282.4235;
113
114// JulianYear and other common periods
115/** JulianYear in days */
116var JulianYear = exports.JulianYear = 365.25; // days
117/** JulianCentury in days */
118var JulianCentury = exports.JulianCentury = 36525; // days
119/** BesselianYear in days; equals mean tropical year */
120var BesselianYear = exports.BesselianYear = 365.2421988; // days
121/** Mean sidereal year */
122var meanSiderealYear = exports.meanSiderealYear = 365.25636; // days
123
124/**
125 * JulianYearToJDE returns the Julian ephemeris day for a Julian year.
126 * @param {Number} jy - Julian year
127 * @returns {Number} jde - Julian ephemeris day
128 */
129function JulianYearToJDE(jy) {
130 return J2000 + JulianYear * (jy - 2000);
131}
132
133/**
134 * JDEToJulianYear returns a Julian year for a Julian ephemeris day.
135 * @param {Number} jde - Julian ephemeris day
136 * @returns {Number} jy - Julian year
137 */
138function JDEToJulianYear(jde) {
139 return 2000 + (jde - J2000) / JulianYear;
140}
141
142/**
143 * BesselianYearToJDE returns the Julian ephemeris day for a Besselian year.
144 * @param {Number} by - Besselian year
145 * @returns {Number} jde - Julian ephemeris day
146 */
147function BesselianYearToJDE(by) {
148 return B1900 + BesselianYear * (by - 1900);
149}
150
151/**
152 * JDEToBesselianYear returns the Besselian year for a Julian ephemeris day.
153 * @param {Number} jde - Julian ephemeris day
154 * @returns {Number} by - Besselian year
155 */
156function JDEToBesselianYear(jde) {
157 return 1900 + (jde - B1900) / BesselianYear;
158}
159
160/**
161 * J2000Century returns the number of Julian centuries since J2000.
162 *
163 * The quantity appears as T in a number of time series.
164 * @param {Number} jde - Julian ephemeris day
165 * @returns {Number} number of Julian centuries since J2000
166 */
167function J2000Century(jde) {
168 // The formula is given in a number of places in the book, for example
169 // (12.1) p. 87.
170 // (22.1) p. 143.
171 // (25.1) p. 163.
172 return (jde - J2000) / JulianCentury;
173}
174
175// ---- phase ----
176
177/**
178 * illuminated returns the illuminated fraction of a body's disk.
179 *
180 * The illuminated body can be the Moon or a planet.
181 *
182 * @param {Number} i - phase angle in radians.
183 * @returns {Number} illuminated fraction of a body's disk.
184 */
185function illuminated(i) {
186 // (41.1) p. 283, also (48.1) p. 345.
187 return (1 + Math.cos(i)) * 0.5;
188}
189
190/**
191 * celestial coordinates in right ascension and declination
192 * or ecliptic coordinates in longitude and latitude
193 *
194 * @param {number} ra - right ascension (or longitude)
195 * @param {number} dec - declination (or latitude)
196 * @param {number} [range] - distance
197 * @param {number} [elongation] - elongation
198 */
199function Coord(ra /* lon */, dec /* lat */, range, elongation) {
200 this._ra = ra || 0;
201 this._dec = dec || 0;
202 this.range = range;
203 this.elongation = elongation;
204
205 Object.defineProperties(this, {
206 ra: {
207 get: function get() {
208 return this._ra;
209 },
210 set: function set(ra) {
211 this._ra = ra;
212 }
213 },
214 dec: {
215 get: function get() {
216 return this._dec;
217 },
218 set: function set(dec) {
219 this._dec = dec;
220 }
221 },
222 lon: {
223 get: function get() {
224 return this._ra;
225 },
226 set: function set(ra) {
227 this._ra = ra;
228 }
229 },
230 lat: {
231 get: function get() {
232 return this._dec;
233 },
234 set: function set(dec) {
235 this._dec = dec;
236 }
237 }
238 });
239}
240
241/**
242 * Limb returns the position angle of the midpoint of an illuminated limb.
243 *
244 * The illuminated body can be the Moon or a planet.
245 *
246 * @param {base.Coord} equ - equatorial coordinates of the body `{ra, dec}` (in radians)
247 * @param {base.Coord} appSun - apparent coordinates of the Sun `{ra, dec}` (In radians).
248 * @returns {Number} position angle of the midpoint (in radians).
249 */
250function limb(equ, appSun) {
251 var α = equ.ra;
252 var δ = equ.dec;
253 var α0 = appSun.ra;
254 var δ0 = appSun.dec;
255 // Mentioned in ch 41, p. 283. Formula (48.5) p. 346
256 var sδ = Math.sin(δ);
257 var cδ = Math.cos(δ);
258 var0 = Math.sin(δ0);
259 var0 = Math.cos(δ0);
260 var0α = Math.sin(α0 - α);
261 var0α = Math.cos(α0 - α);
262 var χ = Math.atan2(cδ0 * sα0α, sδ0 * cδ - cδ0 * sδ * cα0α);
263 if (χ < 0) {
264 χ += 2 * Math.PI;
265 }
266 return χ;
267}
268
269// ---- math ----
270
271// In chapter 17, p. 109, Meeus recommends 10′.
272/**
273 * SmallAngle is threshold used by various routines for switching between
274 * trigonometric functions and Pythagorean approximations.
275 */
276var SmallAngle = exports.SmallAngle = 10 * Math.PI / 180 / 60; // about .003 radians
277/** cosine of SmallAngle */
278var CosSmallAngle = exports.CosSmallAngle = Math.cos(SmallAngle); // about .999996
279
280/**
281 * pmod returns a positive floating-point x mod y.
282 *
283 * For a positive argument y, it returns a value in the range [0,y).
284 *
285 * @param {Number} x
286 * @param {Number} y
287 * @returns {Number} x % y - The result may not be useful if y is negative.
288 */
289function pmod(x, y) {
290 var r = x % y;
291 if (r < 0) {
292 r += y;
293 }
294 return r;
295}
296
297/**
298 * horner evaluates a polynomal with coefficients c at x. The constant
299 * term is c[0].
300 * @param {Number} x
301 * @param {Number|Number[]} c - coefficients
302 * @returns {Number}
303 */
304function horner(x) {
305 for (var _len = arguments.length, c = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
306 c[_key - 1] = arguments[_key];
307 }
308
309 if (Array.isArray(c[0])) {
310 c = c[0];
311 }
312 var i = c.length - 1;
313 var y = c[i];
314 while (i > 0) {
315 i--;
316 y = y * x + c[i];
317 }
318 return y;
319}
320
321/**
322 * FloorDiv returns the integer floor of the fractional value (x / y).
323 * @param {Number} x
324 * @param {Number} y
325 * @returns {Number} (int)
326 */
327function floorDiv(x, y) {
328 var q = x / y;
329 return Math.floor(q);
330}
331
332/**
333 * Cmp compares two float64s and returns -1, 0, or 1 if a is <, ==, or > b,
334 * respectively.
335 * .
336 * @param {Number} a
337 * @param {Number} b
338 * @returns {Number} comparison result
339 */
340function cmp(a, b) {
341 if (a < b) return -1;
342 if (a > b) return 1;
343 return 0;
344}
345
346/**
347 * shorthand function for Math.sin, Math.cos
348 * @param {Number} ε
349 * @returns {Number[]} [sin(ε), cos(ε)]
350 */
351function sincos(ε) {
352 return [Math.sin(ε), Math.cos(ε)];
353}
354
355/**
356 * Convert degrees to radians
357 * @param {Number} deg - Angle in degrees
358 * @return {Number} Angle in radians
359 */
360function toRad(deg) {
361 return Math.PI / 180.0 * deg;
362}
363
364/**
365 * Convert radians to degrees
366 * @param {Number} rad - Angle in radians
367 * @return {Number} Angle in degrees
368 */
369function toDeg(rad) {
370 return 180.0 / Math.PI * rad;
371}
372
373/**
374 * separate fix `i` from fraction `f`
375 * @param {Number} float
376 * @returns {Array} [i, f]
377 * {Number} i - (int) fix value
378 * {Number} f - (float) fractional portion; always > 1
379 */
380function modf(float) {
381 var i = Math.trunc(float);
382 var f = Math.abs(float - i);
383 return [i, f];
384}
385
386/**
387 * Rounds `float` value by precision
388 * @param {Number} float - value to round
389 * @param {Number} precision - (int) number of post decimal positions
390 * @return {Number} rounded `float`
391 */
392function round(float, precision) {
393 precision = precision == undefined ? 14 : precision; // eslint-disable-line eqeqeq
394 return parseFloat(float.toFixed(precision), 10);
395}
396
397function errorCode(msg, code) {
398 var err = new Error(msg);
399 err.code = code;
400 return err;
401}
402
403exports.default = {
404 K: K,
405 AU: AU,
406 SOblJ2000: SOblJ2000,
407 COblJ2000: COblJ2000,
408 lightTime: lightTime,
409 JMod: JMod,
410 J2000: J2000,
411 J1900: J1900,
412 B1900: B1900,
413 B1950: B1950,
414 JulianYear: JulianYear,
415 JulianCentury: JulianCentury,
416 BesselianYear: BesselianYear,
417 meanSiderealYear: meanSiderealYear,
418 JulianYearToJDE: JulianYearToJDE,
419 JDEToJulianYear: JDEToJulianYear,
420 BesselianYearToJDE: BesselianYearToJDE,
421 JDEToBesselianYear: JDEToBesselianYear,
422 J2000Century: J2000Century,
423 illuminated: illuminated,
424 Coord: Coord,
425 limb: limb,
426 SmallAngle: SmallAngle,
427 CosSmallAngle: CosSmallAngle,
428 pmod: pmod,
429 horner: horner,
430 floorDiv: floorDiv,
431 cmp: cmp,
432 sincos: sincos,
433 toRad: toRad,
434 toDeg: toDeg,
435 modf: modf,
436 round: round,
437 errorCode: errorCode
438};
\No newline at end of file