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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/.standard.yml +1 -0
- data/CHANGELOG.md +203 -3
- data/README.md +69 -288
- data/UPGRADING.md +267 -0
- data/docs/README.md +196 -0
- data/docs/angles.md +137 -0
- data/docs/celestial_bodies.md +107 -0
- data/docs/configuration.md +98 -0
- data/docs/coordinates.md +167 -0
- data/docs/ephem.md +85 -0
- data/docs/equinoxes_solstices_times.md +31 -0
- data/docs/glossary.md +152 -0
- data/docs/instant.md +139 -0
- data/docs/moon_phases.md +79 -0
- data/docs/observer.md +65 -0
- data/docs/reference_frames.md +138 -0
- data/docs/rise_transit_set_times.md +119 -0
- data/docs/twilight_times.md +123 -0
- data/lib/astronoby/aberration.rb +56 -31
- data/lib/astronoby/angle.rb +20 -16
- data/lib/astronoby/angles/dms.rb +2 -2
- data/lib/astronoby/angles/hms.rb +2 -2
- data/lib/astronoby/bodies/earth.rb +62 -0
- data/lib/astronoby/bodies/jupiter.rb +28 -0
- data/lib/astronoby/bodies/mars.rb +28 -0
- data/lib/astronoby/bodies/mercury.rb +32 -0
- data/lib/astronoby/bodies/moon.rb +51 -298
- data/lib/astronoby/bodies/neptune.rb +32 -0
- data/lib/astronoby/bodies/saturn.rb +37 -0
- data/lib/astronoby/bodies/solar_system_body.rb +232 -0
- data/lib/astronoby/bodies/sun.rb +33 -214
- data/lib/astronoby/bodies/uranus.rb +16 -0
- data/lib/astronoby/bodies/venus.rb +36 -0
- data/lib/astronoby/cache.rb +188 -0
- data/lib/astronoby/configuration.rb +92 -0
- data/lib/astronoby/constants.rb +17 -2
- data/lib/astronoby/constellation.rb +12 -0
- data/lib/astronoby/constellations/data.rb +42 -0
- data/lib/astronoby/constellations/finder.rb +35 -0
- data/lib/astronoby/constellations/repository.rb +20 -0
- data/lib/astronoby/coordinates/ecliptic.rb +2 -37
- data/lib/astronoby/coordinates/equatorial.rb +28 -10
- data/lib/astronoby/coordinates/horizontal.rb +0 -46
- data/lib/astronoby/corrections/light_time_delay.rb +90 -0
- data/lib/astronoby/data/constellations/constellation_names.dat +88 -0
- data/lib/astronoby/data/constellations/indexed_abbreviations.dat +88 -0
- data/lib/astronoby/data/constellations/radec_to_index.dat +238 -0
- data/lib/astronoby/data/constellations/sorted_declinations.dat +202 -0
- data/lib/astronoby/data/constellations/sorted_right_ascensions.dat +237 -0
- data/lib/astronoby/deflection.rb +187 -0
- data/lib/astronoby/distance.rb +9 -0
- data/lib/astronoby/ephem.rb +39 -0
- data/lib/astronoby/equinox_solstice.rb +22 -19
- data/lib/astronoby/errors.rb +4 -0
- data/lib/astronoby/events/moon_phases.rb +15 -13
- data/lib/astronoby/events/rise_transit_set_calculator.rb +376 -0
- data/lib/astronoby/events/rise_transit_set_event.rb +13 -0
- data/lib/astronoby/events/rise_transit_set_events.rb +13 -0
- data/lib/astronoby/events/twilight_calculator.rb +221 -0
- data/lib/astronoby/events/twilight_event.rb +28 -0
- data/lib/astronoby/events/twilight_events.rb +22 -115
- data/lib/astronoby/instant.rb +176 -0
- data/lib/astronoby/julian_date.rb +78 -0
- data/lib/astronoby/mean_obliquity.rb +24 -13
- data/lib/astronoby/nutation.rb +235 -42
- data/lib/astronoby/observer.rb +55 -0
- data/lib/astronoby/precession.rb +102 -18
- data/lib/astronoby/reference_frame.rb +50 -0
- data/lib/astronoby/reference_frames/apparent.rb +60 -0
- data/lib/astronoby/reference_frames/astrometric.rb +21 -0
- data/lib/astronoby/reference_frames/geometric.rb +20 -0
- data/lib/astronoby/reference_frames/mean_of_date.rb +38 -0
- data/lib/astronoby/reference_frames/topocentric.rb +72 -0
- data/lib/astronoby/time/greenwich_sidereal_time.rb +2 -2
- data/lib/astronoby/true_obliquity.rb +3 -3
- data/lib/astronoby/util/maths.rb +70 -73
- data/lib/astronoby/util/time.rb +455 -32
- data/lib/astronoby/vector.rb +36 -0
- data/lib/astronoby/velocity.rb +116 -0
- data/lib/astronoby/version.rb +1 -1
- data/lib/astronoby.rb +33 -5
- metadata +117 -24
- data/.tool-versions +0 -1
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -80
- data/benchmark/README.md +0 -131
- data/benchmark/benchmark.rb +0 -259
- data/benchmark/data/imcce.csv.zip +0 -0
- data/benchmark/data/sun_calc.csv.zip +0 -0
- data/lib/astronoby/astronomical_models/ephemeride_lunaire_parisienne.rb +0 -143
- data/lib/astronoby/epoch.rb +0 -22
- data/lib/astronoby/events/observation_events.rb +0 -285
- data/lib/astronoby/events/rise_transit_set_iteration.rb +0 -218
- data/lib/astronoby/util/astrodynamics.rb +0 -60
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Astronoby
|
4
|
+
class Saturn < SolarSystemBody
|
5
|
+
EQUATORIAL_RADIUS = Distance.from_meters(60_268_000)
|
6
|
+
ABSOLUTE_MAGNITUDE = -8.914
|
7
|
+
|
8
|
+
def self.ephemeris_segments(_ephem_source)
|
9
|
+
[[SOLAR_SYSTEM_BARYCENTER, SATURN_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 <= 6
|
25
|
+
-0.036 -
|
26
|
+
3.7 * 10**-4 * phase_angle_degrees +
|
27
|
+
6.16 * 10**-4 * phase_angle_degrees * phase_angle_degrees
|
28
|
+
else
|
29
|
+
0.026 +
|
30
|
+
2.446 * 10**-4 * phase_angle_degrees +
|
31
|
+
2.672 * 10**-4 * phase_angle_degrees * phase_angle_degrees -
|
32
|
+
1.505 * 10**-6 * phase_angle_degrees**3 +
|
33
|
+
4.767 * 10**-9 * phase_angle_degrees**4
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Astronoby
|
4
|
+
class SolarSystemBody
|
5
|
+
SOLAR_SYSTEM_BARYCENTER = 0
|
6
|
+
SUN = 10
|
7
|
+
MERCURY_BARYCENTER = 1
|
8
|
+
MERCURY = 199
|
9
|
+
VENUS_BARYCENTER = 2
|
10
|
+
VENUS = 299
|
11
|
+
EARTH_MOON_BARYCENTER = 3
|
12
|
+
EARTH = 399
|
13
|
+
MOON = 301
|
14
|
+
MARS_BARYCENTER = 4
|
15
|
+
JUPITER_BARYCENTER = 5
|
16
|
+
SATURN_BARYCENTER = 6
|
17
|
+
URANUS_BARYCENTER = 7
|
18
|
+
NEPTUNE_BARYCENTER = 8
|
19
|
+
|
20
|
+
attr_reader :geometric, :instant
|
21
|
+
|
22
|
+
def self.geometric(ephem:, instant:)
|
23
|
+
compute_geometric(ephem: ephem, instant: instant)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.compute_geometric(ephem:, instant:)
|
27
|
+
segments = ephemeris_segments(ephem.type)
|
28
|
+
segment1 = segments[0]
|
29
|
+
segment2 = segments[1] if segments.size == 2
|
30
|
+
cache_key = CacheKey.generate(:geometric, instant, segment1, segment2)
|
31
|
+
|
32
|
+
Astronoby.cache.fetch(cache_key) do
|
33
|
+
state1 = ephem[*segment1].state_at(instant.tt)
|
34
|
+
|
35
|
+
if segment2
|
36
|
+
state2 = ephem[*segment2].state_at(instant.tt)
|
37
|
+
position = state1.position + state2.position
|
38
|
+
velocity = state1.velocity + state2.velocity
|
39
|
+
else
|
40
|
+
position = state1.position
|
41
|
+
velocity = state1.velocity
|
42
|
+
end
|
43
|
+
|
44
|
+
position_vector = Vector[
|
45
|
+
Distance.from_kilometers(position.x),
|
46
|
+
Distance.from_kilometers(position.y),
|
47
|
+
Distance.from_kilometers(position.z)
|
48
|
+
]
|
49
|
+
|
50
|
+
velocity_vector = Vector[
|
51
|
+
Velocity.from_kilometers_per_day(velocity.x),
|
52
|
+
Velocity.from_kilometers_per_day(velocity.y),
|
53
|
+
Velocity.from_kilometers_per_day(velocity.z)
|
54
|
+
]
|
55
|
+
|
56
|
+
Geometric.new(
|
57
|
+
position: position_vector,
|
58
|
+
velocity: velocity_vector,
|
59
|
+
instant: instant,
|
60
|
+
target_body: self
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.ephemeris_segments(_ephem_source)
|
66
|
+
raise NotImplementedError
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.absolute_magnitude
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize(ephem:, instant:)
|
74
|
+
@instant = instant
|
75
|
+
@geometric = compute_geometric(ephem)
|
76
|
+
@earth_geometric = Earth.geometric(ephem: ephem, instant: instant)
|
77
|
+
@light_time_corrected_position,
|
78
|
+
@light_time_corrected_velocity =
|
79
|
+
Correction::LightTimeDelay.compute(
|
80
|
+
center: @earth_geometric,
|
81
|
+
target: @geometric,
|
82
|
+
ephem: ephem
|
83
|
+
)
|
84
|
+
compute_sun(ephem) if requires_sun_data?
|
85
|
+
end
|
86
|
+
|
87
|
+
def astrometric
|
88
|
+
@astrometric ||= Astrometric.build_from_geometric(
|
89
|
+
instant: @instant,
|
90
|
+
earth_geometric: @earth_geometric,
|
91
|
+
light_time_corrected_position: @light_time_corrected_position,
|
92
|
+
light_time_corrected_velocity: @light_time_corrected_velocity,
|
93
|
+
target_body: self
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def mean_of_date
|
98
|
+
@mean_of_date ||= MeanOfDate.build_from_geometric(
|
99
|
+
instant: @instant,
|
100
|
+
target_geometric: @geometric,
|
101
|
+
earth_geometric: @earth_geometric,
|
102
|
+
target_body: self
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def apparent
|
107
|
+
@apparent ||= Apparent.build_from_astrometric(
|
108
|
+
instant: @instant,
|
109
|
+
target_astrometric: astrometric,
|
110
|
+
earth_geometric: @earth_geometric,
|
111
|
+
target_body: self
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
def observed_by(observer)
|
116
|
+
Topocentric.build_from_apparent(
|
117
|
+
apparent: apparent,
|
118
|
+
observer: observer,
|
119
|
+
instant: @instant,
|
120
|
+
target_body: self
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns the constellation of the body
|
125
|
+
# @return [Astronoby::Constellation, nil]
|
126
|
+
def constellation
|
127
|
+
@constellation ||= Constellations::Finder.find(
|
128
|
+
Precession.for_equatorial_coordinates(
|
129
|
+
coordinates: astrometric.equatorial,
|
130
|
+
epoch: JulianDate::B1875
|
131
|
+
)
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Source:
|
136
|
+
# Title: Astronomical Algorithms
|
137
|
+
# Author: Jean Meeus
|
138
|
+
# Edition: 2nd edition
|
139
|
+
# Chapter: 48 - Illuminated Fraction of the Moon's Disk
|
140
|
+
# @return [Astronoby::Angle, nil] Phase angle of the body
|
141
|
+
def phase_angle
|
142
|
+
return unless @sun
|
143
|
+
|
144
|
+
@phase_angle ||= begin
|
145
|
+
geocentric_elongation = Angle.acos(
|
146
|
+
@sun.apparent.equatorial.declination.sin *
|
147
|
+
apparent.equatorial.declination.sin +
|
148
|
+
@sun.apparent.equatorial.declination.cos *
|
149
|
+
apparent.equatorial.declination.cos *
|
150
|
+
(
|
151
|
+
@sun.apparent.equatorial.right_ascension -
|
152
|
+
apparent.equatorial.right_ascension
|
153
|
+
).cos
|
154
|
+
)
|
155
|
+
|
156
|
+
term1 = @sun.astrometric.distance.km * geocentric_elongation.sin
|
157
|
+
term2 = astrometric.distance.km -
|
158
|
+
@sun.astrometric.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
|
+
# Fraction between 0 and 1 of the body's disk that is illuminated.
|
166
|
+
# @return [Float, nil] Body's illuminated fraction, between 0 and 1.
|
167
|
+
def illuminated_fraction
|
168
|
+
return unless phase_angle
|
169
|
+
|
170
|
+
@illuminated_fraction ||= (1 + phase_angle.cos) / 2.0
|
171
|
+
end
|
172
|
+
|
173
|
+
# Source:
|
174
|
+
# Title: Astronomical Algorithms
|
175
|
+
# Author: Jean Meeus
|
176
|
+
# Edition: 2nd edition
|
177
|
+
# Chapter: 48 - Illuminated Fraction of the Moon's Disk
|
178
|
+
# Apparent magnitude of the body, as seen from Earth.
|
179
|
+
# @return [Float, nil] Apparent magnitude of the body.
|
180
|
+
def apparent_magnitude
|
181
|
+
return unless self.class.absolute_magnitude
|
182
|
+
|
183
|
+
@apparent_magnitude ||= begin
|
184
|
+
body_sun_distance =
|
185
|
+
(astrometric.position - @sun.astrometric.position).magnitude
|
186
|
+
self.class.absolute_magnitude +
|
187
|
+
5 * Math.log10(body_sun_distance.au * astrometric.distance.au) +
|
188
|
+
magnitude_correction_term
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# Angular diameter of the body, as seen from Earth. Based on the apparent
|
193
|
+
# position of the body.
|
194
|
+
# @return [Astronoby::Angle] Angular diameter of the body
|
195
|
+
def angular_diameter
|
196
|
+
@angular_radius ||= begin
|
197
|
+
return if apparent.position.zero?
|
198
|
+
|
199
|
+
Angle.from_radians(
|
200
|
+
Math.asin(self.class::EQUATORIAL_RADIUS.m / apparent.distance.m) * 2
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# By default, Solar System bodies expose attributes that are dependent on
|
208
|
+
# the Sun's position, such as phase angle and illuminated fraction.
|
209
|
+
# If a body does not require Sun data, it should override this method to
|
210
|
+
# return false.
|
211
|
+
def requires_sun_data?
|
212
|
+
true
|
213
|
+
end
|
214
|
+
|
215
|
+
def compute_geometric(ephem)
|
216
|
+
self.class.compute_geometric(ephem: ephem, instant: @instant)
|
217
|
+
end
|
218
|
+
|
219
|
+
def compute_sun(ephem)
|
220
|
+
@sun ||= Sun.new(instant: @instant, ephem: ephem)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Source:
|
224
|
+
# Title: Explanatory Supplement to the Astronomical Almanac
|
225
|
+
# Authors: Sean E. Urban and P. Kenneth Seidelmann
|
226
|
+
# Edition: University Science Books
|
227
|
+
# Chapter: 10.3 - Phases and Magnitudes
|
228
|
+
def magnitude_correction_term
|
229
|
+
-2.5 * Math.log10(illuminated_fraction)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
data/lib/astronoby/bodies/sun.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Astronoby
|
4
|
-
class Sun
|
5
|
-
|
6
|
-
|
7
|
-
INTERPOLATION_FACTOR = 24.07
|
4
|
+
class Sun < SolarSystemBody
|
5
|
+
EQUATORIAL_RADIUS = Distance.from_meters(695_700_000)
|
6
|
+
ABSOLUTE_MAGNITUDE = -26.74
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
ASTRONOMICAL = :astronomical
|
13
|
-
].freeze
|
14
|
-
|
15
|
-
TWILIGHT_ANGLES = {
|
16
|
-
CIVIL => Angle.from_degrees(96),
|
17
|
-
NAUTICAL => Angle.from_degrees(102),
|
18
|
-
ASTRONOMICAL => Angle.from_degrees(108)
|
19
|
-
}.freeze
|
8
|
+
def self.ephemeris_segments(_ephem_source)
|
9
|
+
[[SOLAR_SYSTEM_BARYCENTER, SUN]]
|
10
|
+
end
|
20
11
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
].freeze
|
12
|
+
def self.absolute_magnitude
|
13
|
+
ABSOLUTE_MAGNITUDE
|
14
|
+
end
|
25
15
|
|
26
|
-
|
16
|
+
# Source:
|
17
|
+
# Title: Explanatory Supplement to the Astronomical Almanac
|
18
|
+
# Authors: Sean E. Urban and P. Kenneth Seidelmann
|
19
|
+
# Edition: University Science Books
|
20
|
+
# Chapter: 10.3 - Phases and Magnitudes
|
21
|
+
# Apparent magnitude of the body, as seen from Earth.
|
22
|
+
# @return [Float] Apparent magnitude of the body.
|
23
|
+
def apparent_magnitude
|
24
|
+
@apparent_magnitude ||=
|
25
|
+
self.class.absolute_magnitude + 5 * Math.log10(astrometric.distance.au)
|
26
|
+
end
|
27
27
|
|
28
28
|
# Source:
|
29
29
|
# Title: Astronomical Algorithms
|
@@ -31,215 +31,34 @@ module Astronoby
|
|
31
31
|
# Edition: 2nd edition
|
32
32
|
# Chapter: 28 - Equation of Time
|
33
33
|
|
34
|
-
# @param date_or_time [Date, Time] Requested date
|
35
34
|
# @return [Integer] Equation of time in seconds
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
epoch = Epoch.from_time(time)
|
40
|
-
sun = new(time: time)
|
41
|
-
right_ascension = sun
|
42
|
-
.apparent_ecliptic_coordinates
|
43
|
-
.to_apparent_equatorial(epoch: epoch)
|
44
|
-
.right_ascension
|
45
|
-
t = (epoch - Epoch::J2000) / Constants::DAYS_PER_JULIAN_MILLENIA
|
35
|
+
def equation_of_time
|
36
|
+
right_ascension = apparent.equatorial.right_ascension
|
37
|
+
t = (@instant.julian_date - JulianDate::J2000) / Constants::DAYS_PER_JULIAN_MILLENIA
|
46
38
|
l0 = (280.4664567 +
|
47
39
|
360_007.6982779 * t +
|
48
40
|
0.03032028 * t**2 +
|
49
41
|
t**3 / 49_931 -
|
50
42
|
t**4 / 15_300 -
|
51
43
|
t**5 / 2_000_000) % Constants::DEGREES_PER_CIRCLE
|
52
|
-
nutation = Nutation.
|
53
|
-
obliquity = TrueObliquity.
|
44
|
+
nutation = Nutation.new(instant: instant).nutation_in_longitude
|
45
|
+
obliquity = TrueObliquity.at(@instant)
|
54
46
|
|
55
47
|
(
|
56
48
|
Angle
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
49
|
+
.from_degrees(
|
50
|
+
l0 -
|
51
|
+
Constants::EQUATION_OF_TIME_CONSTANT -
|
52
|
+
right_ascension.degrees +
|
53
|
+
nutation.degrees * obliquity.cos
|
54
|
+
).hours * Constants::SECONDS_PER_HOUR
|
63
55
|
).round
|
64
56
|
end
|
65
57
|
|
66
|
-
# Source:
|
67
|
-
# Title: Celestial Calculations
|
68
|
-
# Author: J. L. Lawrence
|
69
|
-
# Edition: MIT Press
|
70
|
-
# Chapter: 6 - The Sun
|
71
|
-
|
72
|
-
# @param time [Time] Considered time
|
73
|
-
def initialize(time:)
|
74
|
-
@time = time
|
75
|
-
end
|
76
|
-
|
77
|
-
def epoch
|
78
|
-
@epoch ||= Epoch.from_time(@time)
|
79
|
-
end
|
80
|
-
|
81
|
-
def true_ecliptic_coordinates
|
82
|
-
Coordinates::Ecliptic.new(
|
83
|
-
latitude: Angle.zero,
|
84
|
-
longitude: true_longitude
|
85
|
-
)
|
86
|
-
end
|
87
|
-
|
88
|
-
def apparent_ecliptic_coordinates
|
89
|
-
nutation = Nutation.for_ecliptic_longitude(epoch: epoch)
|
90
|
-
longitude_with_aberration = Aberration.for_ecliptic_coordinates(
|
91
|
-
coordinates: true_ecliptic_coordinates,
|
92
|
-
epoch: epoch
|
93
|
-
).longitude
|
94
|
-
apparent_longitude = nutation + longitude_with_aberration
|
95
|
-
|
96
|
-
Coordinates::Ecliptic.new(
|
97
|
-
latitude: Angle.zero,
|
98
|
-
longitude: apparent_longitude
|
99
|
-
)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Computes the Sun's horizontal coordinates
|
103
|
-
#
|
104
|
-
# @param observer [Astronoby::Observer] Observer of the event
|
105
|
-
# @return [Astronoby::Coordinates::Horizontal] Sun's horizontal coordinates
|
106
|
-
def horizontal_coordinates(observer:)
|
107
|
-
apparent_ecliptic_coordinates
|
108
|
-
.to_apparent_equatorial(epoch: epoch)
|
109
|
-
.to_horizontal(time: @time, observer: observer)
|
110
|
-
end
|
111
|
-
|
112
|
-
# @param observer [Astronoby::Observer] Observer of the event
|
113
|
-
# @return [Astronoby::Events::ObservationEvents] Sun's observation events
|
114
|
-
def observation_events(observer:)
|
115
|
-
today = @time.to_date
|
116
|
-
leap_seconds = Util::Time.terrestrial_universal_time_delta(today)
|
117
|
-
yesterday = today.prev_day
|
118
|
-
yesterday_midnight_terrestrial_time =
|
119
|
-
Time.utc(yesterday.year, yesterday.month, yesterday.day) - leap_seconds
|
120
|
-
yesterday_epoch = Epoch.from_time(yesterday_midnight_terrestrial_time)
|
121
|
-
today_midnight_terrestrial_time =
|
122
|
-
Time.utc(today.year, today.month, today.day) - leap_seconds
|
123
|
-
today_epoch = Epoch.from_time(today_midnight_terrestrial_time)
|
124
|
-
tomorrow = today.next_day
|
125
|
-
tomorrow_midnight_terrestrial_time =
|
126
|
-
Time.utc(tomorrow.year, tomorrow.month, tomorrow.day) - leap_seconds
|
127
|
-
tomorrow_epoch = Epoch.from_time(tomorrow_midnight_terrestrial_time)
|
128
|
-
|
129
|
-
coordinates_of_the_previous_day = self.class
|
130
|
-
.new(time: yesterday_midnight_terrestrial_time)
|
131
|
-
.apparent_ecliptic_coordinates
|
132
|
-
.to_apparent_equatorial(epoch: yesterday_epoch)
|
133
|
-
coordinates_of_the_day = self.class
|
134
|
-
.new(time: today_midnight_terrestrial_time)
|
135
|
-
.apparent_ecliptic_coordinates
|
136
|
-
.to_apparent_equatorial(epoch: today_epoch)
|
137
|
-
coordinates_of_the_next_day = self.class
|
138
|
-
.new(time: tomorrow_midnight_terrestrial_time)
|
139
|
-
.apparent_ecliptic_coordinates
|
140
|
-
.to_apparent_equatorial(epoch: tomorrow_epoch)
|
141
|
-
|
142
|
-
Events::ObservationEvents.new(
|
143
|
-
observer: observer,
|
144
|
-
date: today,
|
145
|
-
coordinates_of_the_previous_day: coordinates_of_the_previous_day,
|
146
|
-
coordinates_of_the_day: coordinates_of_the_day,
|
147
|
-
coordinates_of_the_next_day: coordinates_of_the_next_day,
|
148
|
-
additional_altitude: Angle.from_degrees(angular_size.degrees / 2)
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
# @param observer [Astronoby::Observer] Observer of the events
|
153
|
-
# @return [Astronoby::Events::TwilightEvents] Sun's twilight events
|
154
|
-
def twilight_events(observer:)
|
155
|
-
Events::TwilightEvents.new(sun: self, observer: observer)
|
156
|
-
end
|
157
|
-
|
158
|
-
# @return [Astronoby::Distance] Earth-Sun distance
|
159
|
-
def earth_distance
|
160
|
-
Distance.from_meters(
|
161
|
-
SEMI_MAJOR_AXIS_IN_METERS / distance_angular_size_factor
|
162
|
-
)
|
163
|
-
end
|
164
|
-
|
165
|
-
# @return [Astronoby::Angle] Apparent Sun's angular size
|
166
|
-
def angular_size
|
167
|
-
Angle.from_degrees(
|
168
|
-
ANGULAR_DIAMETER.degrees * distance_angular_size_factor
|
169
|
-
)
|
170
|
-
end
|
171
|
-
|
172
|
-
# @return [Astronoby::Angle] Sun's true anomaly
|
173
|
-
def true_anomaly
|
174
|
-
eccentric_anomaly = Util::Astrodynamics.eccentric_anomaly_newton_raphson(
|
175
|
-
mean_anomaly,
|
176
|
-
orbital_eccentricity.degrees,
|
177
|
-
2e-06,
|
178
|
-
10
|
179
|
-
)
|
180
|
-
|
181
|
-
tan = Math.sqrt(
|
182
|
-
(1 + orbital_eccentricity.degrees) / (1 - orbital_eccentricity.degrees)
|
183
|
-
) * Math.tan(eccentric_anomaly.radians / 2)
|
184
|
-
|
185
|
-
Angle.from_degrees(
|
186
|
-
(Angle.atan(tan).degrees * 2) % Constants::DEGREES_PER_CIRCLE
|
187
|
-
)
|
188
|
-
end
|
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
|
-
|
198
|
-
# @return [Astronoby::Angle] Sun's longitude at perigee
|
199
|
-
def longitude_at_perigee
|
200
|
-
Angle.from_degrees(
|
201
|
-
(281.2208444 + 1.719175 * centuries + 0.000452778 * centuries**2) %
|
202
|
-
Constants::DEGREES_PER_CIRCLE
|
203
|
-
)
|
204
|
-
end
|
205
|
-
|
206
|
-
# @return [Astronoby::Angle] Sun's orbital eccentricity
|
207
|
-
def orbital_eccentricity
|
208
|
-
Angle.from_degrees(
|
209
|
-
(0.01675104 - 0.0000418 * centuries - 0.000000126 * centuries**2) %
|
210
|
-
Constants::DEGREES_PER_CIRCLE
|
211
|
-
)
|
212
|
-
end
|
213
|
-
|
214
58
|
private
|
215
59
|
|
216
|
-
def
|
217
|
-
|
218
|
-
(true_anomaly + longitude_at_perigee).degrees %
|
219
|
-
Constants::DEGREES_PER_CIRCLE
|
220
|
-
)
|
221
|
-
end
|
222
|
-
|
223
|
-
def days_since_epoch
|
224
|
-
Epoch::DEFAULT_EPOCH - epoch
|
225
|
-
end
|
226
|
-
|
227
|
-
def centuries
|
228
|
-
@centuries ||= (epoch - Epoch::J1900) / Constants::DAYS_PER_JULIAN_CENTURY
|
229
|
-
end
|
230
|
-
|
231
|
-
def longitude_at_base_epoch
|
232
|
-
Angle.from_degrees(
|
233
|
-
(279.6966778 + 36000.76892 * centuries + 0.0003025 * centuries**2) %
|
234
|
-
Constants::DEGREES_PER_CIRCLE
|
235
|
-
)
|
236
|
-
end
|
237
|
-
|
238
|
-
def distance_angular_size_factor
|
239
|
-
term1 = 1 + orbital_eccentricity.degrees * true_anomaly.cos
|
240
|
-
term2 = 1 - orbital_eccentricity.degrees**2
|
241
|
-
|
242
|
-
term1 / term2
|
60
|
+
def requires_sun_data?
|
61
|
+
false
|
243
62
|
end
|
244
63
|
end
|
245
64
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Astronoby
|
4
|
+
class Uranus < SolarSystemBody
|
5
|
+
EQUATORIAL_RADIUS = Distance.from_meters(25_559_000)
|
6
|
+
ABSOLUTE_MAGNITUDE = -7.11
|
7
|
+
|
8
|
+
def self.ephemeris_segments(_ephem_source)
|
9
|
+
[[SOLAR_SYSTEM_BARYCENTER, URANUS_BARYCENTER]]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.absolute_magnitude
|
13
|
+
ABSOLUTE_MAGNITUDE
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Astronoby
|
4
|
+
class Venus < SolarSystemBody
|
5
|
+
EQUATORIAL_RADIUS = Distance.from_meters(6_051_800)
|
6
|
+
ABSOLUTE_MAGNITUDE = -4.384
|
7
|
+
|
8
|
+
def self.ephemeris_segments(_ephem_source)
|
9
|
+
[[SOLAR_SYSTEM_BARYCENTER, VENUS_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 < 163.7
|
25
|
+
-1.044 * 10**-3 * phase_angle_degrees +
|
26
|
+
3.687 * 10**-4 * phase_angle_degrees * phase_angle_degrees -
|
27
|
+
2.814 * 10**-6 * phase_angle_degrees**3 +
|
28
|
+
8.938 * 10**-9 * phase_angle_degrees**4
|
29
|
+
|
30
|
+
else
|
31
|
+
240.44228 - 2.81914 * phase_angle_degrees +
|
32
|
+
8.39034 * 10**-3 * phase_angle_degrees * phase_angle_degrees
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|