astronoby 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/.standard.yml +1 -0
  4. data/CHANGELOG.md +203 -3
  5. data/README.md +69 -288
  6. data/UPGRADING.md +267 -0
  7. data/docs/README.md +196 -0
  8. data/docs/angles.md +137 -0
  9. data/docs/celestial_bodies.md +107 -0
  10. data/docs/configuration.md +98 -0
  11. data/docs/coordinates.md +167 -0
  12. data/docs/ephem.md +85 -0
  13. data/docs/equinoxes_solstices_times.md +31 -0
  14. data/docs/glossary.md +152 -0
  15. data/docs/instant.md +139 -0
  16. data/docs/moon_phases.md +79 -0
  17. data/docs/observer.md +65 -0
  18. data/docs/reference_frames.md +138 -0
  19. data/docs/rise_transit_set_times.md +119 -0
  20. data/docs/twilight_times.md +123 -0
  21. data/lib/astronoby/aberration.rb +56 -31
  22. data/lib/astronoby/angle.rb +20 -16
  23. data/lib/astronoby/angles/dms.rb +2 -2
  24. data/lib/astronoby/angles/hms.rb +2 -2
  25. data/lib/astronoby/bodies/earth.rb +62 -0
  26. data/lib/astronoby/bodies/jupiter.rb +28 -0
  27. data/lib/astronoby/bodies/mars.rb +28 -0
  28. data/lib/astronoby/bodies/mercury.rb +32 -0
  29. data/lib/astronoby/bodies/moon.rb +51 -298
  30. data/lib/astronoby/bodies/neptune.rb +32 -0
  31. data/lib/astronoby/bodies/saturn.rb +37 -0
  32. data/lib/astronoby/bodies/solar_system_body.rb +232 -0
  33. data/lib/astronoby/bodies/sun.rb +33 -214
  34. data/lib/astronoby/bodies/uranus.rb +16 -0
  35. data/lib/astronoby/bodies/venus.rb +36 -0
  36. data/lib/astronoby/cache.rb +188 -0
  37. data/lib/astronoby/configuration.rb +92 -0
  38. data/lib/astronoby/constants.rb +17 -2
  39. data/lib/astronoby/constellation.rb +12 -0
  40. data/lib/astronoby/constellations/data.rb +42 -0
  41. data/lib/astronoby/constellations/finder.rb +35 -0
  42. data/lib/astronoby/constellations/repository.rb +20 -0
  43. data/lib/astronoby/coordinates/ecliptic.rb +2 -37
  44. data/lib/astronoby/coordinates/equatorial.rb +28 -10
  45. data/lib/astronoby/coordinates/horizontal.rb +0 -46
  46. data/lib/astronoby/corrections/light_time_delay.rb +90 -0
  47. data/lib/astronoby/data/constellations/constellation_names.dat +88 -0
  48. data/lib/astronoby/data/constellations/indexed_abbreviations.dat +88 -0
  49. data/lib/astronoby/data/constellations/radec_to_index.dat +238 -0
  50. data/lib/astronoby/data/constellations/sorted_declinations.dat +202 -0
  51. data/lib/astronoby/data/constellations/sorted_right_ascensions.dat +237 -0
  52. data/lib/astronoby/deflection.rb +187 -0
  53. data/lib/astronoby/distance.rb +9 -0
  54. data/lib/astronoby/ephem.rb +39 -0
  55. data/lib/astronoby/equinox_solstice.rb +22 -19
  56. data/lib/astronoby/errors.rb +4 -0
  57. data/lib/astronoby/events/moon_phases.rb +15 -13
  58. data/lib/astronoby/events/rise_transit_set_calculator.rb +376 -0
  59. data/lib/astronoby/events/rise_transit_set_event.rb +13 -0
  60. data/lib/astronoby/events/rise_transit_set_events.rb +13 -0
  61. data/lib/astronoby/events/twilight_calculator.rb +221 -0
  62. data/lib/astronoby/events/twilight_event.rb +28 -0
  63. data/lib/astronoby/events/twilight_events.rb +22 -115
  64. data/lib/astronoby/instant.rb +176 -0
  65. data/lib/astronoby/julian_date.rb +78 -0
  66. data/lib/astronoby/mean_obliquity.rb +24 -13
  67. data/lib/astronoby/nutation.rb +235 -42
  68. data/lib/astronoby/observer.rb +55 -0
  69. data/lib/astronoby/precession.rb +102 -18
  70. data/lib/astronoby/reference_frame.rb +50 -0
  71. data/lib/astronoby/reference_frames/apparent.rb +60 -0
  72. data/lib/astronoby/reference_frames/astrometric.rb +21 -0
  73. data/lib/astronoby/reference_frames/geometric.rb +20 -0
  74. data/lib/astronoby/reference_frames/mean_of_date.rb +38 -0
  75. data/lib/astronoby/reference_frames/topocentric.rb +72 -0
  76. data/lib/astronoby/time/greenwich_sidereal_time.rb +2 -2
  77. data/lib/astronoby/true_obliquity.rb +3 -3
  78. data/lib/astronoby/util/maths.rb +70 -73
  79. data/lib/astronoby/util/time.rb +455 -32
  80. data/lib/astronoby/vector.rb +36 -0
  81. data/lib/astronoby/velocity.rb +116 -0
  82. data/lib/astronoby/version.rb +1 -1
  83. data/lib/astronoby.rb +33 -5
  84. metadata +117 -24
  85. data/.tool-versions +0 -1
  86. data/Gemfile +0 -5
  87. data/Gemfile.lock +0 -80
  88. data/benchmark/README.md +0 -131
  89. data/benchmark/benchmark.rb +0 -259
  90. data/benchmark/data/imcce.csv.zip +0 -0
  91. data/benchmark/data/sun_calc.csv.zip +0 -0
  92. data/lib/astronoby/astronomical_models/ephemeride_lunaire_parisienne.rb +0 -143
  93. data/lib/astronoby/epoch.rb +0 -22
  94. data/lib/astronoby/events/observation_events.rb +0 -285
  95. data/lib/astronoby/events/rise_transit_set_iteration.rb +0 -218
  96. data/lib/astronoby/util/astrodynamics.rb +0 -60
@@ -22,6 +22,10 @@ module Astronoby
22
22
  from_radians(radians)
23
23
  end
24
24
 
25
+ def from_degree_arcseconds(arcseconds)
26
+ from_dms(0, 0, arcseconds)
27
+ end
28
+
25
29
  def from_hours(hours)
26
30
  radians = hours * Constants::RADIAN_PER_HOUR
27
31
  from_radians(radians)
@@ -120,10 +124,10 @@ module Astronoby
120
124
  end
121
125
  alias_method :eql?, :==
122
126
 
123
- def str(format)
127
+ def str(format, precision: 4)
124
128
  case format
125
- when :dms then to_dms(degrees).format
126
- when :hms then to_hms(hours).format
129
+ when :dms then to_dms.format(precision: precision)
130
+ when :hms then to_hms.format(precision: precision)
127
131
  else
128
132
  raise UnsupportedFormatError.new(
129
133
  "Expected a format between #{FORMATS.join(", ")}, got #{format}"
@@ -131,36 +135,36 @@ module Astronoby
131
135
  end
132
136
  end
133
137
 
134
- def to_dms(deg)
135
- sign = deg.negative? ? "-" : "+"
136
- absolute_degrees = deg.abs
137
- degrees = absolute_degrees.floor
138
+ def to_dms
139
+ sign = degrees.negative? ? "-" : "+"
140
+ absolute_degrees = degrees.abs
141
+ deg = absolute_degrees.floor
138
142
  decimal_minutes = Constants::MINUTES_PER_DEGREE *
139
- (absolute_degrees - degrees)
143
+ (absolute_degrees - deg)
140
144
  absolute_decimal_minutes = (
141
- Constants::MINUTES_PER_DEGREE * (absolute_degrees - degrees)
145
+ Constants::MINUTES_PER_DEGREE * (absolute_degrees - deg)
142
146
  ).abs
143
147
  minutes = decimal_minutes.floor
144
148
  seconds = Constants::SECONDS_PER_MINUTE * (
145
149
  absolute_decimal_minutes - absolute_decimal_minutes.floor
146
150
  )
147
151
 
148
- Dms.new(sign, degrees, minutes, seconds.floor(4))
152
+ Dms.new(sign, deg, minutes, seconds)
149
153
  end
150
154
 
151
- def to_hms(hrs)
152
- absolute_hours = hrs.abs
153
- hours = absolute_hours.floor
154
- decimal_minutes = Constants::MINUTES_PER_HOUR * (absolute_hours - hours)
155
+ def to_hms
156
+ absolute_hours = hours.abs
157
+ hrs = absolute_hours.floor
158
+ decimal_minutes = Constants::MINUTES_PER_HOUR * (absolute_hours - hrs)
155
159
  absolute_decimal_minutes = (
156
- Constants::MINUTES_PER_HOUR * (absolute_hours - hours)
160
+ Constants::MINUTES_PER_HOUR * (absolute_hours - hrs)
157
161
  ).abs
158
162
  minutes = decimal_minutes.floor
159
163
  seconds = Constants::SECONDS_PER_MINUTE * (
160
164
  absolute_decimal_minutes - absolute_decimal_minutes.floor
161
165
  )
162
166
 
163
- Hms.new(hours, minutes, seconds.floor(4))
167
+ Hms.new(hrs, minutes, seconds)
164
168
  end
165
169
  end
166
170
  end
@@ -11,8 +11,8 @@ module Astronoby
11
11
  @seconds = seconds
12
12
  end
13
13
 
14
- def format
15
- "#{sign}#{degrees}° #{minutes}′ #{seconds}″"
14
+ def format(precision: 4)
15
+ "#{sign}#{degrees}° #{minutes}′ #{seconds.floor(precision)}″"
16
16
  end
17
17
  end
18
18
  end
@@ -10,8 +10,8 @@ module Astronoby
10
10
  @seconds = seconds
11
11
  end
12
12
 
13
- def format
14
- "#{hours}h #{minutes}m #{seconds}s"
13
+ def format(precision: 4)
14
+ "#{hours}h #{minutes}m #{seconds.floor(precision)}s"
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Earth < SolarSystemBody
5
+ def self.ephemeris_segments(ephem_source)
6
+ if ephem_source == ::Ephem::SPK::JPL_DE
7
+ [
8
+ [SOLAR_SYSTEM_BARYCENTER, EARTH_MOON_BARYCENTER],
9
+ [EARTH_MOON_BARYCENTER, EARTH]
10
+ ]
11
+ elsif ephem_source == ::Ephem::SPK::INPOP
12
+ [
13
+ [SOLAR_SYSTEM_BARYCENTER, EARTH]
14
+ ]
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ # Attributes that require Sun data like phase angle or magnitude are not
21
+ # applicable for Earth.
22
+ def requires_sun_data?
23
+ false
24
+ end
25
+
26
+ def compute_astrometric(_ephem)
27
+ Astrometric.new(
28
+ position: Vector[
29
+ Distance.zero,
30
+ Distance.zero,
31
+ Distance.zero
32
+ ],
33
+ velocity: Vector[
34
+ Velocity.zero,
35
+ Velocity.zero,
36
+ Velocity.zero
37
+ ],
38
+ instant: @instant,
39
+ center_identifier: EARTH,
40
+ target_body: self.class
41
+ )
42
+ end
43
+
44
+ def compute_mean_of_date(_ephem)
45
+ MeanOfDate.new(
46
+ position: Vector[
47
+ Distance.zero,
48
+ Distance.zero,
49
+ Distance.zero
50
+ ],
51
+ velocity: Vector[
52
+ Velocity.zero,
53
+ Velocity.zero,
54
+ Velocity.zero
55
+ ],
56
+ instant: @instant,
57
+ center_identifier: EARTH,
58
+ target_body: self.class
59
+ )
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Jupiter < SolarSystemBody
5
+ EQUATORIAL_RADIUS = Distance.from_meters(71_492_000)
6
+ ABSOLUTE_MAGNITUDE = -9.395
7
+
8
+ def self.ephemeris_segments(_ephem_source)
9
+ [[SOLAR_SYSTEM_BARYCENTER, JUPITER_BARYCENTER]]
10
+ end
11
+
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
15
+
16
+ private
17
+
18
+ # Source:
19
+ # Title: Computing Apparent Planetary Magnitudes for The Astronomical
20
+ # Almanac (2018)
21
+ # Authors: Anthony Mallama and James L. Hilton
22
+ def magnitude_correction_term
23
+ phase_angle_degrees = phase_angle.degrees
24
+ -3.7 * 10**-4 * phase_angle_degrees +
25
+ 6.16 * 10**-4 * phase_angle_degrees * phase_angle_degrees
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Mars < SolarSystemBody
5
+ EQUATORIAL_RADIUS = Distance.from_meters(3_396_200)
6
+ ABSOLUTE_MAGNITUDE = -1.601
7
+
8
+ def self.ephemeris_segments(_ephem_source)
9
+ [[SOLAR_SYSTEM_BARYCENTER, MARS_BARYCENTER]]
10
+ end
11
+
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
15
+
16
+ private
17
+
18
+ # Source:
19
+ # Title: Computing Apparent Planetary Magnitudes for The Astronomical
20
+ # Almanac (2018)
21
+ # Authors: Anthony Mallama and James L. Hilton
22
+ def magnitude_correction_term
23
+ phase_angle_degrees = phase_angle.degrees
24
+ 2.267 * 10**-2 * phase_angle_degrees -
25
+ 1.302 * 10**-4 * phase_angle_degrees * phase_angle_degrees
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Mercury < SolarSystemBody
5
+ EQUATORIAL_RADIUS = Distance.from_meters(2_439_700)
6
+ ABSOLUTE_MAGNITUDE = -0.613
7
+
8
+ def self.ephemeris_segments(_ephem_source)
9
+ [[SOLAR_SYSTEM_BARYCENTER, MERCURY_BARYCENTER]]
10
+ end
11
+
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
15
+
16
+ private
17
+
18
+ # Source:
19
+ # Title: Computing Apparent Planetary Magnitudes for The Astronomical
20
+ # Almanac (2018)
21
+ # Authors: Anthony Mallama and James L. Hilton
22
+ def magnitude_correction_term
23
+ phase_angle_degrees = phase_angle.degrees
24
+ 6.328 * 10**-2 * phase_angle_degrees -
25
+ 1.6336 * 10**-3 * phase_angle_degrees * phase_angle_degrees +
26
+ 3.3634 * 10**-5 * phase_angle_degrees**3 -
27
+ 3.4265 * 10**-7 * phase_angle_degrees**4 +
28
+ 1.6893 * 10**-9 * phase_angle_degrees**5 -
29
+ 3.0334 * 10**-12 * phase_angle_degrees**6
30
+ end
31
+ end
32
+ end
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Astronoby
4
- class Moon
4
+ class Moon < SolarSystemBody
5
5
  SEMIDIAMETER_VARIATION = 0.7275
6
- MEAN_GEOCENTRIC_DISTANCE = Astronoby::Distance.from_meters(385_000_560)
6
+ EQUATORIAL_RADIUS = Distance.from_meters(1_737_400)
7
+ ABSOLUTE_MAGNITUDE = 0.28
8
+
9
+ def self.ephemeris_segments(ephem_source)
10
+ if ephem_source == ::Ephem::SPK::JPL_DE
11
+ [
12
+ [SOLAR_SYSTEM_BARYCENTER, EARTH_MOON_BARYCENTER],
13
+ [EARTH_MOON_BARYCENTER, MOON]
14
+ ]
15
+ elsif ephem_source == ::Ephem::SPK::INPOP
16
+ [
17
+ [SOLAR_SYSTEM_BARYCENTER, EARTH],
18
+ [EARTH, MOON]
19
+ ]
20
+ end
21
+ end
7
22
 
8
23
  # Source:
9
24
  # Title: Astronomical Algorithms
@@ -18,323 +33,61 @@ module Astronoby
18
33
  Events::MoonPhases.phases_for(year: year, month: month)
19
34
  end
20
35
 
21
- def initialize(time:)
22
- @time = time
36
+ def self.absolute_magnitude
37
+ ABSOLUTE_MAGNITUDE
23
38
  end
24
39
 
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
40
+ # @return [Float] Phase fraction, from 0 to 1
41
+ def current_phase_fraction
42
+ mean_elongation.degrees / Constants::DEGREES_PER_CIRCLE
44
43
  end
45
44
 
45
+ private
46
+
46
47
  # Source:
47
48
  # Title: Astronomical Algorithms
48
49
  # Author: Jean Meeus
49
50
  # 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
51
+ # Chapter: 48 - Illuminated Fraction of the Moon's Disk
96
52
  def mean_elongation
97
53
  @mean_elongation ||= Angle.from_degrees(
98
54
  (
99
55
  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
56
+ 445267.1114034 * elapsed_centuries -
57
+ 0.0018819 * elapsed_centuries**2 +
58
+ elapsed_centuries**3 / 545868 -
59
+ elapsed_centuries**4 / 113065000
117
60
  ) % 360
118
61
  )
119
62
  end
120
63
 
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
- # @return [Float] Phase fraction, from 0 to 1
171
- def current_phase_fraction
172
- mean_elongation.degrees / Constants::DEGREES_PER_CIRCLE
173
- end
174
-
175
- # @param observer [Astronoby::Observer] Observer of the event
176
- # @return [Astronoby::Events::ObservationEvents] Moon's observation events
177
- def observation_events(observer:)
178
- today = @time.to_date
179
- leap_seconds = Util::Time.terrestrial_universal_time_delta(today)
180
- yesterday = today.prev_day
181
- yesterday_midnight_terrestrial_time =
182
- Time.utc(yesterday.year, yesterday.month, yesterday.day) - leap_seconds
183
- today_midnight_terrestrial_time =
184
- Time.utc(today.year, today.month, today.day) - leap_seconds
185
- tomorrow = today.next_day
186
- tomorrow_midnight_terrestrial_time =
187
- Time.utc(tomorrow.year, tomorrow.month, tomorrow.day) - leap_seconds
188
-
189
- coordinates_of_the_previous_day = self.class
190
- .new(time: yesterday_midnight_terrestrial_time)
191
- .apparent_equatorial_coordinates
192
- coordinates_of_the_day = self.class
193
- .new(time: today_midnight_terrestrial_time)
194
- .apparent_equatorial_coordinates
195
- coordinates_of_the_next_day = self.class
196
- .new(time: tomorrow_midnight_terrestrial_time)
197
- .apparent_equatorial_coordinates
198
- additional_altitude = -Angle.from_degrees(
199
- SEMIDIAMETER_VARIATION *
200
- GeocentricParallax.angle(distance: distance).degrees
201
- )
202
-
203
- Events::ObservationEvents.new(
204
- observer: observer,
205
- date: today,
206
- coordinates_of_the_previous_day: coordinates_of_the_previous_day,
207
- coordinates_of_the_day: coordinates_of_the_day,
208
- coordinates_of_the_next_day: coordinates_of_the_next_day,
209
- additional_altitude: additional_altitude
210
- )
64
+ def elapsed_centuries
65
+ (@instant.tt - JulianDate::DEFAULT_EPOCH) / Constants::DAYS_PER_JULIAN_CENTURY
211
66
  end
212
67
 
213
68
  private
214
69
 
215
- def terrestrial_time
216
- @terrestrial_time ||= begin
217
- delta = Util::Time.terrestrial_universal_time_delta(@time)
218
- @time + delta
70
+ # Source:
71
+ # Title: Computing Apparent Planetary Magnitudes for The Astronomical
72
+ # Almanac (2018)
73
+ # Authors: Anthony Mallama and James L. Hilton
74
+ def magnitude_correction_term
75
+ phase_angle_degrees = phase_angle.degrees
76
+ if phase_angle_degrees <= 150 && current_phase_fraction <= 0.5
77
+ 2.9994 * 10**-2 * phase_angle_degrees -
78
+ 1.6057 * 10**-4 * phase_angle_degrees**2 +
79
+ 3.1543 * 10**-6 * phase_angle_degrees**3 -
80
+ 2.0667 * 10**-8 * phase_angle_degrees**4 +
81
+ 6.2553 * 10**-11 * phase_angle_degrees**5
82
+ elsif phase_angle_degrees <= 150 && current_phase_fraction > 0.5
83
+ 3.3234 * 10**-2 * phase_angle_degrees -
84
+ 3.0725 * 10**-4 * phase_angle_degrees**2 +
85
+ 6.1575 * 10**-6 * phase_angle_degrees**3 -
86
+ 4.7723 * 10**-8 * phase_angle_degrees**4 +
87
+ 1.4681 * 10**-10 * phase_angle_degrees**5
88
+ else
89
+ super
219
90
  end
220
91
  end
221
-
222
- def julian_date
223
- Epoch.from_time(terrestrial_time)
224
- end
225
-
226
- def elapsed_centuries
227
- (julian_date - Epoch::DEFAULT_EPOCH) / Constants::DAYS_PER_JULIAN_CENTURY
228
- end
229
-
230
- def sun
231
- @sun ||= Sun.new(time: @time)
232
- end
233
-
234
- def sun_mean_anomaly
235
- @sun_mean_anomaly ||= sun.mean_anomaly
236
- end
237
-
238
- def a1
239
- @a1 ||= Angle.from_degrees(
240
- (119.75 + 131.849 * elapsed_centuries) % 360
241
- )
242
- end
243
-
244
- def a2
245
- @a2 ||= Angle.from_degrees(
246
- (53.09 + 479264.290 * elapsed_centuries) % 360
247
- )
248
- end
249
-
250
- def a3
251
- @a3 ||= Angle.from_degrees(
252
- (313.45 + 481266.484 * elapsed_centuries) % 360
253
- )
254
- end
255
-
256
- def eccentricity_correction
257
- @eccentricity_correction ||=
258
- 1 - 0.002516 * elapsed_centuries - 0.0000074 * elapsed_centuries**2
259
- end
260
-
261
- def latitude_terms
262
- @latitude_terms ||=
263
- Astronoby::EphemerideLunaireParisienne
264
- .periodic_terms_for_moon_latitude
265
- .inject(0) do |sum, terms|
266
- value = terms[4] * Math.sin(
267
- terms[0] * mean_elongation.radians +
268
- terms[1] * sun_mean_anomaly.radians +
269
- terms[2] * mean_anomaly.radians +
270
- terms[3] * argument_of_latitude.radians
271
- )
272
-
273
- value *= eccentricity_correction if terms[1].abs == 1
274
- value *= eccentricity_correction**2 if terms[1].abs == 2
275
-
276
- sum + value
277
- end
278
- end
279
-
280
- def additive_latitude_terms
281
- @additive_latitude_terms ||=
282
- -2235 * mean_longitude.sin +
283
- 382 * a3.sin +
284
- 175 * (a1 - argument_of_latitude).sin +
285
- 175 * (a1 + argument_of_latitude).sin +
286
- 127 * (mean_longitude - mean_anomaly).sin -
287
- 115 * (mean_longitude + mean_anomaly).sin
288
- end
289
-
290
- def longitude_terms
291
- @longitude_terms ||=
292
- Astronoby::EphemerideLunaireParisienne
293
- .periodic_terms_for_moon_longitude_and_distance
294
- .inject(0) do |sum, terms|
295
- value = terms[4] * Math.sin(
296
- terms[0] * mean_elongation.radians +
297
- terms[1] * sun_mean_anomaly.radians +
298
- terms[2] * mean_anomaly.radians +
299
- terms[3] * argument_of_latitude.radians
300
- )
301
-
302
- value *= eccentricity_correction if terms[1].abs == 1
303
- value *= eccentricity_correction**2 if terms[1].abs == 2
304
-
305
- sum + value
306
- end
307
- end
308
-
309
- def additive_longitude_terms
310
- @additive_longitude_terms ||=
311
- 3958 * a1.sin +
312
- 1962 * (mean_longitude - argument_of_latitude).sin +
313
- 318 * a2.sin
314
- end
315
-
316
- def distance_terms
317
- @distance_terms ||=
318
- EphemerideLunaireParisienne
319
- .periodic_terms_for_moon_longitude_and_distance
320
- .inject(0) do |sum, terms|
321
- value = terms[5] * Math.cos(
322
- terms[0] * mean_elongation.radians +
323
- terms[1] * sun_mean_anomaly.radians +
324
- terms[2] * mean_anomaly.radians +
325
- terms[3] * argument_of_latitude.radians
326
- )
327
-
328
- value *= eccentricity_correction if terms[1].abs == 1
329
- value *= eccentricity_correction**2 if terms[1].abs == 2
330
-
331
- sum + value
332
- end
333
- end
334
-
335
- def nutation
336
- @nutation ||=
337
- Astronoby::Nutation.for_ecliptic_longitude(epoch: julian_date)
338
- end
339
92
  end
340
93
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Neptune < SolarSystemBody
5
+ EQUATORIAL_RADIUS = Distance.from_meters(24_764_000)
6
+ ABSOLUTE_MAGNITUDE = -7.0
7
+
8
+ def self.ephemeris_segments(_ephem_source)
9
+ [[SOLAR_SYSTEM_BARYCENTER, NEPTUNE_BARYCENTER]]
10
+ end
11
+
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
15
+
16
+ private
17
+
18
+ # Source:
19
+ # Title: Computing Apparent Planetary Magnitudes for The Astronomical
20
+ # Almanac (2018)
21
+ # Authors: Anthony Mallama and James L. Hilton
22
+ def magnitude_correction_term
23
+ phase_angle_degrees = phase_angle.degrees
24
+ if phase_angle_degrees < 133 && @instant.tt > JulianDate::J2000
25
+ 7.944 * 10**-3 * phase_angle_degrees +
26
+ 9.617 * 10**-5 * phase_angle_degrees * phase_angle_degrees
27
+ else
28
+ super
29
+ end
30
+ end
31
+ end
32
+ end