UNPKG

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