astronoby 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,249 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class MoonPhasesPeriodicTerms
5
+ # Lunar Solution ELP 2000-82B (Chapront-Touze+, 1988)
6
+
7
+ # Source:
8
+ # Title: Astronomical Algorithms
9
+ # Author: Jean Meeus
10
+ # Edition: 2nd edition
11
+ # Chapter: 49 - Phases of the Moon
12
+
13
+ # @param julian_centuries [Float] Julian centuries
14
+ # @param time [Float] Time
15
+ # @param eccentricity_correction [Float] Eccentricity correction
16
+ # @param moon_mean_anomaly [Float] Moon mean anomaly
17
+ # @param sun_mean_anomaly [Float] Sun mean anomaly
18
+ # @param moon_argument_of_latitude [Float] Moon argument of latitude
19
+ # @param longitude_of_the_ascending_node [Float] Longitude of the ascending node
20
+ def initialize(
21
+ julian_centuries:,
22
+ time:,
23
+ eccentricity_correction:,
24
+ moon_mean_anomaly:,
25
+ sun_mean_anomaly:,
26
+ moon_argument_of_latitude:,
27
+ longitude_of_the_ascending_node:
28
+
29
+ )
30
+ @julian_centuries = julian_centuries
31
+ @time = time
32
+ @eccentricity_correction = eccentricity_correction
33
+ @moon_mean_anomaly = moon_mean_anomaly
34
+ @sun_mean_anomaly = sun_mean_anomaly
35
+ @moon_argument_of_latitude = moon_argument_of_latitude
36
+ @longitude_of_the_ascending_node = longitude_of_the_ascending_node
37
+ end
38
+
39
+ # @return [Float] New moon correction
40
+ def new_moon_correction
41
+ ecc = @eccentricity_correction
42
+ mma = @moon_mean_anomaly.radians
43
+ sma = @sun_mean_anomaly.radians
44
+ maol = @moon_argument_of_latitude.radians
45
+ lotan = @longitude_of_the_ascending_node.radians
46
+ [
47
+ [-0.40720, mma],
48
+ [0.17241 * ecc, sma],
49
+ [0.01608, 2 * mma],
50
+ [0.01039, 2 * maol],
51
+ [0.00739 * ecc, mma - sma],
52
+ [-0.00514 * ecc, mma + sma],
53
+ [0.00208 * ecc * ecc, 2 * sma],
54
+ [-0.00111, mma - 2 * maol],
55
+ [-0.00057, mma + 2 * maol],
56
+ [0.00056 * ecc, 2 * mma + sma],
57
+ [-0.00042, 3 * mma],
58
+ [0.00042 * ecc, sma + 2 * maol],
59
+ [0.00038 * ecc, sma - 2 * maol],
60
+ [-0.00024 * ecc, 2 * mma - sma],
61
+ [-0.00017, lotan],
62
+ [-0.00007, mma + 2 * sma],
63
+ [0.00004, 2 * mma - 2 * maol],
64
+ [0.00004, 3 * sma],
65
+ [0.00003, mma + sma - 2 * maol],
66
+ [0.00003, 2 * mma + 2 * maol],
67
+ [-0.00003, mma + sma + 2 * maol],
68
+ [0.00003, mma - sma + 2 * maol],
69
+ [-0.00002, mma - sma - 2 * maol],
70
+ [-0.00002, 3 * mma + sma],
71
+ [0.00002, 4 * mma]
72
+ ].map { _1.first * Math.sin(_1.last) }.sum
73
+ end
74
+
75
+ # @return [Float] First quarter correction
76
+ def first_quarter_correction
77
+ first_and_last_quarter_correction + first_and_last_quarter_final_correction
78
+ end
79
+
80
+ # @return [Float] Full moon correction
81
+ def full_moon_correction
82
+ ecc = @eccentricity_correction
83
+ mma = @moon_mean_anomaly.radians
84
+ sma = @sun_mean_anomaly.radians
85
+ maol = @moon_argument_of_latitude.radians
86
+ lotan = @longitude_of_the_ascending_node.radians
87
+ [
88
+ [-0.40614, mma],
89
+ [0.17302 * ecc, sma],
90
+ [0.01614, 2 * mma],
91
+ [0.01043, 2 * maol],
92
+ [0.00734 * ecc, mma - sma],
93
+ [-0.00515 * ecc, mma + sma],
94
+ [0.00209 * ecc * ecc, 2 * sma],
95
+ [-0.00111, mma - 2 * maol],
96
+ [-0.00057, mma + 2 * maol],
97
+ [0.00056 * ecc, 2 * mma + sma],
98
+ [-0.00042, 3 * mma],
99
+ [0.00042 * ecc, sma + 2 * maol],
100
+ [0.00038 * ecc, sma - 2 * maol],
101
+ [-0.00024 * ecc, 2 * mma - sma],
102
+ [-0.00017, lotan],
103
+ [-0.00007, mma + 2 * sma],
104
+ [0.00004, 2 * mma - 2 * maol],
105
+ [0.00004, 3 * sma],
106
+ [0.00003, mma + sma - 2 * maol],
107
+ [0.00003, 2 * mma + 2 * maol],
108
+ [-0.00003, mma + sma + 2 * maol],
109
+ [0.00003, mma - sma + 2 * maol],
110
+ [-0.00002, mma - sma - 2 * maol],
111
+ [-0.00002, 3 * mma + sma],
112
+ [0.00002, 4 * mma]
113
+ ].map { _1.first * Math.sin(_1.last) }.sum
114
+ end
115
+
116
+ # @return [Float] Last quarter correction
117
+ def last_quarter_correction
118
+ first_and_last_quarter_correction - first_and_last_quarter_final_correction
119
+ end
120
+
121
+ # @return [Float] Additional corrections
122
+ def additional_corrections
123
+ [
124
+ [0.000325, a1],
125
+ [0.000165, a2],
126
+ [0.000164, a3],
127
+ [0.000126, a4],
128
+ [0.000110, a5],
129
+ [0.000062, a6],
130
+ [0.000060, a7],
131
+ [0.000056, a8],
132
+ [0.000047, a9],
133
+ [0.000042, a10],
134
+ [0.000040, a11],
135
+ [0.000037, a12],
136
+ [0.000035, a13],
137
+ [0.000023, a14]
138
+ ].map { _1.first * _1.last.sin }.sum
139
+ end
140
+
141
+ private
142
+
143
+ def a1
144
+ Angle.from_degrees(
145
+ (
146
+ 299.77 +
147
+ 0.107408 * @time -
148
+ 0.009173 * @julian_centuries**2
149
+ ) % 360
150
+ )
151
+ end
152
+
153
+ def a2
154
+ Angle.from_degrees (251.88 + 0.016321 * @time) % 360
155
+ end
156
+
157
+ def a3
158
+ Angle.from_degrees (251.83 + 26.651886 * @time) % 360
159
+ end
160
+
161
+ def a4
162
+ Angle.from_degrees (349.42 + 36.412478 * @time) % 360
163
+ end
164
+
165
+ def a5
166
+ Angle.from_degrees (84.66 + 18.206239 * @time) % 360
167
+ end
168
+
169
+ def a6
170
+ Angle.from_degrees (141.74 + 53.303771 * @time) % 360
171
+ end
172
+
173
+ def a7
174
+ Angle.from_degrees (207.14 + 2.453732 * @time) % 360
175
+ end
176
+
177
+ def a8
178
+ Angle.from_degrees (154.84 + 7.306860 * @time) % 360
179
+ end
180
+
181
+ def a9
182
+ Angle.from_degrees (34.52 + 27.261239 * @time) % 360
183
+ end
184
+
185
+ def a10
186
+ Angle.from_degrees (207.19 + 0.121824 * @time) % 360
187
+ end
188
+
189
+ def a11
190
+ Angle.from_degrees (291.34 + 1.844379 * @time) % 360
191
+ end
192
+
193
+ def a12
194
+ Angle.from_degrees (161.72 + 24.198154 * @time) % 360
195
+ end
196
+
197
+ def a13
198
+ Angle.from_degrees (239.56 + 25.513099 * @time) % 360
199
+ end
200
+
201
+ def a14
202
+ Angle.from_degrees (331.55 + 3.592518 * @time) % 360
203
+ end
204
+
205
+ def first_and_last_quarter_final_correction
206
+ 0.00306 -
207
+ 0.00038 * @eccentricity_correction * @sun_mean_anomaly.cos +
208
+ 0.00026 * @moon_mean_anomaly.cos -
209
+ 0.00002 * (@moon_mean_anomaly - @sun_mean_anomaly).cos +
210
+ 0.00002 * (@moon_mean_anomaly + @sun_mean_anomaly).cos +
211
+ 0.00002 * Math.cos(2 * @moon_argument_of_latitude.radians)
212
+ end
213
+
214
+ def first_and_last_quarter_correction
215
+ ecc = @eccentricity_correction
216
+ mma = @moon_mean_anomaly.radians
217
+ sma = @sun_mean_anomaly.radians
218
+ maol = @moon_argument_of_latitude.radians
219
+ lotan = @longitude_of_the_ascending_node.radians
220
+ [
221
+ [-0.62801, mma],
222
+ [0.17172 * ecc, sma],
223
+ [-0.01183, mma + sma],
224
+ [0.00862, 2 * mma],
225
+ [0.00804, 2 * maol],
226
+ [0.00454 * ecc, mma - sma],
227
+ [0.00204 * ecc**2, 2 * sma],
228
+ [-0.00180, mma - 2 * maol],
229
+ [-0.00070, mma + 2 * maol],
230
+ [-0.00040, 3 * mma],
231
+ [-0.00034 * ecc, 2 * mma - sma],
232
+ [0.00032 * ecc, sma + 2 * maol],
233
+ [0.00032, sma - 2 * maol],
234
+ [-0.00028 * ecc**2, mma + 2 * sma],
235
+ [0.00027 * ecc, 2 * mma + sma],
236
+ [-0.00017, lotan],
237
+ [-0.00005, mma - sma - 2 * maol],
238
+ [0.00004, 2 * mma + 2 * maol],
239
+ [-0.00004, mma + sma + 2 * maol],
240
+ [0.00004, mma - 2 * sma],
241
+ [0.00003, mma + sma - 2 * maol],
242
+ [0.00003, 3 * sma],
243
+ [0.00002, 2 * mma - 2 * maol],
244
+ [0.00002, mma - sma + 2 * maol],
245
+ [-0.00002, 3 * mma + sma]
246
+ ].map { _1.first * Math.sin(_1.last) }.sum
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,335 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Moon
5
+ SEMIDIAMETER_VARIATION = 0.7275
6
+ MEAN_GEOCENTRIC_DISTANCE = Astronoby::Distance.from_meters(385_000_560)
7
+
8
+ # Source:
9
+ # Title: Astronomical Algorithms
10
+ # Author: Jean Meeus
11
+ # Edition: 2nd edition
12
+ # Chapter: 49 - Phases of the Moon
13
+
14
+ # @param year [Integer] Requested year
15
+ # @param month [Integer] Requested month
16
+ # @return [Array<Astronoby::MoonPhase>] Moon phases for the requested year
17
+ def self.monthly_phase_events(year:, month:)
18
+ Events::MoonPhases.phases_for(year: year, month: month)
19
+ end
20
+
21
+ def initialize(time:)
22
+ @time = time
23
+ end
24
+
25
+ # @return [Astronoby::Coordinates::Ecliptic] Apparent ecliptic coordinates
26
+ # of the Moon
27
+ def apparent_ecliptic_coordinates
28
+ @ecliptic_coordinates ||= begin
29
+ latitude = Astronoby::Angle.from_degrees(
30
+ (latitude_terms + additive_latitude_terms) *
31
+ EphemerideLunaireParisienne::DEGREES_UNIT
32
+ )
33
+
34
+ longitude = mean_longitude + Astronoby::Angle.from_degrees(
35
+ (longitude_terms + additive_longitude_terms) *
36
+ EphemerideLunaireParisienne::DEGREES_UNIT
37
+ ) + nutation
38
+
39
+ Coordinates::Ecliptic.new(
40
+ latitude: latitude,
41
+ longitude: longitude
42
+ )
43
+ end
44
+ end
45
+
46
+ # Source:
47
+ # Title: Astronomical Algorithms
48
+ # Author: Jean Meeus
49
+ # Edition: 2nd edition
50
+ # Chapter: 47 - Position of the Moon
51
+
52
+ # @return [Astronoby::Coordinates::Equatorial] Apparent geocentric
53
+ # equatorial coordinates of the Moon
54
+ def apparent_equatorial_coordinates
55
+ @apparent_equatorial_coordinates ||=
56
+ apparent_ecliptic_coordinates
57
+ .to_apparent_equatorial(epoch: Epoch.from_time(@time))
58
+ end
59
+
60
+ def horizontal_coordinates(observer:)
61
+ apparent_topocentric_equatorial_coordinates =
62
+ Astronoby::GeocentricParallax.for_equatorial_coordinates(
63
+ observer: observer,
64
+ time: @time,
65
+ coordinates: apparent_equatorial_coordinates,
66
+ distance: distance
67
+ )
68
+
69
+ apparent_topocentric_equatorial_coordinates.to_horizontal(
70
+ observer: observer,
71
+ time: @time
72
+ )
73
+ end
74
+
75
+ # @return [Astronoby::Distance] Distance between the Earth and the Moon centers
76
+ def distance
77
+ @distance ||= Astronoby::Distance.from_meters(
78
+ (MEAN_GEOCENTRIC_DISTANCE.meters + distance_terms).round
79
+ )
80
+ end
81
+
82
+ # @return [Angle] Moon's mean longitude
83
+ def mean_longitude
84
+ @mean_longitude ||= Angle.from_degrees(
85
+ (
86
+ 218.3164477 +
87
+ 481267.88123421 * elapsed_centuries -
88
+ 0.0015786 * elapsed_centuries**2 +
89
+ elapsed_centuries**3 / 538841 -
90
+ elapsed_centuries**4 / 65194000
91
+ ) % 360
92
+ )
93
+ end
94
+
95
+ # @return [Angle] Moon's mean elongation
96
+ def mean_elongation
97
+ @mean_elongation ||= Angle.from_degrees(
98
+ (
99
+ 297.8501921 +
100
+ 445267.1114034 * elapsed_centuries -
101
+ 0.0018819 * elapsed_centuries**2 +
102
+ elapsed_centuries**3 / 545868 -
103
+ elapsed_centuries**4 / 113065000
104
+ ) % 360
105
+ )
106
+ end
107
+
108
+ # @return [Angle] Moon's mean anomaly
109
+ def mean_anomaly
110
+ @mean_anomaly ||= Angle.from_degrees(
111
+ (
112
+ 134.9633964 +
113
+ 477198.8675055 * elapsed_centuries +
114
+ 0.0087414 * elapsed_centuries**2 +
115
+ elapsed_centuries**3 / 69699 -
116
+ elapsed_centuries**4 / 14712000
117
+ ) % 360
118
+ )
119
+ end
120
+
121
+ # @return [Angle] Moon's argument of latitude
122
+ def argument_of_latitude
123
+ @argument_of_latitude ||= Angle.from_degrees(
124
+ (
125
+ 93.2720950 +
126
+ 483202.0175233 * elapsed_centuries -
127
+ 0.0036539 * elapsed_centuries**2 -
128
+ elapsed_centuries**3 / 3526000
129
+ ) % 360
130
+ )
131
+ end
132
+
133
+ # Source:
134
+ # Title: Astronomical Algorithms
135
+ # Author: Jean Meeus
136
+ # Edition: 2nd edition
137
+ # Chapter: 48 - Illuminated Fraction of the Moon's Disk
138
+
139
+ # @return [Angle] Moon's phase angle
140
+ def phase_angle
141
+ @phase_angle ||= begin
142
+ sun_apparent_equatorial_coordinates = sun
143
+ .apparent_ecliptic_coordinates
144
+ .to_apparent_equatorial(epoch: Epoch.from_time(@time))
145
+ moon_apparent_equatorial_coordinates = apparent_equatorial_coordinates
146
+ geocentric_elongation = Angle.acos(
147
+ sun_apparent_equatorial_coordinates.declination.sin *
148
+ moon_apparent_equatorial_coordinates.declination.sin +
149
+ sun_apparent_equatorial_coordinates.declination.cos *
150
+ moon_apparent_equatorial_coordinates.declination.cos *
151
+ (
152
+ sun_apparent_equatorial_coordinates.right_ascension -
153
+ moon_apparent_equatorial_coordinates.right_ascension
154
+ ).cos
155
+ )
156
+
157
+ term1 = sun.earth_distance.km * geocentric_elongation.sin
158
+ term2 = distance.km - sun.earth_distance.km * geocentric_elongation.cos
159
+ angle = Angle.atan(term1 / term2)
160
+ Astronoby::Util::Trigonometry
161
+ .adjustement_for_arctangent(term1, term2, angle)
162
+ end
163
+ end
164
+
165
+ # @return [Float] Moon's illuminated fraction
166
+ def illuminated_fraction
167
+ @illuminated_fraction ||= (1 + phase_angle.cos) / 2
168
+ end
169
+
170
+ # @param observer [Astronoby::Observer] Observer of the event
171
+ # @return [Astronoby::Events::ObservationEvents] Moon's observation events
172
+ def observation_events(observer:)
173
+ today = @time.to_date
174
+ leap_seconds = Util::Time.terrestrial_universal_time_delta(today)
175
+ yesterday = today.prev_day
176
+ yesterday_midnight_terrestrial_time =
177
+ Time.utc(yesterday.year, yesterday.month, yesterday.day) - leap_seconds
178
+ today_midnight_terrestrial_time =
179
+ Time.utc(today.year, today.month, today.day) - leap_seconds
180
+ tomorrow = today.next_day
181
+ tomorrow_midnight_terrestrial_time =
182
+ Time.utc(tomorrow.year, tomorrow.month, tomorrow.day) - leap_seconds
183
+
184
+ coordinates_of_the_previous_day = self.class
185
+ .new(time: yesterday_midnight_terrestrial_time)
186
+ .apparent_equatorial_coordinates
187
+ coordinates_of_the_day = self.class
188
+ .new(time: today_midnight_terrestrial_time)
189
+ .apparent_equatorial_coordinates
190
+ coordinates_of_the_next_day = self.class
191
+ .new(time: tomorrow_midnight_terrestrial_time)
192
+ .apparent_equatorial_coordinates
193
+ additional_altitude = -Angle.from_degrees(
194
+ SEMIDIAMETER_VARIATION *
195
+ GeocentricParallax.angle(distance: distance).degrees
196
+ )
197
+
198
+ Events::ObservationEvents.new(
199
+ observer: observer,
200
+ date: today,
201
+ coordinates_of_the_previous_day: coordinates_of_the_previous_day,
202
+ coordinates_of_the_day: coordinates_of_the_day,
203
+ coordinates_of_the_next_day: coordinates_of_the_next_day,
204
+ additional_altitude: additional_altitude
205
+ )
206
+ end
207
+
208
+ private
209
+
210
+ def terrestrial_time
211
+ @terrestrial_time ||= begin
212
+ delta = Util::Time.terrestrial_universal_time_delta(@time)
213
+ @time + delta
214
+ end
215
+ end
216
+
217
+ def julian_date
218
+ Epoch.from_time(terrestrial_time)
219
+ end
220
+
221
+ def elapsed_centuries
222
+ (julian_date - Epoch::DEFAULT_EPOCH) / Constants::DAYS_PER_JULIAN_CENTURY
223
+ end
224
+
225
+ def sun
226
+ @sun ||= Sun.new(time: @time)
227
+ end
228
+
229
+ def sun_mean_anomaly
230
+ @sun_mean_anomaly ||= sun.mean_anomaly
231
+ end
232
+
233
+ def a1
234
+ @a1 ||= Angle.from_degrees(
235
+ (119.75 + 131.849 * elapsed_centuries) % 360
236
+ )
237
+ end
238
+
239
+ def a2
240
+ @a2 ||= Angle.from_degrees(
241
+ (53.09 + 479264.290 * elapsed_centuries) % 360
242
+ )
243
+ end
244
+
245
+ def a3
246
+ @a3 ||= Angle.from_degrees(
247
+ (313.45 + 481266.484 * elapsed_centuries) % 360
248
+ )
249
+ end
250
+
251
+ def eccentricity_correction
252
+ @eccentricity_correction ||=
253
+ 1 - 0.002516 * elapsed_centuries - 0.0000074 * elapsed_centuries**2
254
+ end
255
+
256
+ def latitude_terms
257
+ @latitude_terms ||=
258
+ Astronoby::EphemerideLunaireParisienne
259
+ .periodic_terms_for_moon_latitude
260
+ .inject(0) do |sum, terms|
261
+ value = terms[4] * Math.sin(
262
+ terms[0] * mean_elongation.radians +
263
+ terms[1] * sun_mean_anomaly.radians +
264
+ terms[2] * mean_anomaly.radians +
265
+ terms[3] * argument_of_latitude.radians
266
+ )
267
+
268
+ value *= eccentricity_correction if terms[1].abs == 1
269
+ value *= eccentricity_correction**2 if terms[1].abs == 2
270
+
271
+ sum + value
272
+ end
273
+ end
274
+
275
+ def additive_latitude_terms
276
+ @additive_latitude_terms ||=
277
+ -2235 * mean_longitude.sin +
278
+ 382 * a3.sin +
279
+ 175 * (a1 - argument_of_latitude).sin +
280
+ 175 * (a1 + argument_of_latitude).sin +
281
+ 127 * (mean_longitude - mean_anomaly).sin -
282
+ 115 * (mean_longitude + mean_anomaly).sin
283
+ end
284
+
285
+ def longitude_terms
286
+ @longitude_terms ||=
287
+ Astronoby::EphemerideLunaireParisienne
288
+ .periodic_terms_for_moon_longitude_and_distance
289
+ .inject(0) do |sum, terms|
290
+ value = terms[4] * Math.sin(
291
+ terms[0] * mean_elongation.radians +
292
+ terms[1] * sun_mean_anomaly.radians +
293
+ terms[2] * mean_anomaly.radians +
294
+ terms[3] * argument_of_latitude.radians
295
+ )
296
+
297
+ value *= eccentricity_correction if terms[1].abs == 1
298
+ value *= eccentricity_correction**2 if terms[1].abs == 2
299
+
300
+ sum + value
301
+ end
302
+ end
303
+
304
+ def additive_longitude_terms
305
+ @additive_longitude_terms ||=
306
+ 3958 * a1.sin +
307
+ 1962 * (mean_longitude - argument_of_latitude).sin +
308
+ 318 * a2.sin
309
+ end
310
+
311
+ def distance_terms
312
+ @distance_terms ||=
313
+ EphemerideLunaireParisienne
314
+ .periodic_terms_for_moon_longitude_and_distance
315
+ .inject(0) do |sum, terms|
316
+ value = terms[5] * Math.cos(
317
+ terms[0] * mean_elongation.radians +
318
+ terms[1] * sun_mean_anomaly.radians +
319
+ terms[2] * mean_anomaly.radians +
320
+ terms[3] * argument_of_latitude.radians
321
+ )
322
+
323
+ value *= eccentricity_correction if terms[1].abs == 1
324
+ value *= eccentricity_correction**2 if terms[1].abs == 2
325
+
326
+ sum + value
327
+ end
328
+ end
329
+
330
+ def nutation
331
+ @nutation ||=
332
+ Astronoby::Nutation.for_ecliptic_longitude(epoch: julian_date)
333
+ end
334
+ end
335
+ end
@@ -101,13 +101,12 @@ module Astronoby
101
101
 
102
102
  # Computes the Sun's horizontal coordinates
103
103
  #
104
- # @param latitude [Astronoby::Angle] Latitude of the observer
105
- # @param longitude [Astronoby::Angle] Longitude of the observer
104
+ # @param observer [Astronoby::Observer] Observer of the event
106
105
  # @return [Astronoby::Coordinates::Horizontal] Sun's horizontal coordinates
107
- def horizontal_coordinates(latitude:, longitude:)
106
+ def horizontal_coordinates(observer:)
108
107
  apparent_ecliptic_coordinates
109
108
  .to_apparent_equatorial(epoch: epoch)
110
- .to_horizontal(time: @time, latitude: latitude, longitude: longitude)
109
+ .to_horizontal(time: @time, observer: observer)
111
110
  end
112
111
 
113
112
  # @param observer [Astronoby::Observer] Observer of the event
@@ -156,9 +155,11 @@ module Astronoby
156
155
  Events::TwilightEvents.new(sun: self, observer: observer)
157
156
  end
158
157
 
159
- # @return [Numeric] Earth-Sun distance in meters
158
+ # @return [Astronoby::Distance] Earth-Sun distance
160
159
  def earth_distance
161
- SEMI_MAJOR_AXIS_IN_METERS / distance_angular_size_factor
160
+ Distance.from_meters(
161
+ SEMI_MAJOR_AXIS_IN_METERS / distance_angular_size_factor
162
+ )
162
163
  end
163
164
 
164
165
  # @return [Astronoby::Angle] Apparent Sun's angular size
@@ -186,6 +187,14 @@ module Astronoby
186
187
  )
187
188
  end
188
189
 
190
+ # @return [Astronoby::Angle] Sun's mean anomaly
191
+ def mean_anomaly
192
+ Angle.from_degrees(
193
+ (longitude_at_base_epoch - longitude_at_perigee).degrees %
194
+ Constants::DEGREES_PER_CIRCLE
195
+ )
196
+ end
197
+
189
198
  # @return [Astronoby::Angle] Sun's longitude at perigee
190
199
  def longitude_at_perigee
191
200
  Angle.from_degrees(
@@ -211,13 +220,6 @@ module Astronoby
211
220
  )
212
221
  end
213
222
 
214
- def mean_anomaly
215
- Angle.from_degrees(
216
- (longitude_at_base_epoch - longitude_at_perigee).degrees %
217
- Constants::DEGREES_PER_CIRCLE
218
- )
219
- end
220
-
221
223
  def days_since_epoch
222
224
  Epoch::DEFAULT_EPOCH - epoch
223
225
  end
@@ -21,5 +21,11 @@ module Astronoby
21
21
  PI_IN_DEGREES = 180.0
22
22
 
23
23
  EQUATION_OF_TIME_CONSTANT = 0.0057183
24
+
25
+ KILOMETER_IN_METERS = 1_000
26
+ ASTRONOMICAL_UNIT_IN_METERS = 149_597_870_700
27
+ EARTH_EQUATORIAL_RADIUS_IN_METERS = 6378140
28
+
29
+ EARTH_FLATTENING_CORRECTION = 0.996647
24
30
  end
25
31
  end
@@ -28,7 +28,9 @@ module Astronoby
28
28
  Angle.from_hours(ha)
29
29
  end
30
30
 
31
- def to_horizontal(time:, latitude:, longitude:)
31
+ def to_horizontal(time:, observer:)
32
+ latitude = observer.latitude
33
+ longitude = observer.longitude
32
34
  ha = @hour_angle || compute_hour_angle(time: time, longitude: longitude)
33
35
  t0 = @declination.sin * latitude.sin +
34
36
  @declination.cos * latitude.cos * ha.cos
@@ -46,8 +48,7 @@ module Astronoby
46
48
  Horizontal.new(
47
49
  azimuth: azimuth,
48
50
  altitude: altitude,
49
- latitude: latitude,
50
- longitude: longitude
51
+ observer: observer
51
52
  )
52
53
  end
53
54