ephemeris
Version:
JavaScript implementation of Moshier's ephemeris calculations for sun, planets, comets, asteroids and stars.
165 lines (136 loc) • 5.61 kB
JavaScript
var aberration = require('./aberration')
var altaz = require('./altaz')
var constant = require('./constant')
var constellation = require('./constellation')
var deflection = require('./deflection')
var epsilon = require('./epsilon')
var kepler = require('./kepler')
var light = require('./light')
var lonlat = require('./lonlat')
var nutation = require('./nutation')
var precess = require('./precess')
var util = require('./util')
var moshier = {
body: require('./body')
}
var planet = {}
planet.calc = function (body) {
this.prepare(body)
/* calculate heliocentric position of the object */
kepler.calc(moshier.body.earth.position.date, body)
/* apply correction factors and print apparent place */
this.reduce(body, body.position.rect, moshier.body.earth.position.rect)
}
/**
* The following program reduces the heliocentric equatorial
* rectangular coordinates of the earth and object that
* were computed by kepler() and produces apparent geocentric
* right ascension and declination.
*/
planet.reduce = function (body, q, e) {
/* Save the geometric coordinates at TDT */
var temp = {
longitude: q.longitude,
latitude: q.latitude,
distance: q.distance
}
/* Display ecliptic longitude and latitude, precessed to equinox
of date. */
var polar = body.equinoxEclipticLonLat = lonlat.calc(q, moshier.body.earth.position.date, true)
/* Adjust for light time (planetary aberration) */
light.calc(body, q, e)
/* Find Euclidean vectors between earth, object, and the sun */
var p = {
longitude: q.longitude - e.longitude,
latitude: q.latitude - e.latitude,
distance: q.distance - e.distance
}
util.angles(p, q, e)
var b = temp.longitude - e.longitude
var a = b * b
b = temp.latitude - e.latitude
a += b * b
b = temp.distance - e.distance
a += b * b
body.position.trueGeocentricDistance = Math.sqrt(a)
/* was EO */
body.position.equatorialDiameter = 2 * body.semiDiameter / constant.EO
/* Calculate visual magnitude.
* "Visual" refers to the spectrum of visible light.
* Phase = 0.5(1+pq) = geometric fraction of disc illuminated.
* where pq = cos( sun-object-earth angle )
* The magnitude is
* V(1,0) + 2.5 log10( SE^2 SO^2 / Phase)
* where V(1,0) = elemnt->mag is the magnitude at 1au from
* both earth and sun and 100% illumination.
*/
var phase = 0.5 * (1 + constant.pq)
/* Fudge the phase for light leakage in magnitude estimation.
* Note this phase term estimate does not reflect reality well.
* Calculated magnitudes of Mercury and Venus are inaccurate.
*/
var x = 0.5 * (1.01 + 0.99 * constant.pq)
var magnitude = body.magnitude + 2.1715 * Math.log(constant.EO * constant.SO) - 1.085 * Math.log(x)
body.position.approxVisual = {
magnitude: magnitude,
phase: phase
}
/* Find unit vector from earth in direction of object */
p.longitude /= constant.EO
p.latitude /= constant.EO
p.distance /= constant.EO
temp = {
longitude: p.longitude,
latitude: p.latitude,
distance: p.distance
}
/* Report astrometric position */
body.position.astrometricJ2000 = util.showrd(p, polar)
/* Also in 1950 coordinates */
precess.calc(temp, {julian: constant.b1950}, -1)
body.position.astrometricB1950 = util.showrd(temp, polar)
/* Correct position for light deflection */
body.position.deflection = deflection.calc(p, q, e) // relativity
/* Correct for annual aberration */
body.position.aberration = aberration.calc(p)
/* Precession of the equinox and ecliptic
* from J2000.0 to ephemeris date
*/
precess.calc(p, moshier.body.earth.position.date, -1)
/* Adjust for nutation at current ecliptic. */
epsilon.calc(moshier.body.earth.position.date)
body.position.nutation = nutation.calc(moshier.body.earth.position.date, p)
/* Display the final apparent R.A. and Dec.
* for equinox of date.
*/
body.position.constellation = constellation.calc(p, moshier.body.earth.position.date)
body.position.apparent = util.showrd(p, polar)
/* Geocentric ecliptic longitude and latitude. */
p.longitude *= constant.EO
p.latitude *= constant.EO
p.distance *= constant.EO
body.position.apparentGeocentric = lonlat.calc(p, moshier.body.earth.position.date, false)
body.position.apparentGeocentric_prev_date = lonlat.calc(p, constant.retro_date, false)
body.position.apparentLongitude = body.position.apparentGeocentric.longitude * constant.RTD
body.position.apparentLongitudeString =
body.position.apparentGeocentric.dLongitude.degree + '\u00B0' +
body.position.apparentGeocentric.dLongitude.minutes + '\'' +
Math.floor(body.position.apparentGeocentric.dLongitude.seconds) + '"'
var p1 = body.position.apparentGeocentric_prev_date.dLongitude
var p2 = body.position.apparentGeocentric.dLongitude
body.position.is_retrograde = (util.degreesToDecimal(p1['degree'], p1['minutes'], p1['seconds']) - util.degreesToDecimal(p2['degree'], p2['minutes'], p2['seconds'])) < 0
body.position.apparentLongitude30String =
util.mod30(body.position.apparentGeocentric.dLongitude.degree) + '\u00B0' +
body.position.apparentGeocentric.dLongitude.minutes + '\'' +
Math.floor(body.position.apparentGeocentric.dLongitude.seconds) + '"'
body.position.geocentricDistance = -1
/* Go do topocentric reductions. */
polar.distance = constant.EO
body.position.altaz = altaz.calc(polar, moshier.body.earth.position.date)
}
planet.prepare = function (body) {
if (!body.semiAxis) {
body.semiAxis = body.perihelionDistance / (1 - body.eccentricity)
}
}
module.exports = planet