-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This introduces the new body `Astronoby::Moon` and an entire algorithm to compute its ecliptic coordinates. The algorithm is based on the Lunar theory called "Éphéméride Lunaire Parisienne" by Jean Chapront and Michelle Chapront-Touzé, and used by Jean Meeus's formulae in Astronomical Algorithms. ```rb time = Time.utc(2015, 1, 1) moon = Astronoby::Moon.new(time: time) coordinates = moon.apparent_ecliptic_coordinates coordinates.latitude.str(:dms) # => "-2° 53′ 58.1867″" coordinates.longitude.str(:dms) # => "+50° 37′ 3.5842″" ```
- Loading branch information
1 parent
a1bed12
commit d7abcef
Showing
4 changed files
with
494 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
lib/astronoby/astronomical_models/ephemeride_lunaire_parisienne.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
# frozen_string_literal: true | ||
|
||
module Astronoby | ||
class EphemerideLunaireParisienne | ||
# Lunar theory: Éphéméride Lunaire Parisienne | ||
# By Jean Chapront, Michelle Chapront-Touzé | ||
# https://en.wikipedia.org/wiki/Ephemeride_Lunaire_Parisienne | ||
|
||
DEGREES_UNIT = 10**-6 | ||
|
||
# @return [Array] Periodic terms for the Moon's longitude and distance | ||
def self.periodic_terms_for_moon_longitude_and_distance | ||
[ | ||
[0, 0, 1, 0, 6288774, -20905355], | ||
[2, 0, -1, 0, 1274027, -3699111], | ||
[2, 0, 0, 0, 658314, -2955968], | ||
[0, 0, 2, 0, 213618, -569925], | ||
[0, 1, 0, 0, -185116, 48888], | ||
[0, 0, 0, 2, -114332, -3149], | ||
[2, 0, -2, 0, 58793, 246158], | ||
[2, -1, -1, 0, 57066, -152138], | ||
[2, 0, 1, 0, 53322, -170733], | ||
[2, -1, 0, 0, 45758, -204586], | ||
[0, 1, -1, 0, -40923, -129620], | ||
[1, 0, 0, 0, -34720, 108743], | ||
[0, 1, 1, 0, -30383, 104755], | ||
[2, 0, 0, -2, 15327, 10321], | ||
[0, 0, 1, 2, -12528, 0], | ||
[0, 0, 1, -2, 10980, 79661], | ||
[4, 0, -1, 0, 10675, -34782], | ||
[0, 0, 3, 0, 10034, -23210], | ||
[4, 0, -2, 0, 8548, -21636], | ||
[2, 1, -1, 0, -7888, 24208], | ||
[2, 1, 0, 0, -6766, 30824], | ||
[1, 0, -1, 0, -5163, -8379], | ||
[1, 1, 0, 0, 4987, -16675], | ||
[2, -1, 1, 0, 4036, -12831], | ||
[2, 0, 2, 0, 3994, -10445], | ||
[4, 0, 0, 0, 3861, -11650], | ||
[2, 0, -3, 0, 3665, 14403], | ||
[0, 1, -2, 0, -2689, -7003], | ||
[2, 0, -1, 2, -2602, 0], | ||
[2, -1, -2, 0, 2390, 10056], | ||
[1, 0, 1, 0, -2348, 6322], | ||
[2, -2, 0, 0, 2236, -9884], | ||
[0, 1, 2, 0, -2120, 5751], | ||
[0, 2, 0, 0, -2069, 0], | ||
[2, -2, -1, 0, 2048, -4950], | ||
[2, 0, 1, -2, -1773, 4130], | ||
[2, 0, 0, 2, -1595, 0], | ||
[4, -1, -1, 0, 1215, -3958], | ||
[0, 0, 2, 2, -1110, 0], | ||
[3, 0, -1, 0, -892, 3258], | ||
[2, 1, 1, 0, -810, 2616], | ||
[4, -1, -2, 0, 759, -1897], | ||
[0, 2, -1, 0, -713, -2117], | ||
[2, 2, -1, 0, -700, 2354], | ||
[2, 1, -2, 0, 691, 0], | ||
[2, -1, 0, -2, 596, 0], | ||
[4, 0, 1, 0, 549, -1423], | ||
[0, 0, 4, 0, 537, -1117], | ||
[4, -1, 0, 0, 520, -1571], | ||
[1, 0, -2, 0, -487, -1739], | ||
[2, 1, 0, -2, -399, 0], | ||
[0, 0, 2, -2, -381, -4421], | ||
[1, 1, 1, 0, 351, 0], | ||
[3, 0, -2, 0, -340, 0], | ||
[4, 0, -3, 0, 330, 0], | ||
[2, -1, 2, 0, 327, 0], | ||
[0, 2, 1, 0, -323, 1165], | ||
[1, 1, -1, 0, 299, 0], | ||
[2, 0, 3, 0, 294, 0], | ||
[2, 0, -1, -2, 0, 8752] | ||
] | ||
end | ||
|
||
# @return [Array] Periodic terms for the Moon's latitude | ||
def self.periodic_terms_for_moon_latitude | ||
[ | ||
[0, 0, 0, 1, 5128122], | ||
[0, 0, 1, 1, 280602], | ||
[0, 0, 1, -1, 277693], | ||
[2, 0, 0, -1, 173237], | ||
[2, 0, -1, 1, 55413], | ||
[2, 0, -1, -1, 46271], | ||
[2, 0, 0, 1, 32573], | ||
[0, 0, 2, 1, 17198], | ||
[2, 0, 1, -1, 9266], | ||
[0, 0, 2, -1, 8822], | ||
[2, -1, 0, -1, 8216], | ||
[2, 0, -2, -1, 4324], | ||
[2, 0, 1, 1, 4200], | ||
[2, 1, 0, -1, -3359], | ||
[2, -1, -1, 1, 2463], | ||
[2, -1, 0, 1, 2211], | ||
[2, -1, -1, -1, 2065], | ||
[0, 1, -1, -1, -1870], | ||
[4, 0, -1, -1, 1828], | ||
[0, 1, 0, 1, -1794], | ||
[0, 0, 0, 3, -1749], | ||
[0, 1, -1, 1, -1565], | ||
[1, 0, 0, 1, -1491], | ||
[0, 1, 1, 1, -1475], | ||
[0, 1, 1, -1, -1410], | ||
[0, 1, 0, -1, -1344], | ||
[1, 0, 0, -1, -1335], | ||
[0, 0, 3, 1, 1107], | ||
[4, 0, 0, -1, 1021], | ||
[4, 0, -1, 1, 833], | ||
[0, 0, 1, -3, 777], | ||
[4, 0, -2, 1, 671], | ||
[2, 0, 0, -3, 607], | ||
[2, 0, 2, -1, 596], | ||
[2, -1, 1, -1, 491], | ||
[2, 0, -2, 1, -451], | ||
[0, 0, 3, -1, 439], | ||
[2, 0, 2, 1, 422], | ||
[2, 0, -3, -1, 421], | ||
[2, 1, -1, 1, -366], | ||
[2, 1, 0, 1, -351], | ||
[4, 0, 0, 1, 331], | ||
[2, -1, 1, 1, 315], | ||
[2, -2, 0, -1, 302], | ||
[0, 0, 1, 3, -283], | ||
[2, 1, 1, -1, -229], | ||
[1, 1, 0, -1, 223], | ||
[1, 1, 0, 1, 223], | ||
[0, 1, -2, -1, -220], | ||
[2, 1, -1, -1, -220], | ||
[1, 0, 1, 1, -185], | ||
[2, -1, -2, -1, 181], | ||
[0, 1, 2, 1, -177], | ||
[4, 0, -2, -1, 176], | ||
[4, -1, -1, -1, 166], | ||
[1, 0, 1, -1, -164], | ||
[4, 0, 1, -1, 132], | ||
[1, 0, -1, -1, -119], | ||
[4, -1, 0, -1, 115], | ||
[2, -2, 0, 1, 107] | ||
] | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
# frozen_string_literal: true | ||
|
||
module Astronoby | ||
class Moon | ||
MEAN_GEOCENTRIC_DISTANCE = 385_000_560 | ||
|
||
def initialize(time:) | ||
@time = time | ||
end | ||
|
||
# Source: | ||
# Title: Astronomical Algorithms | ||
# Author: Jean Meeus | ||
# Edition: 2nd edition | ||
# Chapter: 47 - Position of the Moon | ||
|
||
# @return [Coordinates::Ecliptic] Ecliptic coordinates of the Moon | ||
def apparent_ecliptic_coordinates | ||
@ecliptic_coordinates ||= begin | ||
latitude = Astronoby::Angle.from_degrees( | ||
(latitude_terms + additive_latitude_terms) * | ||
EphemerideLunaireParisienne::DEGREES_UNIT | ||
) | ||
|
||
longitude = mean_longitude + Astronoby::Angle.from_degrees( | ||
(longitude_terms + additive_longitude_terms) * | ||
EphemerideLunaireParisienne::DEGREES_UNIT | ||
) + nutation | ||
|
||
Coordinates::Ecliptic.new( | ||
latitude: latitude, | ||
longitude: longitude | ||
) | ||
end | ||
end | ||
|
||
# @return [Integer] Distance between the Earth and the Moon centers in meters | ||
def distance | ||
@distance ||= (MEAN_GEOCENTRIC_DISTANCE + distance_terms).round | ||
end | ||
|
||
# @return [Angle] Moon's mean longitude | ||
def mean_longitude | ||
@mean_longitude ||= begin | ||
degrees = | ||
218.3164477 + | ||
481267.88123421 * elapsed_centuries - | ||
0.0015786 * elapsed_centuries**2 + | ||
elapsed_centuries**3 / 538841 - | ||
elapsed_centuries**4 / 65194000 | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
# @return [Angle] Moon's mean elongation | ||
def mean_elongation | ||
@mean_elongation ||= begin | ||
degrees = | ||
297.8501921 + | ||
445267.1114034 * elapsed_centuries - | ||
0.0018819 * elapsed_centuries**2 + | ||
elapsed_centuries**3 / 545868 - | ||
elapsed_centuries**4 / 113065000 | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
# @return [Angle] Moon's mean anomaly | ||
def mean_anomaly | ||
@mean_anomaly ||= begin | ||
degrees = | ||
134.9633964 + | ||
477198.8675055 * elapsed_centuries + | ||
0.0087414 * elapsed_centuries**2 + | ||
elapsed_centuries**3 / 69699 - | ||
elapsed_centuries**4 / 14712000 | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
# @return [Angle] Moon's argument of latitude | ||
def argument_of_latitude | ||
@argument_of_latitude ||= begin | ||
degrees = | ||
93.2720950 + | ||
483202.0175233 * elapsed_centuries - | ||
0.0036539 * elapsed_centuries**2 - | ||
elapsed_centuries**3 / 3526000 | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
private | ||
|
||
def terrestrial_time | ||
@terrestrial_time ||= begin | ||
delta = Util::Time.terrestrial_universal_time_delta(@time) | ||
@time + delta | ||
end | ||
end | ||
|
||
def julian_date | ||
Epoch.from_time(terrestrial_time) | ||
end | ||
|
||
def elapsed_centuries | ||
(julian_date - Epoch::DEFAULT_EPOCH) / Constants::DAYS_PER_JULIAN_CENTURY | ||
end | ||
|
||
def sun_mean_anomaly | ||
@sun_mean_anomaly ||= Sun.new(time: @time).mean_anomaly | ||
end | ||
|
||
def a1 | ||
@a1 ||= begin | ||
degrees = 119.75 + 131.849 * elapsed_centuries | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
def a2 | ||
@a2 ||= begin | ||
degrees = 53.09 + 479264.290 * elapsed_centuries | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
def a3 | ||
@a3 ||= begin | ||
degrees = 313.45 + 481266.484 * elapsed_centuries | ||
degrees += Constants::DEGREES_PER_CIRCLE while degrees.negative? | ||
Angle.from_degrees(degrees) | ||
end | ||
end | ||
|
||
def eccentricity_correction | ||
@eccentricity_correction ||= | ||
1 - 0.002516 * elapsed_centuries - 0.0000074 * elapsed_centuries**2 | ||
end | ||
|
||
def latitude_terms | ||
@latitude_terms ||= | ||
Astronoby::EphemerideLunaireParisienne | ||
.periodic_terms_for_moon_latitude | ||
.inject(0) do |sum, terms| | ||
value = terms[4] * Math.sin( | ||
terms[0] * mean_elongation.radians + | ||
terms[1] * sun_mean_anomaly.radians + | ||
terms[2] * mean_anomaly.radians + | ||
terms[3] * argument_of_latitude.radians | ||
) | ||
|
||
value *= eccentricity_correction if terms[1].abs == 1 | ||
value *= eccentricity_correction**2 if terms[1].abs == 2 | ||
|
||
sum + value | ||
end | ||
end | ||
|
||
def additive_latitude_terms | ||
@additive_latitude_terms ||= | ||
-2235 * mean_longitude.sin + | ||
382 * a3.sin + | ||
175 * (a1 - argument_of_latitude).sin + | ||
175 * (a1 + argument_of_latitude).sin + | ||
127 * (mean_longitude - mean_anomaly).sin - | ||
115 * (mean_longitude + mean_anomaly).sin | ||
end | ||
|
||
def longitude_terms | ||
@longitude_terms ||= | ||
Astronoby::EphemerideLunaireParisienne | ||
.periodic_terms_for_moon_longitude_and_distance | ||
.inject(0) do |sum, terms| | ||
value = terms[4] * Math.sin( | ||
terms[0] * mean_elongation.radians + | ||
terms[1] * sun_mean_anomaly.radians + | ||
terms[2] * mean_anomaly.radians + | ||
terms[3] * argument_of_latitude.radians | ||
) | ||
|
||
value *= eccentricity_correction if terms[1].abs == 1 | ||
value *= eccentricity_correction**2 if terms[1].abs == 2 | ||
|
||
sum + value | ||
end | ||
end | ||
|
||
def additive_longitude_terms | ||
@additive_longitude_terms ||= | ||
3958 * a1.sin + | ||
1962 * (mean_longitude - argument_of_latitude).sin + | ||
318 * a2.sin | ||
end | ||
|
||
def distance_terms | ||
@distance_terms ||= | ||
EphemerideLunaireParisienne | ||
.periodic_terms_for_moon_longitude_and_distance | ||
.inject(0) do |sum, terms| | ||
value = terms[5] * Math.cos( | ||
terms[0] * mean_elongation.radians + | ||
terms[1] * sun_mean_anomaly.radians + | ||
terms[2] * mean_anomaly.radians + | ||
terms[3] * argument_of_latitude.radians | ||
) | ||
|
||
value *= eccentricity_correction if terms[1].abs == 1 | ||
value *= eccentricity_correction**2 if terms[1].abs == 2 | ||
|
||
sum + value | ||
end | ||
end | ||
|
||
def nutation | ||
@nutation ||= | ||
Astronoby::Nutation.for_ecliptic_longitude(epoch: julian_date) | ||
end | ||
end | ||
end |
Oops, something went wrong.