Class: Astronoby::Moon

Inherits:
Object
  • Object
show all
Defined in:
lib/astronoby/bodies/moon.rb

Constant Summary collapse

SEMIDIAMETER_VARIATION =
0.7275
MEAN_GEOCENTRIC_DISTANCE =
Astronoby::Distance.from_meters(385_000_560)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(time:) ⇒ Moon

Returns a new instance of Moon.



21
22
23
# File 'lib/astronoby/bodies/moon.rb', line 21

def initialize(time:)
  @time = time
end

Class Method Details

.monthly_phase_events(year:, month:) ⇒ Array<Astronoby::MoonPhase>

Returns Moon phases for the requested year.

Parameters:

  • year (Integer)

    Requested year

  • month (Integer)

    Requested month

Returns:



17
18
19
# File 'lib/astronoby/bodies/moon.rb', line 17

def self.monthly_phase_events(year:, month:)
  Events::MoonPhases.phases_for(year: year, month: month)
end

Instance Method Details

#apparent_ecliptic_coordinatesAstronoby::Coordinates::Ecliptic

Returns Apparent ecliptic coordinates of the Moon.

Returns:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/astronoby/bodies/moon.rb', line 27

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

#apparent_equatorial_coordinatesAstronoby::Coordinates::Equatorial

Returns Apparent geocentric equatorial coordinates of the Moon.

Returns:



54
55
56
57
58
# File 'lib/astronoby/bodies/moon.rb', line 54

def apparent_equatorial_coordinates
  @apparent_equatorial_coordinates ||=
    apparent_ecliptic_coordinates
      .to_apparent_equatorial(epoch: Epoch.from_time(@time))
end

#argument_of_latitudeAngle

Returns Moon’s argument of latitude.

Returns:

  • (Angle)

    Moon’s argument of latitude



122
123
124
125
126
127
128
129
130
131
# File 'lib/astronoby/bodies/moon.rb', line 122

def argument_of_latitude
  @argument_of_latitude ||= Angle.from_degrees(
    (
      93.2720950 +
      483202.0175233 * elapsed_centuries -
      0.0036539 * elapsed_centuries**2 -
      elapsed_centuries**3 / 3526000
    ) % 360
  )
end

#distanceAstronoby::Distance

Returns Distance between the Earth and the Moon centers.

Returns:



76
77
78
79
80
# File 'lib/astronoby/bodies/moon.rb', line 76

def distance
  @distance ||= Astronoby::Distance.from_meters(
    (MEAN_GEOCENTRIC_DISTANCE.meters + distance_terms).round
  )
end

#horizontal_coordinates(observer:) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/astronoby/bodies/moon.rb', line 60

def horizontal_coordinates(observer:)
  apparent_topocentric_equatorial_coordinates =
    Astronoby::GeocentricParallax.for_equatorial_coordinates(
      observer: observer,
      time: @time,
      coordinates: apparent_equatorial_coordinates,
      distance: distance
    )

  apparent_topocentric_equatorial_coordinates.to_horizontal(
    observer: observer,
    time: @time
  )
end

#illuminated_fractionFloat

Returns Moon’s illuminated fraction.

Returns:

  • (Float)

    Moon’s illuminated fraction



166
167
168
# File 'lib/astronoby/bodies/moon.rb', line 166

def illuminated_fraction
  @illuminated_fraction ||= (1 + phase_angle.cos) / 2
end

#mean_anomalyAngle

Returns Moon’s mean anomaly.

Returns:

  • (Angle)

    Moon’s mean anomaly



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/astronoby/bodies/moon.rb', line 109

def mean_anomaly
  @mean_anomaly ||= Angle.from_degrees(
    (
      134.9633964 +
      477198.8675055 * elapsed_centuries +
      0.0087414 * elapsed_centuries**2 +
      elapsed_centuries**3 / 69699 -
      elapsed_centuries**4 / 14712000
    ) % 360
  )
end

#mean_elongationAngle

Returns Moon’s mean elongation.

Returns:

  • (Angle)

    Moon’s mean elongation



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/astronoby/bodies/moon.rb', line 96

def mean_elongation
  @mean_elongation ||= Angle.from_degrees(
    (
      297.8501921 +
      445267.1114034 * elapsed_centuries -
      0.0018819 * elapsed_centuries**2 +
      elapsed_centuries**3 / 545868 -
      elapsed_centuries**4 / 113065000
    ) % 360
  )
end

#mean_longitudeAngle

Returns Moon’s mean longitude.

Returns:

  • (Angle)

    Moon’s mean longitude



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/astronoby/bodies/moon.rb', line 83

def mean_longitude
  @mean_longitude ||= Angle.from_degrees(
    (
      218.3164477 +
      481267.88123421 * elapsed_centuries -
      0.0015786 * elapsed_centuries**2 +
      elapsed_centuries**3 / 538841 -
      elapsed_centuries**4 / 65194000
    ) % 360
  )
end

#observation_events(observer:) ⇒ Astronoby::Events::ObservationEvents

Returns Moon’s observation events.

Parameters:

Returns:



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/astronoby/bodies/moon.rb', line 172

def observation_events(observer:)
  today = @time.to_date
  leap_seconds = Util::Time.terrestrial_universal_time_delta(today)
  yesterday = today.prev_day
  yesterday_midnight_terrestrial_time =
    Time.utc(yesterday.year, yesterday.month, yesterday.day) - leap_seconds
  today_midnight_terrestrial_time =
    Time.utc(today.year, today.month, today.day) - leap_seconds
  tomorrow = today.next_day
  tomorrow_midnight_terrestrial_time =
    Time.utc(tomorrow.year, tomorrow.month, tomorrow.day) - leap_seconds

  coordinates_of_the_previous_day = self.class
    .new(time: yesterday_midnight_terrestrial_time)
    .apparent_equatorial_coordinates
  coordinates_of_the_day = self.class
    .new(time: today_midnight_terrestrial_time)
    .apparent_equatorial_coordinates
  coordinates_of_the_next_day = self.class
    .new(time: tomorrow_midnight_terrestrial_time)
    .apparent_equatorial_coordinates
  additional_altitude = -Angle.from_degrees(
    SEMIDIAMETER_VARIATION *
      GeocentricParallax.angle(distance: distance).degrees
  )

  Events::ObservationEvents.new(
    observer: observer,
    date: today,
    coordinates_of_the_previous_day: coordinates_of_the_previous_day,
    coordinates_of_the_day: coordinates_of_the_day,
    coordinates_of_the_next_day: coordinates_of_the_next_day,
    additional_altitude: additional_altitude
  )
end

#phase_angleAngle

Returns Moon’s phase angle.

Returns:

  • (Angle)

    Moon’s phase angle



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/astronoby/bodies/moon.rb', line 140

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