import { Sun } from '@/sun'
import { DEG2RAD, ONE_UA_IN_KILOMETERS, RAD2DEG } from '@/constants'
import { ArcSecond, Degree, Equinox, JulianDay, Kilometer, Obliquity, Radian } from '@/types'
import { getRadiusVector as getEarthRadiusVector } from '@/earth/coordinates'
import { getGeocentricEquatorialCoordinates, getRadiusVectorInKilometer } from './coordinates'
/**
* The geocentric elongation of the moon
* @param {JulianDay} jd
* @returns {Degree}
* @memberof module:Earth
*/
export function getGeocentricElongation (jd: JulianDay): Degree {
const sunCoords = Sun.getGeocentricEquatorialCoordinates(jd, Equinox.MeanOfTheDate)
const moonCoords = getGeocentricEquatorialCoordinates(jd, Obliquity.Mean)
const decRadSun = sunCoords.declination * DEG2RAD
const decRadMoon = moonCoords.declination * DEG2RAD
const raRadSun = sunCoords.rightAscension * DEG2RAD
const raRadMoon = moonCoords.rightAscension * DEG2RAD
const sins = Math.sin(decRadSun) * Math.sin(decRadMoon)
const coss = Math.cos(decRadSun) * Math.cos(decRadMoon) * Math.cos(raRadSun - raRadMoon)
// See first equation 48.2 of AA, p. 345.
return Math.acos(sins + coss) * RAD2DEG
}
/**
* The phase angle (angle Sun-Moon-Earth)
* @param {JulianDay} jd The julian day
* @return {Degree}
* @memberof module:Earth
*/
export function getPhaseAngle (jd: JulianDay): Degree {
// Geocentric elongation of the Moon from the Sun
const psi: Radian = getGeocentricElongation(jd) * DEG2RAD
// Distance Earth-Moon
const Delta: Kilometer = getRadiusVectorInKilometer(jd) // kilometer!!!
// Distance Earth-Sun
const R: Kilometer = getEarthRadiusVector(jd) * ONE_UA_IN_KILOMETERS
return Math.atan2(R * Math.sin(psi), Delta - R * Math.cos(psi)) * RAD2DEG
}
/**
* The position angle of the bright limb.
* The position angle of the Moon's bright limb is the position angle of the midpoint of the illuminated limb of
* the Moon, reckoned eastward from the North Point of the disk (not from the axis of rotation of the lunar globe).
* @param {JulianDay} jd The julian day
* @return {Degree}
* @memberof module:Earth
*/
export function getPositionAngleOfTheBrightLimb (jd: JulianDay): Degree {
const sunCoords = Sun.getGeocentricEquatorialCoordinates(jd, Equinox.MeanOfTheDate)
const moonCoords = getGeocentricEquatorialCoordinates(jd, Obliquity.Mean)
const alpha0 = (sunCoords.rightAscension as Degree) * DEG2RAD
const alpha = (moonCoords.rightAscension as Degree) * DEG2RAD
const delta0 = (sunCoords.declination as Degree) * DEG2RAD
const delta = (moonCoords.declination as Degree) * DEG2RAD
const y = Math.cos(delta0) * Math.sin(alpha0 - alpha)
const x = Math.sin(delta0) * Math.cos(delta)
- (Math.cos(delta0) * Math.sin(delta) * Math.cos(alpha0 - alpha))
return Math.atan2(y, x) * RAD2DEG
}
/**
* The illuminated fraction of the Moon as seen from the Earth.
* Between 0 and 1.
* @param {JulianDay} jd The julian day
* @returns {number}
* @memberof module:Earth
*/
export function getIlluminatedFraction (jd: JulianDay): number {
const phaseAngle = getPhaseAngle(jd) * DEG2RAD
return (1 + Math.cos(phaseAngle)) / 2
}
/**
* Equatorial horizontal parallax
* @param {JulianDay} jd The julian day
* @returns {Degree}
* @memberof module:Earth
*/
export function getEquatorialHorizontalParallax (jd: JulianDay): Degree {
return Math.asin(6378.14 / getRadiusVectorInKilometer(jd)) * RAD2DEG
}
/**
* Geocentric Moon semi-diameter.
* Error is less than 0.0005 arcsecond (see AA p391).
* @param {JulianDay} jd The julian day
* @returns {Degree}
* @memberof module:Earth
*/
export function getGeocentricSemiDiameter (jd: JulianDay): ArcSecond {
return 358_473_400 / getRadiusVectorInKilometer(jd)
}
Source