'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var apparent = require('./apparent.cjs'); var base = require('./base.cjs'); var coord = require('./coord.cjs'); var kepler = require('./kepler.cjs'); var nutation = require('./nutation.cjs'); var planetposition = require('./planetposition.cjs'); var solarxyz = require('./solarxyz.cjs'); /** * @copyright 2013 Sonia Keys * @copyright 2016 commenthol * @license MIT * @module elliptic */ /** * Position returns observed equatorial coordinates of a planet at a given time. * * Argument p must be a valid V87Planet object for the observed planet. * Argument earth must be a valid V87Planet object for Earth. * * Results are right ascension and declination, α and δ in radians. */ function position (planet, earth, jde) { // (p, earth *pp.V87Planet, jde float64) (α, δ float64) let x = 0; let y = 0; let z = 0; const posEarth = earth.position(jde); const [L0, B0, R0] = [posEarth.lon, posEarth.lat, posEarth.range]; const [sB0, cB0] = base["default"].sincos(B0); const [sL0, cL0] = base["default"].sincos(L0); function pos (τ = 0) { const pos = planet.position(jde - τ); const [L, B, R] = [pos.lon, pos.lat, pos.range]; const [sB, cB] = base["default"].sincos(B); const [sL, cL] = base["default"].sincos(L); x = R * cB * cL - R0 * cB0 * cL0; y = R * cB * sL - R0 * cB0 * sL0; z = R * sB - R0 * sB0; } pos(); const Δ = Math.sqrt(x * x + y * y + z * z); // (33.4) p. 224 const τ = base["default"].lightTime(Δ); // repeating with jde-τ pos(τ); let λ = Math.atan2(y, x); // (33.1) p. 223 let β = Math.atan2(z, Math.hypot(x, y)); // (33.2) p. 223 const [Δλ, Δβ] = apparent["default"].eclipticAberration(λ, β, jde); const fk5 = planetposition["default"].toFK5(λ + Δλ, β + Δβ, jde); λ = fk5.lon; β = fk5.lat; const [Δψ, Δε] = nutation["default"].nutation(jde); λ += Δψ; const ε = nutation["default"].meanObliquity(jde) + Δε; return new coord["default"].Ecliptic(λ, β).toEquatorial(ε) // Meeus gives a formula for elongation but doesn't spell out how to // obtaion term λ0 and doesn't give an example solution. } /** * Elements holds keplerian elements. */ class Elements { /* Axis float64 // Semimajor axis, a, in AU Ecc float64 // Eccentricity, e Inc float64 // Inclination, i, in radians ArgP float64 // Argument of perihelion, ω, in radians Node float64 // Longitude of ascending node, Ω, in radians TimeP float64 // Time of perihelion, T, as jde */ constructor (axis, ecc, inc, argP, node, timeP) { let o = {}; if (typeof axis === 'object') { o = axis; } this.axis = o.axis || axis; this.ecc = o.ecc || ecc; this.inc = o.inc || inc; this.argP = o.argP || argP; this.node = o.node || node; this.timeP = o.timeP || timeP; } /** * Position returns observed equatorial coordinates of a body with Keplerian elements. * * Argument e must be a valid V87Planet object for Earth. * * Results are right ascension and declination α and δ, and elongation ψ, * all in radians. */ position (jde, earth) { // (α, δ, ψ float64) { // (33.6) p. 227 const n = base["default"].K / this.axis / Math.sqrt(this.axis); const sε = base["default"].SOblJ2000; const cε = base["default"].COblJ2000; const [sΩ, cΩ] = base["default"].sincos(this.node); const [si, ci] = base["default"].sincos(this.inc); // (33.7) p. 228 const F = cΩ; const G = sΩ * cε; const H = sΩ * sε; const P = -sΩ * ci; const Q = cΩ * ci * cε - si * sε; const R = cΩ * ci * sε + si * cε; // (33.8) p. 229 const A = Math.atan2(F, P); const B = Math.atan2(G, Q); const C = Math.atan2(H, R); const a = Math.hypot(F, P); const b = Math.hypot(G, Q); const c = Math.hypot(H, R); const f = (jde) => { // (x, y, z float64) { const M = n * (jde - this.timeP); let E; try { E = kepler["default"].kepler2b(this.ecc, M, 15); } catch (e) { E = kepler["default"].kepler3(this.ecc, M); } const ν = kepler["default"].trueAnomaly(E, this.ecc); const r = kepler["default"].radius(E, this.ecc, this.axis); // (33.9) p. 229 const x = r * a * Math.sin(A + this.argP + ν); const y = r * b * Math.sin(B + this.argP + ν); const z = r * c * Math.sin(C + this.argP + ν); return { x, y, z } }; return astrometricJ2000(f, jde, earth) } } /** * AstrometricJ2000 is a utility function for computing astrometric coordinates. * * It is used internally and only exported so that it can be used from * multiple packages. It is not otherwise expected to be used. * * Argument f is a function that returns J2000 equatorial rectangular * coodinates of a body. * * Results are J2000 right ascention, declination, and elongation. */ function astrometricJ2000 (f, jde, earth) { // (f func(float64) (x, y, z float64), jde float64, e *pp.V87Planet) (α, δ, ψ float64) const sol = solarxyz["default"].positionJ2000(earth, jde); const [X, Y, Z] = [sol.x, sol.y, sol.z]; let ξ = 0; let η = 0; let ζ = 0; let Δ = 0; function fn (τ = 0) { // (33.10) p. 229 const { x, y, z } = f(jde - τ); ξ = X + x; η = Y + y; ζ = Z + z; Δ = Math.sqrt(ξ * ξ + η * η + ζ * ζ); } fn(); const τ = base["default"].lightTime(Δ); fn(τ); let α = Math.atan2(η, ξ); if (α < 0) { α += 2 * Math.PI; } const δ = Math.asin(ζ / Δ); const R0 = Math.sqrt(X * X + Y * Y + Z * Z); const ψ = Math.acos((ξ * X + η * Y + ζ * Z) / R0 / Δ); return new base["default"].Coord(α, δ, undefined, ψ) } /** * Velocity returns instantaneous velocity of a body in elliptical orbit around the Sun. * * Argument a is the semimajor axis of the body, r is the instaneous distance * to the Sun, both in AU. * * Result is in Km/sec. */ function velocity (a, r) { // (a, r float64) float64 return 42.1219 * Math.sqrt(1 / r - 0.5 / a) } /** * Velocity returns the velocity of a body at aphelion. * * Argument a is the semimajor axis of the body in AU, e is eccentricity. * * Result is in Km/sec. */ function vAphelion (a, e) { // (a, e float64) float64 return 29.7847 * Math.sqrt((1 - e) / (1 + e) / a) } /** * Velocity returns the velocity of a body at perihelion. * * Argument a is the semimajor axis of the body in AU, e is eccentricity. * * Result is in Km/sec. */ function vPerihelion (a, e) { // (a, e float64) float64 return 29.7847 * Math.sqrt((1 + e) / (1 - e) / a) } /** * Length1 returns Ramanujan's approximation for the length of an elliptical * orbit. * * Argument a is semimajor axis, e is eccentricity. * * Result is in units used for semimajor axis, typically AU. */ function length1 (a, e) { // (a, e float64) float64 const b = a * Math.sqrt(1 - e * e); return Math.PI * (3 * (a + b) - Math.sqrt((a + 3 * b) * (3 * a + b))) } /** * Length2 returns an alternate approximation for the length of an elliptical * orbit. * * Argument a is semimajor axis, e is eccentricity. * * Result is in units used for semimajor axis, typically AU. */ function length2 (a, e) { // (a, e float64) float64 const b = a * Math.sqrt(1 - e * e); const s = a + b; const p = a * b; const A = s * 0.5; const G = Math.sqrt(p); const H = 2 * p / s; return Math.PI * (21 * A - 2 * G - 3 * H) * 0.125 } /** * Length3 returns the length of an elliptical orbit. * * Argument a is semimajor axis, e is eccentricity. * * Result is exact, and in units used for semimajor axis, typically AU. */ /* As Meeus notes, Length4 converges faster. There is no reason to use this function export function length3 (a, e) { // (a, e float64) float64 const sum0 = 1.0 const e2 = e * e const term = e2 * 0.25 const sum1 = 1.0 - term const nf = 1.0 const df = 2.0 while (sum1 !== sum0) { term *= nf nf += 2 df += 2 term *= nf * e2 / (df * df) sum0 = sum1 sum1 -= term } return 2 * Math.PI * a * sum0 } */ /** * Length4 returns the length of an elliptical orbit. * * Argument a is semimajor axis, e is eccentricity. * * Result is exact, and in units used for semimajor axis, typically AU. */ function length4 (a, e) { // (a, e float64) float64 const b = a * Math.sqrt(1 - e * e); const m = (a - b) / (a + b); const m2 = m * m; let sum0 = 1.0; let term = m2 * 0.25; let sum1 = 1.0 + term; let nf = -1.0; let df = 2.0; while (sum1 !== sum0) { nf += 2; df += 2; term *= nf * nf * m2 / (df * df); sum0 = sum1; sum1 += term; } return 2 * Math.PI * a * sum0 / (1 + m) } var elliptic = { position, Elements, astrometricJ2000, velocity, vAphelion, vPerihelion, length1, length2, // length3, length4 }; exports.Elements = Elements; exports.astrometricJ2000 = astrometricJ2000; exports["default"] = elliptic; exports.length1 = length1; exports.length2 = length2; exports.length4 = length4; exports.position = position; exports.vAphelion = vAphelion; exports.vPerihelion = vPerihelion; exports.velocity = velocity;