astronomia
Version:
An astronomical library
342 lines (300 loc) • 8.32 kB
JavaScript
/**
* @copyright 2013 Sonia Keys
* @copyright 2016 commenthol
* @license MIT
* @module moonposition
*/
/**
* Moonposition: Chapter 47, Position of the Moon.
*/
import base, { Coord } from './base.js' // eslint-disable-line no-unused-vars
const { asin, sin } = Math
const D2R = Math.PI / 180
const EARTH_RADIUS = 6378.137 // km
/**
* parallax returns equatorial horizontal parallax of the Moon.
*
* @param {Number} distance - distance between centers of the Earth and Moon, in km.
* @returns {Number} Result in radians.
*/
export function parallax (distance) {
// p. 337
return asin(EARTH_RADIUS / distance)
}
function dmf (T) {
const d = base.horner(T, 297.8501921 * D2R, 445267.1114034 * D2R, -0.0018819 * D2R, D2R / 545868, -D2R / 113065000)
const m = base.horner(T, 357.5291092 * D2R, 35999.0502909 * D2R, -0.0001536 * D2R, D2R / 24490000)
const m_ = base.horner(T, 134.9633964 * D2R, 477198.8675055 * D2R,
0.0087414 * D2R, D2R / 69699, -D2R / 14712000)
const f = base.horner(T, 93.272095 * D2R, 483202.0175233 * D2R, -0.0036539 * D2R, -D2R / 3526000, D2R / 863310000)
return [d, m, m_, f]
}
/**
* position returns geocentric location of the Moon.
*
* Results are referenced to mean equinox of date and do not include
* the effect of nutation.
*
* @param {number} jde - Julian ephemeris day
* @returns {Coord}
* {number} lon - Geocentric longitude λ, in radians.
* {number} lat - Geocentric latitude β, in radians.
* {number} range - Distance Δ between centers of the Earth and Moon, in km.
*/
export function position (jde) {
const T = base.J2000Century(jde)
const l_ = base.horner(T, 218.3164477 * D2R, 481267.88123421 * D2R, -0.0015786 * D2R, D2R / 538841, -D2R / 65194000)
const [d, m, m_, f] = dmf(T)
const a1 = 119.75 * D2R + 131.849 * D2R * T
const a2 = 53.09 * D2R + 479264.29 * D2R * T
const a3 = 313.45 * D2R + 481266.484 * D2R * T
const e = base.horner(T, 1, -0.002516, -0.0000074)
const e2 = e * e
let Σl = 3958 * sin(a1) + 1962 * sin(l_ - f) + 318 * sin(a2)
let Σr = 0.0
let Σb = -2235 * sin(l_) + 382 * sin(a3) + 175 * sin(a1 - f) +
175 * sin(a1 + f) + 127 * sin(l_ - m_) - 115 * sin(l_ + m_)
ta.forEach((r) => {
const [sina, cosa] = base.sincos(d * r.d + m * r.m + m_ * r.m_ + f * r.f)
switch (r.m) {
case 0:
Σl += r.Σl * sina
Σr += r.Σr * cosa
break
case -1:
case 1:
Σl += r.Σl * sina * e
Σr += r.Σr * cosa * e
break
case -2:
case 2:
Σl += r.Σl * sina * e2
Σr += r.Σr * cosa * e2
break
}
})
tb.forEach((r) => {
const sb = sin(d * r.d + m * r.m + m_ * r.m_ + f * r.f)
switch (r.m) {
case 0:
Σb += r.Σb * sb
break
case -1:
case 1:
Σb += r.Σb * sb * e
break
case -2:
case 2:
Σb += r.Σb * sb * e2
break
}
})
const lon = base.pmod(l_, 2 * Math.PI) + Σl * 1e-6 * D2R
const lat = Σb * 1e-6 * D2R
const range = 385000.56 + Σr * 1e-3
return new base.Coord(lon, lat, range)
}
const ta = (function () {
const ta = [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[]
]
return ta.map((row) => {
const o = {}
const vals = ['d', 'm', 'm_', 'f', 'Σl', 'Σr']
vals.forEach((D2R, i) => {
o[D2R] = row[i]
})
return o
})
})()
const tb = (function () {
const tb = [
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[]
]
return tb.map((row) => {
const o = {}
const vals = ['d', 'm', 'm_', 'f', 'Σb']
vals.forEach((D2R, i) => {
o[D2R] = row[i]
})
return o
})
})()
/**
* Node returns longitude of the mean ascending node of the lunar orbit.
*
* @param {number} jde - Julian ephemeris day
* @returns result in radians.
*/
export function node (jde) {
return base.pmod(
base.horner(
base.J2000Century(jde),
125.0445479 * D2R,
-1934.1362891 * D2R,
0.0020754 * D2R,
D2R / 467441,
-D2R / 60616000
), 2 * Math.PI
)
}
/**
* perigee returns longitude of perigee of the lunar orbit.
*
* @param {number} jde - Julian ephemeris day
* @returns result in radians.
*/
export function perigee (jde) {
return base.pmod(
base.horner(
base.J2000Century(jde),
83.3532465 * D2R,
4069.0137287 * D2R,
-0.01032 * D2R,
-D2R / 80053,
D2R / 18999000
), 2 * Math.PI
)
}
/**
* trueNode returns longitude of the true ascending node.
*
* That is, the node of the instantaneous lunar orbit.
*
* @param {number} jde - Julian ephemeris day
* @returns result in radians.
*/
export function trueNode (jde) {
const [d, m, m_, f] = dmf(base.J2000Century(jde))
return node(jde) +
-1.4979 * D2R * sin(2 * (d - f)) +
-0.15 * D2R * sin(m) +
-0.1226 * D2R * sin(2 * d) +
0.1176 * D2R * sin(2 * f) +
-0.0801 * D2R * sin(2 * (m_ - f))
}
export default {
parallax,
position,
node,
perigee,
trueNode
}