astronoby 0.9.0 → 0.10.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 -1
- data/CHANGELOG.md +101 -0
- data/README.md +6 -1
- data/UPGRADING.md +84 -0
- data/docs/README.md +80 -15
- data/docs/angles.md +1 -0
- data/docs/configuration.md +20 -17
- data/docs/coordinates.md +72 -12
- data/docs/deep_sky_bodies.md +1 -1
- data/docs/ephem.md +5 -2
- data/docs/equinoxes_solstices_times.md +4 -3
- data/docs/glossary.md +97 -1
- data/docs/iers.md +40 -0
- data/docs/instant.md +20 -15
- data/docs/lunar_eclipses.md +93 -0
- data/docs/lunar_observation.md +87 -0
- data/docs/moon_phases.md +4 -1
- data/docs/observer.md +20 -6
- data/docs/planetary_phenomena.md +78 -0
- data/docs/reference_frames.md +192 -34
- data/docs/rise_transit_set_times.md +6 -4
- data/docs/solar_system_bodies.md +26 -4
- data/docs/twilight_times.md +25 -21
- data/lib/astronoby/angle.rb +63 -2
- data/lib/astronoby/angles/dms.rb +18 -1
- data/lib/astronoby/angles/hms.rb +14 -1
- data/lib/astronoby/angular_velocity.rb +21 -0
- data/lib/astronoby/bodies/deep_sky_object.rb +6 -1
- data/lib/astronoby/bodies/deep_sky_object_position.rb +32 -17
- data/lib/astronoby/bodies/earth.rb +7 -44
- data/lib/astronoby/bodies/jupiter.rb +10 -0
- data/lib/astronoby/bodies/mars.rb +10 -0
- data/lib/astronoby/bodies/mercury.rb +10 -0
- data/lib/astronoby/bodies/moon.rb +158 -32
- data/lib/astronoby/bodies/neptune.rb +10 -0
- data/lib/astronoby/bodies/saturn.rb +10 -0
- data/lib/astronoby/bodies/solar_system_body.rb +240 -61
- data/lib/astronoby/bodies/sun.rb +79 -4
- data/lib/astronoby/bodies/uranus.rb +10 -0
- data/lib/astronoby/bodies/venus.rb +10 -0
- data/lib/astronoby/body.rb +6 -0
- data/lib/astronoby/center.rb +84 -0
- data/lib/astronoby/constellation.rb +9 -1
- data/lib/astronoby/coordinates/ecliptic.rb +10 -1
- data/lib/astronoby/coordinates/equatorial.rb +64 -8
- data/lib/astronoby/coordinates/geodetic.rb +102 -0
- data/lib/astronoby/coordinates/horizontal.rb +13 -1
- data/lib/astronoby/distance.rb +35 -0
- data/lib/astronoby/duration.rb +116 -0
- data/lib/astronoby/earth_rotation.rb +70 -0
- data/lib/astronoby/equinox_solstice.rb +31 -8
- data/lib/astronoby/errors.rb +11 -0
- data/lib/astronoby/events/conjunction.rb +51 -0
- data/lib/astronoby/events/conjunction_opposition_calculator.rb +84 -0
- data/lib/astronoby/events/eclipse_phase.rb +27 -0
- data/lib/astronoby/events/extremum_calculator.rb +23 -176
- data/lib/astronoby/events/greatest_elongation.rb +58 -0
- data/lib/astronoby/events/greatest_elongation_calculator.rb +56 -0
- data/lib/astronoby/events/lunar_eclipse.rb +99 -0
- data/lib/astronoby/events/lunar_eclipse_calculator.rb +285 -0
- data/lib/astronoby/events/opposition.rb +19 -0
- data/lib/astronoby/events/rise_transit_set_event.rb +12 -1
- data/lib/astronoby/events/rise_transit_set_events.rb +12 -1
- data/lib/astronoby/events/twilight_event.rb +24 -6
- data/lib/astronoby/events/twilight_events.rb +26 -6
- data/lib/astronoby/extremum_finder.rb +148 -0
- data/lib/astronoby/instant.rb +10 -7
- data/lib/astronoby/libration.rb +25 -0
- data/lib/astronoby/mean_obliquity.rb +8 -0
- data/lib/astronoby/moon_orientation_ephemeris.rb +69 -0
- data/lib/astronoby/moon_physical_ephemeris.rb +263 -0
- data/lib/astronoby/nutation.rb +10 -20
- data/lib/astronoby/observer.rb +67 -49
- data/lib/astronoby/orientation.rb +107 -0
- data/lib/astronoby/position.rb +16 -0
- data/lib/astronoby/precession.rb +61 -60
- data/lib/astronoby/reference_frame.rb +73 -7
- data/lib/astronoby/reference_frames/apparent.rb +26 -7
- data/lib/astronoby/reference_frames/astrometric.rb +14 -1
- data/lib/astronoby/reference_frames/geometric.rb +7 -1
- data/lib/astronoby/reference_frames/mean_of_date.rb +13 -1
- data/lib/astronoby/reference_frames/teme.rb +153 -0
- data/lib/astronoby/reference_frames/topocentric.rb +30 -4
- data/lib/astronoby/refraction.rb +26 -5
- data/lib/astronoby/root_finder.rb +83 -0
- data/lib/astronoby/rotation.rb +49 -0
- data/lib/astronoby/time/greenwich_apparent_sidereal_time.rb +9 -0
- data/lib/astronoby/time/greenwich_mean_sidereal_time.rb +42 -5
- data/lib/astronoby/time/greenwich_sidereal_time.rb +21 -0
- data/lib/astronoby/time/local_apparent_sidereal_time.rb +21 -0
- data/lib/astronoby/time/local_mean_sidereal_time.rb +21 -0
- data/lib/astronoby/time/local_sidereal_time.rb +24 -0
- data/lib/astronoby/time/sidereal_time.rb +23 -1
- data/lib/astronoby/true_obliquity.rb +4 -0
- data/lib/astronoby/util/maths.rb +8 -0
- data/lib/astronoby/util/time.rb +10 -485
- data/lib/astronoby/vector.rb +10 -0
- data/lib/astronoby/velocity.rb +39 -0
- data/lib/astronoby/version.rb +1 -1
- data/lib/astronoby.rb +22 -0
- metadata +45 -5
data/lib/astronoby/angle.rb
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents an angle with radians as its internal representation.
|
|
5
|
+
# Provides conversions between radians, degrees, hours, and sexagesimal
|
|
6
|
+
# formats (DMS and HMS), as well as trigonometric operations.
|
|
7
|
+
#
|
|
8
|
+
# @example Create an angle from degrees
|
|
9
|
+
# angle = Astronoby::Angle.from_degrees(180)
|
|
10
|
+
# angle.radians # => Math::PI
|
|
11
|
+
#
|
|
12
|
+
# @example Create an angle from hours, minutes, seconds
|
|
13
|
+
# angle = Astronoby::Angle.from_hms(12, 30, 0)
|
|
14
|
+
#
|
|
4
15
|
class Angle
|
|
5
16
|
include Comparable
|
|
6
17
|
|
|
@@ -8,29 +19,42 @@ module Astronoby
|
|
|
8
19
|
FORMATS = %i[dms hms].freeze
|
|
9
20
|
|
|
10
21
|
class << self
|
|
22
|
+
# @return [Astronoby::Angle] a zero angle
|
|
11
23
|
def zero
|
|
12
24
|
new(0)
|
|
13
25
|
end
|
|
14
26
|
|
|
27
|
+
# @param radians [Numeric] the angle in radians
|
|
28
|
+
# @return [Astronoby::Angle] a new Angle, normalized to (-2π, 2π)
|
|
15
29
|
def from_radians(radians)
|
|
16
30
|
normalized_radians = radians.remainder(Constants::RADIANS_PER_CIRCLE)
|
|
17
31
|
new(normalized_radians)
|
|
18
32
|
end
|
|
19
33
|
|
|
34
|
+
# @param degrees [Numeric] the angle in degrees
|
|
35
|
+
# @return [Astronoby::Angle] a new Angle
|
|
20
36
|
def from_degrees(degrees)
|
|
21
37
|
radians = degrees / Constants::PI_IN_DEGREES * Math::PI
|
|
22
38
|
from_radians(radians)
|
|
23
39
|
end
|
|
24
40
|
|
|
41
|
+
# @param arcseconds [Numeric] the angle in arcseconds
|
|
42
|
+
# @return [Astronoby::Angle] a new Angle
|
|
25
43
|
def from_degree_arcseconds(arcseconds)
|
|
26
44
|
from_dms(0, 0, arcseconds)
|
|
27
45
|
end
|
|
28
46
|
|
|
47
|
+
# @param hours [Numeric] the angle in hour-angle hours
|
|
48
|
+
# @return [Astronoby::Angle] a new Angle
|
|
29
49
|
def from_hours(hours)
|
|
30
50
|
radians = hours * Constants::RADIAN_PER_HOUR
|
|
31
51
|
from_radians(radians)
|
|
32
52
|
end
|
|
33
53
|
|
|
54
|
+
# @param hour [Numeric] hours component
|
|
55
|
+
# @param minute [Numeric] minutes component
|
|
56
|
+
# @param second [Numeric] seconds component
|
|
57
|
+
# @return [Astronoby::Angle] a new Angle
|
|
34
58
|
def from_hms(hour, minute, second)
|
|
35
59
|
hours = hour +
|
|
36
60
|
minute / Constants::MINUTES_PER_HOUR +
|
|
@@ -38,89 +62,118 @@ module Astronoby
|
|
|
38
62
|
from_hours(hours)
|
|
39
63
|
end
|
|
40
64
|
|
|
65
|
+
# @param degree [Numeric] degrees component (sign determines overall sign)
|
|
66
|
+
# @param minute [Numeric] arcminutes component
|
|
67
|
+
# @param second [Numeric] arcseconds component
|
|
68
|
+
# @return [Astronoby::Angle] a new Angle
|
|
41
69
|
def from_dms(degree, minute, second)
|
|
42
70
|
sign = degree.negative? ? -1 : 1
|
|
43
71
|
degrees = degree.abs +
|
|
44
|
-
minute / Constants::
|
|
45
|
-
second / Constants::
|
|
72
|
+
minute / Constants::ARCMINUTES_PER_DEGREE +
|
|
73
|
+
second / Constants::ARCSECONDS_PER_DEGREE
|
|
46
74
|
from_degrees(sign * degrees)
|
|
47
75
|
end
|
|
48
76
|
|
|
77
|
+
# @param ratio [Numeric] the sine value (-1..1)
|
|
78
|
+
# @return [Astronoby::Angle] the arcsine
|
|
49
79
|
def asin(ratio)
|
|
50
80
|
radians = Math.asin(ratio)
|
|
51
81
|
from_radians(radians)
|
|
52
82
|
end
|
|
53
83
|
|
|
84
|
+
# @param ratio [Numeric] the cosine value (-1..1)
|
|
85
|
+
# @return [Astronoby::Angle] the arccosine
|
|
54
86
|
def acos(ratio)
|
|
55
87
|
radians = Math.acos(ratio)
|
|
56
88
|
from_radians(radians)
|
|
57
89
|
end
|
|
58
90
|
|
|
91
|
+
# @param ratio [Numeric] the tangent value
|
|
92
|
+
# @return [Astronoby::Angle] the arctangent
|
|
59
93
|
def atan(ratio)
|
|
60
94
|
radians = Math.atan(ratio)
|
|
61
95
|
from_radians(radians)
|
|
62
96
|
end
|
|
63
97
|
end
|
|
64
98
|
|
|
99
|
+
# @return [Numeric] the angle in radians
|
|
65
100
|
attr_reader :radians
|
|
66
101
|
|
|
102
|
+
# @param radians [Numeric] the angle in radians
|
|
67
103
|
def initialize(radians)
|
|
68
104
|
@radians = radians
|
|
69
105
|
freeze
|
|
70
106
|
end
|
|
71
107
|
|
|
108
|
+
# @return [Float] the angle in degrees
|
|
72
109
|
def degrees
|
|
73
110
|
@radians * Constants::PI_IN_DEGREES / Math::PI
|
|
74
111
|
end
|
|
75
112
|
|
|
113
|
+
# @return [Float] the angle in milliarcseconds
|
|
76
114
|
def degree_milliarcseconds
|
|
77
115
|
degrees * Constants::MILLIARCSECONDS_PER_DEGREE
|
|
78
116
|
end
|
|
79
117
|
|
|
118
|
+
# @return [Float] the angle in hour-angle hours
|
|
80
119
|
def hours
|
|
81
120
|
@radians / Constants::RADIAN_PER_HOUR
|
|
82
121
|
end
|
|
83
122
|
|
|
123
|
+
# @param other [Astronoby::Angle] angle to add
|
|
124
|
+
# @return [Astronoby::Angle] the sum
|
|
84
125
|
def +(other)
|
|
85
126
|
self.class.from_radians(radians + other.radians)
|
|
86
127
|
end
|
|
87
128
|
|
|
129
|
+
# @param other [Astronoby::Angle] angle to subtract
|
|
130
|
+
# @return [Astronoby::Angle] the difference
|
|
88
131
|
def -(other)
|
|
89
132
|
self.class.from_radians(@radians - other.radians)
|
|
90
133
|
end
|
|
91
134
|
|
|
135
|
+
# @return [Astronoby::Angle] the negated angle
|
|
92
136
|
def -@
|
|
93
137
|
self.class.from_radians(-@radians)
|
|
94
138
|
end
|
|
95
139
|
|
|
140
|
+
# @return [Float] the sine of the angle
|
|
96
141
|
def sin
|
|
97
142
|
Math.sin(radians)
|
|
98
143
|
end
|
|
99
144
|
|
|
145
|
+
# @return [Float] the cosine of the angle
|
|
100
146
|
def cos
|
|
101
147
|
Math.cos(radians)
|
|
102
148
|
end
|
|
103
149
|
|
|
150
|
+
# @return [Float] the tangent of the angle
|
|
104
151
|
def tan
|
|
105
152
|
Math.tan(radians)
|
|
106
153
|
end
|
|
107
154
|
|
|
155
|
+
# @return [Boolean] true if the angle is positive
|
|
108
156
|
def positive?
|
|
109
157
|
radians > 0
|
|
110
158
|
end
|
|
111
159
|
|
|
160
|
+
# @return [Boolean] true if the angle is negative
|
|
112
161
|
def negative?
|
|
113
162
|
radians < 0
|
|
114
163
|
end
|
|
115
164
|
|
|
165
|
+
# @return [Boolean] true if the angle is zero
|
|
116
166
|
def zero?
|
|
117
167
|
radians.zero?
|
|
118
168
|
end
|
|
119
169
|
|
|
170
|
+
# @return [Integer] hash value
|
|
120
171
|
def hash
|
|
121
172
|
[radians, self.class].hash
|
|
122
173
|
end
|
|
123
174
|
|
|
175
|
+
# @param other [Astronoby::Angle] angle to compare with
|
|
176
|
+
# @return [Integer, nil] -1, 0, or 1; nil if not comparable
|
|
124
177
|
def <=>(other)
|
|
125
178
|
return unless other.is_a?(self.class)
|
|
126
179
|
|
|
@@ -128,6 +181,12 @@ module Astronoby
|
|
|
128
181
|
end
|
|
129
182
|
alias_method :eql?, :==
|
|
130
183
|
|
|
184
|
+
# Formats the angle as a string in the given format.
|
|
185
|
+
#
|
|
186
|
+
# @param format [Symbol] :dms or :hms
|
|
187
|
+
# @param precision [Integer] decimal places for seconds
|
|
188
|
+
# @return [String] the formatted angle
|
|
189
|
+
# @raise [Astronoby::UnsupportedFormatError] if format is not :dms or :hms
|
|
131
190
|
def str(format, precision: 4)
|
|
132
191
|
case format
|
|
133
192
|
when :dms then to_dms.format(precision: precision)
|
|
@@ -139,6 +198,7 @@ module Astronoby
|
|
|
139
198
|
end
|
|
140
199
|
end
|
|
141
200
|
|
|
201
|
+
# @return [Astronoby::Dms] the angle in degrees, arcminutes, arcseconds
|
|
142
202
|
def to_dms
|
|
143
203
|
sign = degrees.negative? ? "-" : "+"
|
|
144
204
|
absolute_degrees = degrees.abs
|
|
@@ -156,6 +216,7 @@ module Astronoby
|
|
|
156
216
|
Dms.new(sign, deg, minutes, seconds)
|
|
157
217
|
end
|
|
158
218
|
|
|
219
|
+
# @return [Astronoby::Hms] the angle in hours, minutes, seconds
|
|
159
220
|
def to_hms
|
|
160
221
|
absolute_hours = hours.abs
|
|
161
222
|
hrs = absolute_hours.floor
|
data/lib/astronoby/angles/dms.rb
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents an angle in degrees, arcminutes, arcseconds (DMS) notation.
|
|
4
5
|
class Dms
|
|
5
|
-
|
|
6
|
+
# @return [String] "+" or "-"
|
|
7
|
+
attr_reader :sign
|
|
6
8
|
|
|
9
|
+
# @return [Integer] degrees component
|
|
10
|
+
attr_reader :degrees
|
|
11
|
+
|
|
12
|
+
# @return [Integer] arcminutes component
|
|
13
|
+
attr_reader :minutes
|
|
14
|
+
|
|
15
|
+
# @return [Float] arcseconds component
|
|
16
|
+
attr_reader :seconds
|
|
17
|
+
|
|
18
|
+
# @param sign [String] "+" or "-"
|
|
19
|
+
# @param degrees [Integer] degrees component
|
|
20
|
+
# @param minutes [Integer] arcminutes component
|
|
21
|
+
# @param seconds [Float] arcseconds component
|
|
7
22
|
def initialize(sign, degrees, minutes, seconds)
|
|
8
23
|
@sign = sign
|
|
9
24
|
@degrees = degrees
|
|
@@ -11,6 +26,8 @@ module Astronoby
|
|
|
11
26
|
@seconds = seconds
|
|
12
27
|
end
|
|
13
28
|
|
|
29
|
+
# @param precision [Integer] decimal places for the seconds component
|
|
30
|
+
# @return [String] the formatted DMS string (e.g., "+45° 30′ 15.0000″")
|
|
14
31
|
def format(precision: 4)
|
|
15
32
|
"#{sign}#{degrees}° #{minutes}′ #{seconds.floor(precision)}″"
|
|
16
33
|
end
|
data/lib/astronoby/angles/hms.rb
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents an angle in hours, minutes, seconds (HMS) notation.
|
|
4
5
|
class Hms
|
|
5
|
-
|
|
6
|
+
# @return [Integer] hours component
|
|
7
|
+
attr_reader :hours
|
|
6
8
|
|
|
9
|
+
# @return [Integer] minutes component
|
|
10
|
+
attr_reader :minutes
|
|
11
|
+
|
|
12
|
+
# @return [Float] seconds component
|
|
13
|
+
attr_reader :seconds
|
|
14
|
+
|
|
15
|
+
# @param hours [Integer] hours component
|
|
16
|
+
# @param minutes [Integer] minutes component
|
|
17
|
+
# @param seconds [Float] seconds component
|
|
7
18
|
def initialize(hours, minutes, seconds)
|
|
8
19
|
@hours = hours
|
|
9
20
|
@minutes = minutes
|
|
10
21
|
@seconds = seconds
|
|
11
22
|
end
|
|
12
23
|
|
|
24
|
+
# @param precision [Integer] decimal places for the seconds component
|
|
25
|
+
# @return [String] the formatted HMS string (e.g., "12h 30m 45.0000s")
|
|
13
26
|
def format(precision: 4)
|
|
14
27
|
"#{hours}h #{minutes}m #{seconds.floor(precision)}s"
|
|
15
28
|
end
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents an angular velocity with radians per second as its internal
|
|
5
|
+
# representation. Used primarily for stellar proper motion.
|
|
4
6
|
class AngularVelocity
|
|
5
7
|
include Comparable
|
|
6
8
|
|
|
7
9
|
class << self
|
|
10
|
+
# @return [Astronoby::AngularVelocity] a zero angular velocity
|
|
8
11
|
def zero
|
|
9
12
|
new(0)
|
|
10
13
|
end
|
|
11
14
|
|
|
15
|
+
# @param radians_per_second [Numeric] the angular velocity in rad/s
|
|
16
|
+
# @return [Astronoby::AngularVelocity] a new AngularVelocity
|
|
12
17
|
def from_radians_per_second(radians_per_second)
|
|
13
18
|
new(radians_per_second)
|
|
14
19
|
end
|
|
15
20
|
|
|
21
|
+
# @param mas_per_year [Numeric] the angular velocity in mas/yr
|
|
22
|
+
# @return [Astronoby::AngularVelocity] a new AngularVelocity
|
|
16
23
|
def from_milliarcseconds_per_year(mas_per_year)
|
|
17
24
|
angle = Angle.from_degree_arcseconds(mas_per_year / 1000.0)
|
|
18
25
|
radians_per_second = angle.radians / Constants::SECONDS_PER_JULIAN_YEAR
|
|
@@ -20,52 +27,66 @@ module Astronoby
|
|
|
20
27
|
end
|
|
21
28
|
end
|
|
22
29
|
|
|
30
|
+
# @return [Numeric] the angular velocity in radians per second
|
|
23
31
|
attr_reader :radians_per_second
|
|
24
32
|
alias_method :rps, :radians_per_second
|
|
25
33
|
|
|
34
|
+
# @param radians_per_second [Numeric] the angular velocity in rad/s
|
|
26
35
|
def initialize(radians_per_second)
|
|
27
36
|
@radians_per_second = radians_per_second
|
|
28
37
|
freeze
|
|
29
38
|
end
|
|
30
39
|
|
|
40
|
+
# @return [Float] the angular velocity in milliarcseconds per year
|
|
31
41
|
def milliarcseconds_per_year
|
|
32
42
|
angle = Angle.from_radians(@radians_per_second)
|
|
33
43
|
angle.degree_milliarcseconds * Constants::SECONDS_PER_JULIAN_YEAR
|
|
34
44
|
end
|
|
35
45
|
alias_method :mas_per_year, :milliarcseconds_per_year
|
|
36
46
|
|
|
47
|
+
# @param other [Astronoby::AngularVelocity] angular velocity to add
|
|
48
|
+
# @return [Astronoby::AngularVelocity] the sum
|
|
37
49
|
def +(other)
|
|
38
50
|
self.class.from_radians_per_second(
|
|
39
51
|
@radians_per_second + other.radians_per_second
|
|
40
52
|
)
|
|
41
53
|
end
|
|
42
54
|
|
|
55
|
+
# @param other [Astronoby::AngularVelocity] angular velocity to subtract
|
|
56
|
+
# @return [Astronoby::AngularVelocity] the difference
|
|
43
57
|
def -(other)
|
|
44
58
|
self.class.from_radians_per_second(
|
|
45
59
|
@radians_per_second - other.radians_per_second
|
|
46
60
|
)
|
|
47
61
|
end
|
|
48
62
|
|
|
63
|
+
# @return [Astronoby::AngularVelocity] the negated angular velocity
|
|
49
64
|
def -@
|
|
50
65
|
self.class.from_radians_per_second(-@radians_per_second)
|
|
51
66
|
end
|
|
52
67
|
|
|
68
|
+
# @return [Boolean] true if the angular velocity is positive
|
|
53
69
|
def positive?
|
|
54
70
|
@radians_per_second > 0
|
|
55
71
|
end
|
|
56
72
|
|
|
73
|
+
# @return [Boolean] true if the angular velocity is negative
|
|
57
74
|
def negative?
|
|
58
75
|
@radians_per_second < 0
|
|
59
76
|
end
|
|
60
77
|
|
|
78
|
+
# @return [Boolean] true if the angular velocity is zero
|
|
61
79
|
def zero?
|
|
62
80
|
@radians_per_second.zero?
|
|
63
81
|
end
|
|
64
82
|
|
|
83
|
+
# @return [Integer] hash value
|
|
65
84
|
def hash
|
|
66
85
|
[@radians_per_second, self.class].hash
|
|
67
86
|
end
|
|
68
87
|
|
|
88
|
+
# @param other [Astronoby::AngularVelocity] angular velocity to compare with
|
|
89
|
+
# @return [Integer, nil] -1, 0, or 1; nil if not comparable
|
|
69
90
|
def <=>(other)
|
|
70
91
|
return unless other.is_a?(self.class)
|
|
71
92
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents a deep-sky object (star, galaxy, nebula, etc.) with optional
|
|
5
|
+
# proper motion and parallax data.
|
|
4
6
|
class DeepSkyObject
|
|
7
|
+
include Body
|
|
8
|
+
|
|
5
9
|
# @param equatorial_coordinates [Astronoby::Coordinates::Equatorial]
|
|
6
10
|
# Equatorial coordinates at epoch J2000.0
|
|
7
11
|
# @param proper_motion_ra [Astronoby::AngularVelocity, nil] Proper motion in
|
|
@@ -37,7 +41,8 @@ module Astronoby
|
|
|
37
41
|
proper_motion_ra: @proper_motion_ra,
|
|
38
42
|
proper_motion_dec: @proper_motion_dec,
|
|
39
43
|
parallax: @parallax,
|
|
40
|
-
radial_velocity: @radial_velocity
|
|
44
|
+
radial_velocity: @radial_velocity,
|
|
45
|
+
deep_sky_object: self
|
|
41
46
|
)
|
|
42
47
|
end
|
|
43
48
|
end
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents the computed position of a deep-sky object at a specific
|
|
5
|
+
# instant, providing astrometric, apparent, and topocentric reference frames.
|
|
4
6
|
class DeepSkyObjectPosition
|
|
7
|
+
include Position
|
|
8
|
+
|
|
5
9
|
DEFAULT_DISTANCE = Distance.from_parsecs(1e9)
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
# @return [Astronoby::Instant] the time instant
|
|
12
|
+
attr_reader :instant
|
|
13
|
+
|
|
14
|
+
# @return [Astronoby::Apparent] the apparent reference frame
|
|
15
|
+
attr_reader :apparent
|
|
16
|
+
|
|
17
|
+
# @return [Astronoby::DeepSkyObject, nil] the body definition
|
|
18
|
+
attr_reader :body
|
|
8
19
|
|
|
9
20
|
# @param instant [Astronoby::Instant] Instant of the observation
|
|
10
21
|
# @param equatorial_coordinates [Astronoby::Coordinates::Equatorial]
|
|
11
22
|
# Equatorial coordinates at epoch J2000.0
|
|
23
|
+
# @param ephem [::Ephem::SPK, nil] Ephemeris data source for Earth position
|
|
12
24
|
# @param proper_motion_ra [Astronoby::AngularVelocity, nil] Proper motion in
|
|
13
25
|
# right ascension
|
|
14
26
|
# @param proper_motion_dec [Astronoby::AngularVelocity, nil] Proper motion
|
|
15
27
|
# in declination
|
|
16
28
|
# @param parallax [Astronoby::Angle, nil] Parallax angle
|
|
17
29
|
# @param radial_velocity [Astronoby::Velocity, nil] Radial velocity
|
|
30
|
+
# @param deep_sky_object [Astronoby::DeepSkyObject, nil] the body definition
|
|
18
31
|
def initialize(
|
|
19
32
|
instant:,
|
|
20
33
|
equatorial_coordinates:,
|
|
@@ -22,7 +35,8 @@ module Astronoby
|
|
|
22
35
|
proper_motion_ra: nil,
|
|
23
36
|
proper_motion_dec: nil,
|
|
24
37
|
parallax: nil,
|
|
25
|
-
radial_velocity: nil
|
|
38
|
+
radial_velocity: nil,
|
|
39
|
+
deep_sky_object: nil
|
|
26
40
|
)
|
|
27
41
|
@instant = instant
|
|
28
42
|
@initial_equatorial_coordinates = equatorial_coordinates
|
|
@@ -30,6 +44,7 @@ module Astronoby
|
|
|
30
44
|
@proper_motion_dec = proper_motion_dec
|
|
31
45
|
@parallax = parallax
|
|
32
46
|
@radial_velocity = radial_velocity
|
|
47
|
+
@body = deep_sky_object
|
|
33
48
|
if ephem
|
|
34
49
|
@earth_geometric = Earth.geometric(ephem: ephem, instant: @instant)
|
|
35
50
|
end
|
|
@@ -42,24 +57,24 @@ module Astronoby
|
|
|
42
57
|
instant: @instant,
|
|
43
58
|
position: astrometric_position,
|
|
44
59
|
velocity: astrometric_velocity,
|
|
45
|
-
|
|
46
|
-
target_body:
|
|
47
|
-
)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def observed_by(observer)
|
|
51
|
-
Topocentric.build_from_apparent(
|
|
52
|
-
apparent: @apparent,
|
|
53
|
-
observer: observer,
|
|
54
|
-
instant: @instant,
|
|
55
|
-
target_body: self
|
|
60
|
+
center: Center.geocentric,
|
|
61
|
+
target_body: body
|
|
56
62
|
)
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
private
|
|
60
66
|
|
|
61
67
|
def astrometric_position
|
|
62
|
-
@astrometric_position ||=
|
|
68
|
+
@astrometric_position ||=
|
|
69
|
+
if @earth_geometric
|
|
70
|
+
barycentric_position - @earth_geometric.position
|
|
71
|
+
else
|
|
72
|
+
barycentric_position
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def barycentric_position
|
|
77
|
+
if use_stellar_propagation?
|
|
63
78
|
stellar_propagation.position
|
|
64
79
|
else
|
|
65
80
|
astronomical_distance = DEFAULT_DISTANCE.meters
|
|
@@ -103,7 +118,7 @@ module Astronoby
|
|
|
103
118
|
instant: @instant,
|
|
104
119
|
target_astrometric: astrometric,
|
|
105
120
|
earth_geometric: @earth_geometric,
|
|
106
|
-
target_body:
|
|
121
|
+
target_body: body
|
|
107
122
|
)
|
|
108
123
|
else
|
|
109
124
|
precession_matrix = Precession.matrix_for(@instant)
|
|
@@ -118,8 +133,8 @@ module Astronoby
|
|
|
118
133
|
position: corrected_position,
|
|
119
134
|
velocity: corrected_velocity,
|
|
120
135
|
instant: @instant,
|
|
121
|
-
|
|
122
|
-
target_body:
|
|
136
|
+
center: Center.geocentric,
|
|
137
|
+
target_body: body
|
|
123
138
|
)
|
|
124
139
|
end
|
|
125
140
|
end
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents the Earth. Provides ephemeris segments for computing Earth's
|
|
5
|
+
# geometric position.
|
|
4
6
|
class Earth < SolarSystemBody
|
|
7
|
+
ORBITAL_PERIOD = 365.256
|
|
8
|
+
|
|
9
|
+
# @param ephem_source [Symbol] the ephemeris source type
|
|
10
|
+
# @return [Array<Array>] ephemeris segment identifiers
|
|
5
11
|
def self.ephemeris_segments(ephem_source)
|
|
6
12
|
if ephem_source == ::Ephem::SPK::JPL_DE
|
|
7
13
|
[
|
|
@@ -15,52 +21,9 @@ module Astronoby
|
|
|
15
21
|
end
|
|
16
22
|
end
|
|
17
23
|
|
|
24
|
+
# @return [nil] Earth has no phase angle as seen from itself
|
|
18
25
|
def phase_angle
|
|
19
26
|
nil
|
|
20
27
|
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
# Attributes that require Sun data like phase angle or magnitude are not
|
|
25
|
-
# applicable for Earth.
|
|
26
|
-
def requires_sun_data?
|
|
27
|
-
true
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def compute_astrometric(_ephem)
|
|
31
|
-
Astrometric.new(
|
|
32
|
-
position: Vector[
|
|
33
|
-
Distance.zero,
|
|
34
|
-
Distance.zero,
|
|
35
|
-
Distance.zero
|
|
36
|
-
],
|
|
37
|
-
velocity: Vector[
|
|
38
|
-
Velocity.zero,
|
|
39
|
-
Velocity.zero,
|
|
40
|
-
Velocity.zero
|
|
41
|
-
],
|
|
42
|
-
instant: @instant,
|
|
43
|
-
center_identifier: EARTH,
|
|
44
|
-
target_body: self.class
|
|
45
|
-
)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def compute_mean_of_date(_ephem)
|
|
49
|
-
MeanOfDate.new(
|
|
50
|
-
position: Vector[
|
|
51
|
-
Distance.zero,
|
|
52
|
-
Distance.zero,
|
|
53
|
-
Distance.zero
|
|
54
|
-
],
|
|
55
|
-
velocity: Vector[
|
|
56
|
-
Velocity.zero,
|
|
57
|
-
Velocity.zero,
|
|
58
|
-
Velocity.zero
|
|
59
|
-
],
|
|
60
|
-
instant: @instant,
|
|
61
|
-
center_identifier: EARTH,
|
|
62
|
-
target_body: self.class
|
|
63
|
-
)
|
|
64
|
-
end
|
|
65
28
|
end
|
|
66
29
|
end
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents Jupiter.
|
|
4
5
|
class Jupiter < SolarSystemBody
|
|
5
6
|
EQUATORIAL_RADIUS = Distance.from_meters(71_492_000)
|
|
6
7
|
ABSOLUTE_MAGNITUDE = -9.395
|
|
8
|
+
ORBITAL_PERIOD = 4332.59
|
|
7
9
|
|
|
10
|
+
# @return [Boolean] true; Jupiter is a superior planet
|
|
11
|
+
def self.superior_planet?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param _ephem_source [Symbol] the ephemeris source type
|
|
16
|
+
# @return [Array<Array>] ephemeris segment identifiers
|
|
8
17
|
def self.ephemeris_segments(_ephem_source)
|
|
9
18
|
[[SOLAR_SYSTEM_BARYCENTER, JUPITER_BARYCENTER]]
|
|
10
19
|
end
|
|
11
20
|
|
|
21
|
+
# @return [Float] absolute magnitude
|
|
12
22
|
def self.absolute_magnitude
|
|
13
23
|
ABSOLUTE_MAGNITUDE
|
|
14
24
|
end
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents Mars.
|
|
4
5
|
class Mars < SolarSystemBody
|
|
5
6
|
EQUATORIAL_RADIUS = Distance.from_meters(3_396_200)
|
|
6
7
|
ABSOLUTE_MAGNITUDE = -1.601
|
|
8
|
+
ORBITAL_PERIOD = 686.98
|
|
7
9
|
|
|
10
|
+
# @return [Boolean] true; Mars is a superior planet
|
|
11
|
+
def self.superior_planet?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param _ephem_source [Symbol] the ephemeris source type
|
|
16
|
+
# @return [Array<Array>] ephemeris segment identifiers
|
|
8
17
|
def self.ephemeris_segments(_ephem_source)
|
|
9
18
|
[[SOLAR_SYSTEM_BARYCENTER, MARS_BARYCENTER]]
|
|
10
19
|
end
|
|
11
20
|
|
|
21
|
+
# @return [Float] absolute magnitude
|
|
12
22
|
def self.absolute_magnitude
|
|
13
23
|
ABSOLUTE_MAGNITUDE
|
|
14
24
|
end
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
+
# Represents Mercury.
|
|
4
5
|
class Mercury < SolarSystemBody
|
|
5
6
|
EQUATORIAL_RADIUS = Distance.from_meters(2_439_700)
|
|
6
7
|
ABSOLUTE_MAGNITUDE = -0.613
|
|
8
|
+
ORBITAL_PERIOD = 87.969
|
|
7
9
|
|
|
10
|
+
# @return [Boolean] true; Mercury is an inferior planet
|
|
11
|
+
def self.inferior_planet?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param _ephem_source [Symbol] the ephemeris source type
|
|
16
|
+
# @return [Array<Array>] ephemeris segment identifiers
|
|
8
17
|
def self.ephemeris_segments(_ephem_source)
|
|
9
18
|
[[SOLAR_SYSTEM_BARYCENTER, MERCURY_BARYCENTER]]
|
|
10
19
|
end
|
|
11
20
|
|
|
21
|
+
# @return [Float] absolute magnitude
|
|
12
22
|
def self.absolute_magnitude
|
|
13
23
|
ABSOLUTE_MAGNITUDE
|
|
14
24
|
end
|