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. */
|
43 | export var K = 0.01720209895;
|
44 | // K from ch 33, p. 228, for example
|
45 |
|
46 | /** AU is one astronomical unit in km. */
|
47 | export var AU = 149597870;
|
48 | // from Appendix I, p, 407.
|
49 |
|
50 | /** SOblJ2000 sine obliquity at J2000. */
|
51 | export var SOblJ2000 = 0.397777156;
|
52 | /** COblJ2000 cosine obliquity at J2000. */
|
53 | export 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 | */
|
63 | export 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. */
|
76 | export var JMod = 2400000.5;
|
77 |
|
78 | /** J2000 is the Julian date corresponding to January 1.5, year 2000. */
|
79 | export var J2000 = 2451545.0;
|
80 |
|
81 | // Julian days of common epochs.
|
82 | // B1900, B1950 from p. 133
|
83 | /** Julian days of Julian epoch 1900 */
|
84 | export var J1900 = 2415020.0;
|
85 | /** Julian days of Besselian epoch 1900 */
|
86 | export var B1900 = 2415020.3135;
|
87 | /** Julian days of Besselian epoch 1950 */
|
88 | export var B1950 = 2433282.4235;
|
89 |
|
90 | // JulianYear and other common periods
|
91 | /** JulianYear in days */
|
92 | export var JulianYear = 365.25; // days
|
93 | /** JulianCentury in days */
|
94 | export var JulianCentury = 36525; // days
|
95 | /** BesselianYear in days; equals mean tropical year */
|
96 | export var BesselianYear = 365.2421988; // days
|
97 | /** Mean sidereal year */
|
98 | export 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 | */
|
105 | export 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 | */
|
114 | export 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 | */
|
123 | export 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 | */
|
132 | export 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 | */
|
143 | export 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 | */
|
161 | export 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 | */
|
175 | export 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 | */
|
226 | export 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 | var sδ0 = Math.sin(δ0);
|
235 | var cδ0 = Math.cos(δ0);
|
236 | var sα0α = Math.sin(α0 - α);
|
237 | var cα0α = 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 | */
|
252 | export var SmallAngle = 10 * Math.PI / 180 / 60; // about .003 radians
|
253 | /** cosine of SmallAngle */
|
254 | export 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 | */
|
265 | export 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 | */
|
280 | export 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 | */
|
303 | export 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 | */
|
316 | export 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 | */
|
327 | export 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 | */
|
336 | export 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 | */
|
345 | export 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 | */
|
356 | export 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 | */
|
368 | export function round(float, precision) {
|
369 | precision = precision == undefined ? 14 : precision; // eslint-disable-line eqeqeq
|
370 | return parseFloat(float.toFixed(precision), 10);
|
371 | }
|
372 |
|
373 | export function errorCode(msg, code) {
|
374 | var err = new Error(msg);
|
375 | err.code = code;
|
376 | return err;
|
377 | }
|
378 |
|
379 | export 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 |