astronomia
Version:
An astronomical library
470 lines (425 loc) • 11.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/**
* @copyright 2013 Sonia Keys
* @copyright 2016 commenthol
* @license MIT
* @module base
*/
/**
* Base: Functions and other definitions useful with multiple packages.
*
* Base contains various definitions and support functions useful in multiple
* chapters.
*
* Bessellian and Julian Year
*
* Chapter 21, Precession actually contains these definitions. They are moved
* here because of their general utility.
*
* Chapter 22, Nutation contains the function for Julian centuries since J2000.
*
* Phase angle functions
*
* Two functions, Illuminated and Limb, concern the illumnated phase of a body
* and are given in two chapters, 41 an 48. They are collected here because
* the identical functions apply in both chapters.
*
* General purpose math functions
*
* SmallAngle is recommended in chapter 17, p. 109.
*
* PMod addresses the issue on p. 7, chapter 1, in the section "Trigonometric
* functions of large angles", but the function is not written to be specific
* to angles and so has more general utility.
*
* Horner is described on p. 10, chapter 1.
*
* FloorDiv and FloorDiv64 are optimizations for the INT function described
* on p. 60, chapter 7.
*/
// ---- constants ----
/** K is the Gaussian gravitational constant. */
const K = 0.01720209895;
// K from ch 33, p. 228, for example
/** AU is one astronomical unit in km. */
const AU = 149597870;
// from Appendix I, p, 407.
/** SOblJ2000 sine obliquity at J2000. */
const SOblJ2000 = 0.397777156;
/** COblJ2000 cosine obliquity at J2000. */
const COblJ2000 = 0.917482062;
// SOblJ2000, COblJ2000 from ch 33, p. 228, for example
/**
* lightTime returns time for light to travel a given distance.
* `dist` is distance in to earth in AU. √(x² + y² + z²)
* Result in seconds of time.
* @param {Number} dist - distance in to earth in AU
* @returns {Number} time for light to travel a given distance in seconds
*/
function lightTime (dist) {
// Formula given as (33.3) p. 224.
return 0.0057755183 * dist
}
// ---- julian ----
/**
* Julian and Besselian years described in chapter 21, Precession.
* T, Julian centuries since J2000 described in chapter 22, Nutation.
*/
/** JMod is the Julian date of the modified Julian date epoch. */
const JMod = 2400000.5;
/** J2000 is the Julian date corresponding to January 1.5, year 2000. */
const J2000 = 2451545.0;
// Julian days of common epochs.
// B1900, B1950 from p. 133
/** Julian days of Julian epoch 1900 */
const J1900 = 2415020.0;
/** Julian days of Besselian epoch 1900 */
const B1900 = 2415020.3135;
/** Julian days of Besselian epoch 1950 */
const B1950 = 2433282.4235;
// JulianYear and other common periods
/** JulianYear in days */
const JulianYear = 365.25; // days
/** JulianCentury in days */
const JulianCentury = 36525; // days
/** BesselianYear in days; equals mean tropical year */
const BesselianYear = 365.2421988; // days
/** Mean sidereal year */
const meanSiderealYear = 365.25636; // days
/**
* JulianYearToJDE returns the Julian ephemeris day for a Julian year.
* @param {Number} jy - Julian year
* @returns {Number} jde - Julian ephemeris day
*/
function JulianYearToJDE (jy) {
return J2000 + JulianYear * (jy - 2000)
}
/**
* JDEToJulianYear returns a Julian year for a Julian ephemeris day.
* @param {Number} jde - Julian ephemeris day
* @returns {Number} jy - Julian year
*/
function JDEToJulianYear (jde) {
return 2000 + (jde - J2000) / JulianYear
}
/**
* BesselianYearToJDE returns the Julian ephemeris day for a Besselian year.
* @param {Number} by - Besselian year
* @returns {Number} jde - Julian ephemeris day
*/
function BesselianYearToJDE (by) {
return B1900 + BesselianYear * (by - 1900)
}
/**
* JDEToBesselianYear returns the Besselian year for a Julian ephemeris day.
* @param {Number} jde - Julian ephemeris day
* @returns {Number} by - Besselian year
*/
function JDEToBesselianYear (jde) {
return 1900 + (jde - B1900) / BesselianYear
}
/**
* J2000Century returns the number of Julian centuries since J2000.
*
* The quantity appears as T in a number of time series.
* @param {Number} jde - Julian ephemeris day
* @returns {Number} number of Julian centuries since J2000
*/
function J2000Century (jde) {
// The formula is given in a number of places in the book, for example
// (12.1) p. 87.
// (22.1) p. 143.
// (25.1) p. 163.
return (jde - J2000) / JulianCentury
}
// ---- phase ----
/**
* illuminated returns the illuminated fraction of a body's disk.
*
* The illuminated body can be the Moon or a planet.
*
* @param {Number} i - phase angle in radians.
* @returns {Number} illuminated fraction of a body's disk.
*/
function illuminated (i) {
// (41.1) p. 283, also (48.1) p. 345.
return (1 + Math.cos(i)) * 0.5
}
/**
* celestial coordinates in right ascension and declination
* or ecliptic coordinates in longitude and latitude
*/
class Coord {
/**
* celestial coordinates in right ascension and declination
* or ecliptic coordinates in longitude and latitude
*
* @param {number} ra - right ascension (or longitude)
* @param {number} dec - declination (or latitude)
* @param {number} [range] - distance
* @param {number} [elongation] - elongation
*/
constructor (ra, dec, range, elongation) {
this._ra = ra || 0;
this._dec = dec || 0;
this.range = range;
this.elongation = elongation;
}
/**
* right ascension
* @return {number}
*/
get ra () {
return this._ra
}
set ra (ra) {
this._ra = ra;
}
/**
* declination
* @return {number}
*/
get dec () {
return this._dec
}
set dec (dec) {
this._dec = dec;
}
/**
* right ascension (or longitude)
* @return {number}
*/
get lon () {
return this._ra
}
set lon (ra) {
this._ra = ra;
}
/**
* declination (or latitude)
* @return {number}
*/
get lat () {
return this._dec
}
set lat (dec) {
this._dec = dec;
}
}
/**
* Limb returns the position angle of the midpoint of an illuminated limb.
*
* The illuminated body can be the Moon or a planet.
*
* @param {Coord} equ - equatorial coordinates of the body `{ra, dec}` (in radians)
* @param {Coord} appSun - apparent coordinates of the Sun `{ra, dec}` (In radians).
* @returns {Number} position angle of the midpoint (in radians).
*/
function limb (equ, appSun) {
const α = equ.ra;
const δ = equ.dec;
const α0 = appSun.ra;
const δ0 = appSun.dec;
// Mentioned in ch 41, p. 283. Formula (48.5) p. 346
const sδ = Math.sin(δ);
const cδ = Math.cos(δ);
const sδ0 = Math.sin(δ0);
const cδ0 = Math.cos(δ0);
const sα0α = Math.sin(α0 - α);
const cα0α = Math.cos(α0 - α);
let χ = Math.atan2(cδ0 * sα0α, (sδ0 * cδ - cδ0 * sδ * cα0α));
if (χ < 0) {
χ += 2 * Math.PI;
}
return χ
}
// ---- math ----
// In chapter 17, p. 109, Meeus recommends 10′.
/**
* SmallAngle is threshold used by various routines for switching between
* trigonometric functions and Pythagorean approximations.
*/
const SmallAngle = 10 * Math.PI / 180 / 60; // about .003 radians
/** cosine of SmallAngle */
const CosSmallAngle = Math.cos(SmallAngle); // about .999996
/**
* pmod returns a positive floating-point x mod y.
*
* For a positive argument y, it returns a value in the range [0,y).
*
* @param {Number} x
* @param {Number} y
* @returns {Number} x % y - The result may not be useful if y is negative.
*/
function pmod (x, y) {
let r = x % y;
if (r < 0) {
r += y;
}
return r
}
/**
* horner evaluates a polynomal with coefficients c at x. The constant
* term is c[0].
* @param {Number} x
* @param {Number[]} c - coefficients; c[0] may be of type Number[]
* @returns {Number}
*/
function horner (x, ...c) {
if (Array.isArray(c[0])) {
c = c[0];
}
let i = c.length - 1;
let y = c[i];
while (i > 0) {
i--;
y = y * x + c[i];
}
return y
}
/**
* FloorDiv returns the integer floor of the fractional value (x / y).
* @param {Number} x
* @param {Number} y
* @returns {Number} (int)
*/
function floorDiv (x, y) {
const q = x / y;
return Math.floor(q)
}
/**
* Cmp compares two float64s and returns -1, 0, or 1 if a is <, ==, or > b,
* respectively.
* .
* @param {Number} a
* @param {Number} b
* @returns {Number} comparison result
*/
function cmp (a, b) {
if (a < b) return -1
if (a > b) return 1
return 0
}
/**
* shorthand function for Math.sin, Math.cos
* @param {Number} ε
* @returns {Number[]} [sin(ε), cos(ε)]
*/
function sincos (ε) {
return [Math.sin(ε), Math.cos(ε)]
}
/**
* Convert degrees to radians
* @param {Number} deg - Angle in degrees
* @return {Number} Angle in radians
*/
function toRad (deg) {
return (Math.PI / 180.0) * deg
}
/**
* Convert radians to degrees
* @param {Number} rad - Angle in radians
* @return {Number} Angle in degrees
*/
function toDeg (rad) {
return (180.0 / Math.PI) * rad
}
/**
* separate fix `i` from fraction `f`
* @param {Number} float
* @returns {Array} [i, f]
* {Number} i - (int) fix value
* {Number} f - (float) fractional portion; always > 1
*/
function modf (float) {
const i = Math.trunc(float);
const f = Math.abs(float - i);
return [i, f]
}
/**
* Rounds `float` value by precision
* @param {Number} float - value to round
* @param {Number} [precision] - (int) number of post decimal positions
* @return {Number} rounded `float`
*/
function round (float, precision = 14) {
return parseFloat(float.toFixed(precision))
}
function errorCode (msg, code) {
const err = new Error(msg);
// @ts-ignore
err.code = code;
return err
}
var base = {
K,
AU,
SOblJ2000,
COblJ2000,
lightTime,
JMod,
J2000,
J1900,
B1900,
B1950,
JulianYear,
JulianCentury,
BesselianYear,
meanSiderealYear,
JulianYearToJDE,
JDEToJulianYear,
BesselianYearToJDE,
JDEToBesselianYear,
J2000Century,
illuminated,
Coord,
limb,
SmallAngle,
CosSmallAngle,
pmod,
horner,
floorDiv,
cmp,
sincos,
toRad,
toDeg,
modf,
round,
errorCode
};
exports.AU = AU;
exports.B1900 = B1900;
exports.B1950 = B1950;
exports.BesselianYear = BesselianYear;
exports.BesselianYearToJDE = BesselianYearToJDE;
exports.COblJ2000 = COblJ2000;
exports.Coord = Coord;
exports.CosSmallAngle = CosSmallAngle;
exports.J1900 = J1900;
exports.J2000 = J2000;
exports.J2000Century = J2000Century;
exports.JDEToBesselianYear = JDEToBesselianYear;
exports.JDEToJulianYear = JDEToJulianYear;
exports.JMod = JMod;
exports.JulianCentury = JulianCentury;
exports.JulianYear = JulianYear;
exports.JulianYearToJDE = JulianYearToJDE;
exports.K = K;
exports.SOblJ2000 = SOblJ2000;
exports.SmallAngle = SmallAngle;
exports.cmp = cmp;
exports["default"] = base;
exports.errorCode = errorCode;
exports.floorDiv = floorDiv;
exports.horner = horner;
exports.illuminated = illuminated;
exports.lightTime = lightTime;
exports.limb = limb;
exports.meanSiderealYear = meanSiderealYear;
exports.modf = modf;
exports.pmod = pmod;
exports.round = round;
exports.sincos = sincos;
exports.toDeg = toDeg;
exports.toRad = toRad;