From bf02e4cb6c47dd75ae5cc7870d0a92c3544f0da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Hannequin?= Date: Mon, 20 May 2024 15:40:10 +0200 Subject: [PATCH] Moon's phase angle and illuminated fraction --- lib/astronoby/bodies/moon.rb | 37 ++++++++++- spec/astronoby/bodies/moon_spec.rb | 103 +++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/lib/astronoby/bodies/moon.rb b/lib/astronoby/bodies/moon.rb index 3920609..2d25e14 100644 --- a/lib/astronoby/bodies/moon.rb +++ b/lib/astronoby/bodies/moon.rb @@ -120,6 +120,37 @@ def argument_of_latitude end end + # @return [Angle] Moon's phase angle + def phase_angle + @phase_angle ||= begin + sun_apparent_equatorial_coordinates = sun + .apparent_ecliptic_coordinates + .to_apparent_equatorial(epoch: Epoch.from_time(@time)) + moon_apparent_equatorial_coordinates = apparent_equatorial_coordinates + geocentric_elongation = Angle.acos( + sun_apparent_equatorial_coordinates.declination.sin * + moon_apparent_equatorial_coordinates.declination.sin + + sun_apparent_equatorial_coordinates.declination.cos * + moon_apparent_equatorial_coordinates.declination.cos * + ( + sun_apparent_equatorial_coordinates.right_ascension - + moon_apparent_equatorial_coordinates.right_ascension + ).cos + ) + + term1 = sun.earth_distance.km * geocentric_elongation.sin + term2 = distance.km - sun.earth_distance.km * geocentric_elongation.cos + angle = Angle.atan(term1 / term2) + Astronoby::Util::Trigonometry + .adjustement_for_arctangent(term1, term2, angle) + end + end + + # @return [Float] Moon's illuminated fraction + def illuminated_fraction + @illuminated_fraction ||= (1 + phase_angle.cos) / 2 + end + private def terrestrial_time @@ -137,8 +168,12 @@ def elapsed_centuries (julian_date - Epoch::DEFAULT_EPOCH) / Constants::DAYS_PER_JULIAN_CENTURY end + def sun + @sun ||= Sun.new(time: @time) + end + def sun_mean_anomaly - @sun_mean_anomaly ||= Sun.new(time: @time).mean_anomaly + @sun_mean_anomaly ||= sun.mean_anomaly end def a1 diff --git a/spec/astronoby/bodies/moon_spec.rb b/spec/astronoby/bodies/moon_spec.rb index 28913db..5f4330b 100644 --- a/spec/astronoby/bodies/moon_spec.rb +++ b/spec/astronoby/bodies/moon_spec.rb @@ -286,4 +286,107 @@ # Result from IMCCE: +313° 25′ 58.08″ end end + + describe "#phase_angle" do + # Source: + # Title: Astronomical Algorithms + # Author: Jean Meeus + # Edition: 2nd edition + # Chapter: 48 - Illuminated Fraction of the Moon's Disk, p.346 + it "returns the phase angle for 1992-04-12" do + # Example gives 1992-04-12 00:00:00 TT (and not UTC) + time = Time.utc(1992, 4, 12, 0, 0, 0) + time -= Astronoby::Util::Time.terrestrial_universal_time_delta(time) + moon = described_class.new(time: time) + + phase_angle = moon.phase_angle + + expect(phase_angle.degrees.round(4)).to eq 69.0742 + # Result from the book: 69.0756° + # Result from IMCCE: 69.07611798° + end + end + + describe "#illuminated_fraction" do + # Source: + # Title: Astronomical Algorithms + # Author: Jean Meeus + # Edition: 2nd edition + # Chapter: 48 - Illuminated Fraction of the Moon's Disk, p.346 + it "returns the illuminated fraction for 1992-04-12" do + # Example gives 1992-04-12 00:00:00 TT (and not UTC) + time = Time.utc(1992, 4, 12, 0, 0, 0) + time -= Astronoby::Util::Time.terrestrial_universal_time_delta(time) + moon = described_class.new(time: time) + + illuminated_fraction = moon.illuminated_fraction + + expect(illuminated_fraction.round(4)).to eq 0.6786 + # Result from the book: 0.6786 + # Result from IMCCE: 0.679 + end + + # Source: + # Title: Celestial Calculations + # Author: J. L. Lawrence + # Edition: MIT Press + # Chapter: 7 - The Moon, p.180 + it "returns the illuminated fraction for 2015-01-01" do + moon = described_class.new(time: Time.utc(2015, 1, 1)) + + illuminated_fraction = moon.illuminated_fraction + + expect(illuminated_fraction.round(4)).to eq 0.8243 + # Result from the book: 0.82 + # Result from IMCCE: 0.824 + end + + # Source: + # Title: Celestial Calculations + # Author: J. L. Lawrence + # Edition: MIT Press + # Chapter: 7 - The Moon, p.185 + it "returns the apparent ecliptic coordinates for 2005-08-09" do + moon = described_class.new(time: Time.utc(2005, 8, 9)) + + illuminated_fraction = moon.illuminated_fraction + + expect(illuminated_fraction.round(4)).to eq 0.1315 + # Result from the book: 0.13 + # Result from IMCCE: 0.132 + end + + # Source: + # Title: Celestial Calculations + # Author: J. L. Lawrence + # Edition: MIT Press + # Chapter: 7 - The Moon, p.185 + it "returns the apparent ecliptic coordinates for 2005-05-06" do + moon = described_class.new(time: Time.utc(2005, 5, 6, 14, 30)) + + illuminated_fraction = moon.illuminated_fraction + + expect(illuminated_fraction.round(4)).to eq 0.0347 + # Result from the book: 0.06 + # Result from IMCCE: 0.035 + end + + # Source: + # Title: Practical Astronomy with your Calculator or Spreadsheet + # Authors: Peter Duffett-Smith and Jonathan Zwart + # Edition: Cambridge University Press + # Chapter: 67 - The phases of the Moon, p.171 + it "returns the apparent ecliptic coordinates for 2003-09-01" do + # Example gives 2003-09-01 00:00:00 TT (and not UTC) + time = Time.utc(2003, 9, 1, 0, 0, 0) + time -= Astronoby::Util::Time.terrestrial_universal_time_delta(time) + moon = described_class.new(time: time) + + illuminated_fraction = moon.illuminated_fraction + + expect(illuminated_fraction.round(4)).to eq 0.2257 + # Result from the book: 0.225 + # Result from IMCCE: 0.226 + end + end end