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
data/UPGRADING.md CHANGED
@@ -7,6 +7,273 @@ changes to it as long as a major version has not been released.
7
7
  If you are already using Astronoby and wish to follow the changes to its
8
8
  public API, please read the upgrading notes for each release.
9
9
 
10
+ ## Upgrading from 0.7.0 to 0.8.0
11
+
12
+ ### Benchmark directory changed
13
+
14
+ The precision benchmark has been moved to `benchmarks`.
15
+
16
+ ### `Epoch` refactored into `JulianDate`
17
+
18
+ The `Epoch` class has been removed and replaced by `JulianDate`. This change is
19
+ meant to clarify the purpose of the class, which is to represent a Julian date
20
+ and not an epoch.
21
+
22
+ * Method `#to_utc` has been dropped in favor as is was ambiguous regarding the
23
+ timescale used.
24
+ * Therefore, constant `JULIAN_DAY_NUMBER_OFFSET` has also been dropped.
25
+ * `MeanObliquity::for_epoch` was renamed to `::at` and now takes an `instant` as
26
+ parameter
27
+ * `MeanObliquity::obliquity_of_reference_in_milliarcseconds` was renamed to
28
+ `::obliquity_of_reference_in_arcseconds`
29
+ * `TrueObliquity::for_epoch` was renamed to to `::at` and now takes an
30
+ `instant` as parameter
31
+ * `Coordinates::Equatorial#to_ecliptic` method now takes an `instant` as
32
+ parameter
33
+
34
+ ### `#angular_diameter` moved from topocentric position to body
35
+
36
+ Previously accessible from the topocentric reference frame, the angular diameter
37
+ of a Solar System body is now accessible from the body itself.
38
+
39
+ ## Upgrading from 0.6.0 to 0.7.0
40
+
41
+ ### Signature change for `Sun` and `Moon`
42
+
43
+ Both classes are now initialized with the key arguments `ephem` and `instant`.
44
+ `ephem` comes from `Ephem.load` which provides the raw geometric data for Solar
45
+ System bodies. `instant` is an instance of `Instant`, the new concept for
46
+ representing an instant in time.
47
+
48
+ ```rb
49
+ Astronoby::Ephem.download(name: "de421.bsp", target: "tmp/de421.bsp")
50
+ ephem = Astronoby::Ephem.load("tmp/de421.bsp")
51
+
52
+ time = Time.utc(2025, 6, 19, 12, 0, 0)
53
+ instant = Astronoby::Instant.from_time(time)
54
+
55
+ sun = Astronoby::Sun.new(instant: instant, ephem: ephem)
56
+ ```
57
+
58
+ Learn more on [ephem].
59
+
60
+ [ephem]: https://github.com/rhannequin/astronoby/wiki/Ephem
61
+
62
+ ### Drop of methods for `Sun`
63
+
64
+ `Sun` doesn't expose the following class and instance methods anymore:
65
+ * `::equation_of_time` (replaced with `#equation_of_time`)
66
+ * `#epoch` (replaced with `#instant`)
67
+ * `#true_ecliptic_coordinates` (replaced with `#ecliptic` on reference frames)
68
+ * `#apparent_ecliptic_coordinates` (replaced with `#ecliptic` on reference frames)
69
+ * `#horizontal_coordinates` (replaced with `#horizontal` on the Topocentric reference frame)
70
+ * `#observation_events`
71
+ * `#twilight_events`
72
+ * `#earth_distance` (replaced with `#distance` on referential frames)
73
+ * `#angular_size` (replaced with `#angular_diameter` on referential frames)
74
+ * `#true_anomaly`
75
+ * `#mean_anomaly`
76
+ * `#longitude_at_perigee`
77
+ * `#orbital_eccentricity`
78
+
79
+ Learn more on [reference frames].
80
+
81
+ [reference frames]: https://github.com/rhannequin/astronoby/wiki/Reference-Frames
82
+
83
+ ### Drop of instance methods for `Moon`
84
+
85
+ `Moon` doesn't expose the following nstance methods anymore:
86
+ * `#apparent_ecliptic_coordinates` (replaced with `#ecliptic` on reference frames)
87
+ * `#apparent_equatorial_coordinates` (replaced with `#equatorial` on reference frames)
88
+ * `#horizontal_coordinates` (replaced with the Apparent and Topocentric reference frames)
89
+ * `#distance` (replaced with `#distance` on referential frames)
90
+ * `#mean_longitude`
91
+ * `#mean_elongation`
92
+ * `#mean_anomaly`
93
+ * `#argument_of_latitude`
94
+ * `#phase_angle`
95
+ * `#observation_events`
96
+
97
+ ### Signature change for `Aberration`
98
+
99
+ `Aberration` is now initialized with the key arguments `astrometric_position`
100
+ and `observer_velocity`. `astrometric_position` is a position vector
101
+ (`Astronoby::Vector<Astronoby::Distance>`) available from any referential frame
102
+ with the `#position` method.`observer_velocity` is a velocity vector
103
+ (`Astronoby::Vector<Astronoby::Distance>`) available from any referential frame
104
+ with the `#velocity` method.
105
+
106
+ `observer_velocity` is meant to be a geometric velocity, while
107
+ `astrometric_position` is meant to be an astrometric position.
108
+
109
+ ```rb
110
+ time = Time.utc(2025, 4, 1)
111
+ instant = Astronoby::Instant.from_time(time)
112
+ ephem = Astronoby::Ephem.load("de421.bsp")
113
+ earth = Astronoby::Earth.new(instant: instant, ephem: ephem)
114
+ mars = Astronoby::Mars.new(instant: instant, ephem: ephem)
115
+ earth_geometric_velocity = earth.geometric.velocity
116
+ mars_astrometric_position = mars.astrometric.position
117
+
118
+ aberration = Astronoby::Aberration.new(
119
+ astrometric_position: mars_astrometric_position,
120
+ observer_velocity: earth_geometric_velocity
121
+ )
122
+ ```
123
+
124
+ ### Signature change for `Angle#to_dms` and `Angle#to_hms`
125
+
126
+ `Angle#to_dms` and `Angle#to_hms` don't have arguments anymore. The angle value
127
+ is now taken from the object itself. This was a misbehavior in the previous
128
+ implementation.
129
+
130
+ ```rb
131
+ angle = Astronoby::Angle.from_degrees(45.0)
132
+ dms = angle.to_dms
133
+
134
+ dms.format
135
+ # => "+45° 0′ 0.0″"
136
+ ```
137
+
138
+ ### Signature change for `EquinoxSolstice`
139
+
140
+ `EquinoxSolstice.new` now takes an additional argument expected to be an ephem
141
+ (`Astronoby::Ephem`).
142
+
143
+ ### Signature change for `Nutation`
144
+
145
+ The expected `epoch` (`Astronoby::Epoch`) argument has been replaced by an
146
+ `instant` (`Astronoby::Instant`) key argument.
147
+
148
+ ### Drop of `Nutation::for_ecliptic_longitude` and `Nutation::for_obliquity_of_the_ecliptic`
149
+
150
+ `Nutation::for_ecliptic_longitude` and `Nutation::for_obliquity_of_the_ecliptic`
151
+ methods have been removed. The `Nutation` class now exposes the
152
+ `#nutation_in_longitude` and `#nutation_in_obliquity` instance methods which
153
+ both return an angle (`Astronoby::Angle`).
154
+
155
+ ### Signature change for `Precession`
156
+
157
+ The expected `coordinates` and `epoch` (`Astronoby::Epoch`) key arguments have
158
+ been replaced by an `instant` (`Astronoby::Instant`) key argument.
159
+
160
+ ### Drop of `Precession#for_equatorial_coordinates` and `Precession#precess`
161
+
162
+ `Precession#for_equatorial_coordinates` and `Precession#precess` methods have
163
+ been refactoed into class methods.
164
+
165
+ ### Drop of `Coordinates::Horizontal#to_equatorial`
166
+
167
+ `Coordinates::Horizontal#to_equatorial` has been removed as equatorial
168
+ coordinates are now available from the reference frames.
169
+
170
+ ### Drop of instance methods for `Coordinates::Ecliptic`
171
+
172
+ `Coordinates::Ecliptic#to_true_equatorial` and
173
+ `Coordinates::Ecliptic#to_apparent_equatorial` have been removed as
174
+ equatorial coordinates are now available from the reference frames.
175
+
176
+ ### Drop of `Coordinates::Equatorial#to_epoch`
177
+
178
+ `Coordinates::Equatorial#to_epoch` has been removed.
179
+
180
+ ### Drop of `Events::ObservationEvents`
181
+
182
+ `Events::ObservationEvents` has been removed. The rising, transit and setting
183
+ times can now be calculated using `RiseTransitSetCalculator`.
184
+
185
+ ```rb
186
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
187
+ observer = Astronoby::Observer.new(
188
+ latitude: Astronoby::Angle.from_degrees(48),
189
+ longitude: Astronoby::Angle.from_degrees(2)
190
+ )
191
+ date = Date.new(2025, 4, 24)
192
+
193
+ calculator = Astronoby::RiseTransitSetCalculator.new(
194
+ body: Astronoby::Sun,
195
+ observer: observer,
196
+ ephem: ephem
197
+ )
198
+
199
+ event = calculator.event_on(date)
200
+
201
+ event.rising_time
202
+ # => 2025-04-24 04:45:42 UTC
203
+
204
+ event.transit_time
205
+ # => 2025-04-24 11:50:04 UTC
206
+
207
+ event.setting_time
208
+ # => 2025-04-24 18:55:24 UTC
209
+ ```
210
+
211
+ ### Drop of `RiseTransitSetIteration`
212
+
213
+ `RiseTransitSetIteration` has been removed as it was only used by
214
+ `Events::ObservationEvents`.
215
+
216
+ ### Drop of `Events::TwilightEvents`
217
+
218
+ `Events::TwilightEvents` has been removed. The twilight times can now be
219
+ calculated using `TwilightCalculator`.
220
+
221
+ ```rb
222
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
223
+ observer = Astronoby::Observer.new(
224
+ latitude: Astronoby::Angle.from_degrees(48),
225
+ longitude: Astronoby::Angle.from_degrees(2)
226
+ )
227
+ date = Date.new(2025, 4, 24)
228
+
229
+ calculator = Astronoby::TwilightCalculator.new(
230
+ observer: observer,
231
+ ephem: ephem
232
+ )
233
+
234
+ event = calculator.event_on(date)
235
+ # Returns a Astronoby::TwilightEvent object
236
+
237
+ event.morning_astronomical_twilight_time
238
+ # => 2025-04-24 02:43:38 UTC
239
+
240
+ event.morning_nautical_twilight_time
241
+ # => 2025-04-24 03:30:45 UTC
242
+
243
+ event.morning_civil_twilight_time
244
+ # => 2025-04-24 04:12:38 UTC
245
+
246
+ event.evening_civil_twilight_time
247
+ # => 2025-04-24 19:27:34 UTC
248
+
249
+ event.evening_nautical_twilight_time
250
+ # => 2025-04-24 20:09:27 UTC
251
+
252
+ event.evening_astronomical_twilight_time
253
+ # => 2025-04-24 20:56:34 UTC
254
+ ```
255
+
256
+ ### Drop of `EphemerideLunaireParisienne`
257
+
258
+ `EphemerideLunaireParisienne` has been removed.
259
+
260
+ ### Drop of `Util::Astrodynamics`
261
+
262
+ `Util::Astrodynamics` has been removed.
263
+
264
+ ### Drop of `Util::Maths.interpolate` and `Util::Maths.normalize_angles_for_interpolation`
265
+
266
+ `Util::Maths.interpolate` and `Util::Maths.normalize_angles_for_interpolation`
267
+ have been removed.
268
+
269
+ ### Drop of `Constants::SECONDS_PER_DEGREE`
270
+
271
+ `Constants::SECONDS_PER_DEGREE` has been removed.
272
+
273
+ ## Upgrading from 0.5.0 to 0.6.0
274
+
275
+ No breaking changes.
276
+
10
277
  ## Upgrading from 0.4.0 to 0.5.0
11
278
 
12
279
  ### `Sun#horizontal_coordinates` method signature changed ([#69])
data/docs/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # Quick Start
2
+
3
+ ## Download an ephemeris
4
+
5
+ You only need to run this once, it will download and store an ephemeris on your
6
+ file system.
7
+
8
+ ```rb
9
+ Ephem::IO::Download.call(name: "de421.bsp", target: "tmp/de421.bsp")
10
+ ```
11
+
12
+ Ephemerides can be large files, but Astronoby provides a tool to drastically
13
+ reduce the size to your needs. You can learn more about ephemerides on the
14
+ [Ephem page].
15
+
16
+ ## Load an ephemeris
17
+
18
+ ```rb
19
+ ephem = Astronoby::Ephem.load("tmp/de421.bsp")
20
+ ```
21
+
22
+ ## Define a time and create an `Instant` object from it
23
+
24
+ ```rb
25
+ time = Time.utc(2025, 6, 19, 12, 0, 0)
26
+ instant = Astronoby::Instant.from_time(time)
27
+ ```
28
+
29
+ You can learn more about time scales on the [Instant page].
30
+
31
+ ## Instantiate a Solar System body object
32
+
33
+ ```rb
34
+ jupiter = Astronoby::Jupiter.new(instant: instant, ephem: ephem)
35
+ ```
36
+
37
+ You can learn more about planets and bodies on the [Celestial Bodies page].
38
+
39
+ ## Define an observer from geographic coordinates
40
+
41
+ ```rb
42
+ observer = Astronoby::Observer.new(
43
+ latitude: Astronoby::Angle.from_degrees(48.83661378408946),
44
+ longitude: Astronoby::Angle.from_degrees(2.3366748126024466),
45
+ elevation: Astronoby::Distance.from_meters(65)
46
+ )
47
+ ```
48
+
49
+ You can learn more about angles on the [Angles page], and about observers on the
50
+ [Observer page].
51
+
52
+ ## Compute the topocentric position of the body as seen from the observer
53
+
54
+ ```rb
55
+ topocentric = jupiter.observed_by(observer)
56
+ ```
57
+
58
+ You can learn more about reference frames and positions on the
59
+ [Reference Frames page].
60
+
61
+ ## Get the horizontal coordinates from the position
62
+
63
+ ```rb
64
+ topocentric.horizontal.azimuth.str(:dms)
65
+ # => "+175° 34′ 28.2724″"
66
+
67
+ topocentric.horizontal.altitude.str(:dms)
68
+ # => "+64° 22′ 58.1084″"
69
+ ```
70
+
71
+ You can learn more about coordinates on the [Coordinates page].
72
+
73
+ ## Get the rising, transit and setting times between two times
74
+
75
+ ```rb
76
+ calculator = Astronoby::RiseTransitSetCalculator.new(
77
+ body: Astronoby::Jupiter,
78
+ observer: observer,
79
+ ephem: ephem
80
+ )
81
+
82
+ events = calculator.events_between(
83
+ Time.utc(2025, 5, 1),
84
+ Time.utc(2025, 5, 3),
85
+ )
86
+
87
+ events.rising_times
88
+ # => [2025-05-01 06:35:35 UTC, 2025-05-02 06:32:26 UTC]
89
+
90
+ events.transit_times
91
+ # => [2025-05-01 14:34:34 UTC, 2025-05-02 14:31:31 UTC]
92
+
93
+ events.setting_times
94
+ # => [2025-05-01 22:33:37 UTC, 2025-05-02 22:30:39 UTC]
95
+ ```
96
+
97
+ You can learn more about this calculator on the
98
+ [Rise, transit and setting times page].
99
+
100
+ ## Get the twilight times of the day
101
+
102
+ ```rb
103
+ calculator = Astronoby::TwilightCalculator.new(
104
+ observer: observer,
105
+ ephem: ephem
106
+ )
107
+
108
+ event = calculator.event_on(Date.new(2025, 5, 1))
109
+
110
+ event.morning_astronomical_twilight_time
111
+ # => 2025-05-01 02:17:28 UTC
112
+
113
+ event.morning_nautical_twilight_time
114
+ # => 2025-05-01 03:10:17 UTC
115
+
116
+ event.morning_civil_twilight_time
117
+ # => 2025-05-01 03:55:17 UTC
118
+
119
+ event.evening_civil_twilight_time
120
+ # => 2025-05-01 19:40:12 UTC
121
+
122
+ event.evening_nautical_twilight_time
123
+ # => 2025-05-01 20:25:12 UTC
124
+
125
+ event.evening_astronomical_twilight_time
126
+ # => 2025-05-01 21:18:01 UTC
127
+ ```
128
+
129
+ You can learn more about this calculator on the [Twilight times page].
130
+
131
+ ## Moon phases
132
+
133
+ You can either get all the major Moon phases that will happen in a month, or get
134
+ information about the current Moon phase.
135
+
136
+ ```rb
137
+ may_2024_phases = Astronoby::Events::MoonPhases.phases_for(year: 2024, month: 5)
138
+
139
+ may_2024_phases.each { puts "#{_1.phase}: #{_1.time}" }
140
+ # last_quarter: 2024-05-01 11:27:15 UTC
141
+ # new_moon: 2024-05-08 03:21:56 UTC
142
+ # first_quarter: 2024-05-15 11:48:02 UTC
143
+ # full_moon: 2024-05-23 13:53:12 UTC
144
+ # last_quarter: 2024-05-30 17:12:43 UTC
145
+ ```
146
+
147
+ ```rb
148
+ time = Time.utc(2025, 5, 15)
149
+ instant = Astronoby::Instant.from_time(time)
150
+ moon = Astronoby::Moon.new(ephem: ephem, instant: instant)
151
+
152
+ moon.illuminated_fraction.round(2)
153
+ # => 0.15
154
+
155
+ moon.current_phase_fraction.round(2)
156
+ # => 0.11
157
+ ```
158
+
159
+ You can learn more about phases on the [Moon phases page].
160
+
161
+ ## Equinox and solstice times
162
+
163
+ ```rb
164
+
165
+ Astronoby::EquinoxSolstice.march_equinox(2025, ephem)
166
+ # => 2025-03-20 09:01:29 UTC
167
+
168
+ Astronoby::EquinoxSolstice.june_solstice(2025, ephem)
169
+ # => 2025-06-21 02:42:19 UTC
170
+
171
+ Astronoby::EquinoxSolstice.september_equinox(2025, ephem)
172
+ # => 2025-09-22 18:19:22 UTC
173
+
174
+ Astronoby::EquinoxSolstice.december_solstice(2025, ephem)
175
+ # => 2025-12-21 15:03:03 UTC
176
+ ```
177
+
178
+ You can learn more about equinoxes and solstices on the
179
+ [Equinoxes and solstices times page].
180
+
181
+ ## See also
182
+ - [Glossary](glossary.md) - for astronomical and technical terms
183
+ - [Configuration](configuration.md) - for performance tuning
184
+ - [Performance Benchmarks](../benchmarks/README.md) - for testing improvements
185
+
186
+ [Ephem page]: ephem.md
187
+ [Instant page]: instant.md
188
+ [Celestial Bodies page]: celestial_bodies.md
189
+ [Observer page]: observer.md
190
+ [Reference Frames page]: reference_frames.md
191
+ [Angles page]: angles.md
192
+ [Coordinates page]: coordinates.md
193
+ [Rise, transit and setting times page]: rise_transit_set_times.md
194
+ [Twilight times page]: twilight_times.md
195
+ [Moon phases page]: moon_phases.md
196
+ [Equinoxes and solstices times page]: equinoxes_solstices_times.md
data/docs/angles.md ADDED
@@ -0,0 +1,137 @@
1
+ # Angles
2
+
3
+ `Astronoby::Angle` is one of the most important object in the library. An object
4
+ on the celestial sphere is described with angles, an observer's location on
5
+ Earth is described with angles, the distance between two points in the sky is
6
+ described with an angle.
7
+
8
+ ## Create an angle
9
+
10
+ You can create an instance of `Astronoby::Angle` with a value in different
11
+ units: radians, degrees or hours.
12
+
13
+ ```rb
14
+ Astronoby::Angle.from_radians(Math::PI)
15
+ Astronoby::Angle.from_degrees(180)
16
+ Astronoby::Angle.from_hours(12)
17
+ ```
18
+
19
+ You can also use the hour-minute-second (HMS) or degree-minute-second (DMS)
20
+ formats.
21
+
22
+ ```rb
23
+ Astronoby::Angle.from_hms(22, 45, 23)
24
+ Astronoby::Angle.from_dms(340, 45, 23)
25
+ ```
26
+
27
+ Alternatively, you can create an angle of 0 (regardless of the unit).
28
+
29
+ ```rb
30
+ Astronoby::Angle.zero
31
+ ```
32
+
33
+ Finally, you can create an angle from the ratio of a trigonometric function.
34
+
35
+ ```rb
36
+ Astronoby::Angle.acos(0)
37
+ Astronoby::Angle.asin(-1)
38
+ Astronoby::Angle.atan(1 / Math.sqrt(3))
39
+ ```
40
+
41
+ ## Convert between units
42
+
43
+ Once an angle object is instantiated, its value lives inside it. You need to
44
+ specify a unit to extract it.
45
+
46
+ ```rb
47
+ angle = Astronoby::Angle.from_degrees(180)
48
+
49
+ angle.degrees # => 180.0
50
+ angle.radians # => 3.141592653589793
51
+ angle.hours # => 12.0
52
+ ```
53
+
54
+ ## Format an angle
55
+
56
+ You can format an angle in HMS or DMS formatted strings.
57
+
58
+ ```rb
59
+ angle = Astronoby::Angle.from_degrees(155.76479)
60
+
61
+ angle.str(:dms) # => "+155° 45′ 53.2439″"
62
+ angle.str(:hms) # => "10h 23m 3.5496s"
63
+ ```
64
+
65
+ Alternatively you can extract these numbers without having to format them into a
66
+ string.
67
+
68
+ ```rb
69
+ angle = Astronoby::Angle.from_degrees(155.76479)
70
+
71
+ dms = angle.to_dms
72
+ dms.sign # => "+"
73
+ dms.degrees # => 155
74
+ dms.minutes # => 45
75
+ dms.seconds # => 53.2439
76
+
77
+ hms = angle.to_hms
78
+ hms.hours # => 10
79
+ hms.minutes # => 23
80
+ hms.seconds # => 3.5496
81
+ ```
82
+
83
+ ## Manipulate angles
84
+
85
+ You can compare an angle with another angle.
86
+
87
+ ```rb
88
+ Astronoby::Angle.from_hours(12) == Astronoby::Angle.from_degrees(180)
89
+ # => true
90
+
91
+ angle1 = Astronoby::Angle.from_degrees(90)
92
+ angle2 = Astronoby::Angle.from_hours(12)
93
+
94
+ angle1 < angle2 # => true
95
+ ```
96
+
97
+ ## Math with angles
98
+
99
+ Trigonometric functions can be applied to angles to get the value as a `Float`.
100
+ Please be aware some results won't be strictly exact because of the limited
101
+ precision of floating-point numbers and the limited amount of digits
102
+ of `Math::PI`.
103
+
104
+ ```rb
105
+ angle = Astronoby::Angle.from_degrees(180)
106
+
107
+ angle.cos # => -1.0
108
+ angle.sin # => 1.2246467991473532e-16, strictly supposed to be 0
109
+ angle.tan # => -1.2246467991473532e-16, strictly supposed to be 0
110
+ ```
111
+
112
+ You can add up or subtract angles into a new one. Multiplication and division
113
+ are not supported as they mathematically should return something else than an
114
+ angle.
115
+
116
+ ```rb
117
+ angle1 = Astronoby::Angle.from_hours(12)
118
+ angle2 = Astronoby::Angle.from_degrees(90)
119
+
120
+ angle3 = angle1 + angle2
121
+ angle3.degrees # => 270.0
122
+
123
+ angle4 = angle1 - angle2
124
+ angle4.degrees # => 90.0
125
+
126
+ angle5 = -angle1
127
+ angle5.degrees # => -180.0
128
+
129
+ angle1.positive? # => true
130
+ angle1.negative? # => false
131
+ ```
132
+
133
+ ## See also
134
+ - [Coordinates](coordinates.md) - for using angles in coordinate systems
135
+ - [Observer](observer.md) - for latitude and longitude
136
+ - [Reference Frames](reference_frames.md) - for position calculations
137
+ - [Celestial Bodies](celestial_bodies.md) - for object positions
@@ -0,0 +1,107 @@
1
+ # Celestial Bodies
2
+
3
+ Currently, Astronoby only supports the following major bodies of the Solar
4
+ System:
5
+ * the Sun (`Astronoby::Sun`)
6
+ * planets from Mercury to Neptune, including the Earth (`Astronoby::Earth`, ...)
7
+ * the Moon (`Astronoby::Moon`)
8
+
9
+ Given an ephemeris (`Astronoby::Ephem`) and an instant object
10
+ (`Astronoby::Instant`), these classes enable you to get instances which provide
11
+ positions in different reference frames.
12
+
13
+ You can learn more about [ephemerides] and [reference frames].
14
+
15
+ ```rb
16
+ ephem = Astronoby::Ephem.load("inpop19a.bsp")
17
+ time = Time.utc(2021, 7, 8)
18
+ instant = Astronoby::Instant.from_time(time)
19
+
20
+ venus = Astronoby::Venus.new(ephem: ephem, instant: instant)
21
+ apparent_position = venus.apparent.position
22
+
23
+ apparent_position.x.km.round
24
+ # => -148794622
25
+ ```
26
+
27
+ Each of these bodies also provides its own equatorial radius
28
+ (`Astronoby::Distance`).
29
+
30
+ ```rb
31
+ Astronoby::Venus::EQUATORIAL_RADIUS.meters
32
+ # => 6051800
33
+ ```
34
+
35
+ ## Attributes of planets
36
+
37
+ For all Solar System bodies, except the Sun and the Earth, the following
38
+ attributes are available. Note that dynamic values are accessible through
39
+ instance methods, while absolute values are accessible through class methods.
40
+
41
+ ### `#angular_diameter`
42
+
43
+ Size of the body in the sky. Returns a `Astronoby::Angle` object.
44
+
45
+ ```rb
46
+ venus.angular_diameter.str(:dms)
47
+ # => "+0° 0′ 11.4587″"
48
+ ```
49
+
50
+ ### `#constellation`
51
+
52
+ Constellation where the body appears in the sky as seen from Earth. Returns
53
+ a `Astronoby::Constellation` object.
54
+
55
+ ```rb
56
+ venus.constellation.name
57
+ # => "Cancer"
58
+
59
+ venus.constellation.abbreviation
60
+ # => "Cnc"
61
+ ```
62
+
63
+ ### `#phase_angle`
64
+
65
+ "Sun-object-Earth" angle. Returns a `Astronoby::Angle` object.
66
+
67
+ ```rb
68
+ venus.phase_angle.degrees.round
69
+ # => 40
70
+ ```
71
+
72
+ ### `#illuminated_fraction`
73
+
74
+ Fraction of the object's disk illuminated as seen from Earth. Returns a `Float`
75
+ between `0` and `1`.
76
+
77
+ ```rb
78
+ venus.illuminated_fraction.round(2)
79
+ # => 0.88
80
+ ```
81
+
82
+ ### `#apparent_magnitude`
83
+
84
+ Apparent brightness of the body. Returns a `Float`.
85
+
86
+ ```rb
87
+ venus.apparent_magnitude.round(2)
88
+ # => -3.89
89
+ ```
90
+
91
+ ### `::absolute_magnitude`
92
+
93
+ Absolute brightness of the body. Returns a `Float`.
94
+
95
+ ```rb
96
+ Astronoby::Venus.absolute_magnitude
97
+ # => -4.384
98
+ ```
99
+
100
+ [ephemerides]: ephem.md
101
+ [reference frames]: reference_frames.md
102
+
103
+ ## See also
104
+ - [Ephemerides](ephem.md) - for understanding data sources
105
+ - [Reference Frames](reference_frames.md) - for coordinate systems
106
+ - [Observer](observer.md) - for setting up observation locations
107
+ - [Angles](angles.md) - for working with angular measurements