astronoby 0.8.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 +159 -0
- data/README.md +12 -5
- data/UPGRADING.md +109 -0
- data/docs/README.md +109 -16
- data/docs/angles.md +2 -1
- data/docs/configuration.md +20 -17
- data/docs/coordinates.md +73 -13
- data/docs/deep_sky_bodies.md +101 -0
- data/docs/ephem.md +6 -3
- data/docs/equinoxes_solstices_times.md +4 -3
- data/docs/glossary.md +97 -1
- data/docs/iers.md +40 -0
- data/docs/instant.md +21 -16
- data/docs/lunar_eclipses.md +93 -0
- data/docs/lunar_observation.md +87 -0
- data/docs/moon_phases.md +5 -2
- data/docs/observer.md +21 -7
- data/docs/planetary_phenomena.md +78 -0
- data/docs/reference_frames.md +193 -35
- data/docs/rise_transit_set_times.md +10 -8
- data/docs/{celestial_bodies.md → solar_system_bodies.md} +27 -5
- data/docs/twilight_times.md +25 -21
- data/lib/astronoby/angle.rb +69 -4
- data/lib/astronoby/angles/dms.rb +18 -1
- data/lib/astronoby/angles/hms.rb +14 -1
- data/lib/astronoby/angular_velocity.rb +97 -0
- data/lib/astronoby/bodies/deep_sky_object.rb +49 -0
- data/lib/astronoby/bodies/deep_sky_object_position.rb +142 -0
- data/lib/astronoby/bodies/earth.rb +9 -42
- 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 +162 -15
- data/lib/astronoby/bodies/neptune.rb +10 -0
- data/lib/astronoby/bodies/saturn.rb +10 -0
- data/lib/astronoby/bodies/solar_system_body.rb +257 -53
- 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/cache.rb +1 -0
- data/lib/astronoby/center.rb +84 -0
- data/lib/astronoby/constants.rb +7 -2
- data/lib/astronoby/constellation.rb +9 -1
- data/lib/astronoby/coordinates/ecliptic.rb +10 -1
- data/lib/astronoby/coordinates/equatorial.rb +66 -13
- data/lib/astronoby/coordinates/geodetic.rb +102 -0
- data/lib/astronoby/coordinates/horizontal.rb +13 -1
- data/lib/astronoby/distance.rb +41 -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 +80 -0
- data/lib/astronoby/events/extremum_event.rb +15 -0
- 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_calculator.rb +9 -6
- 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_calculator.rb +1 -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 +35 -9
- 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 +25 -16
- 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 +31 -5
- 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/stellar_propagation.rb +162 -0
- data/lib/astronoby/time/greenwich_apparent_sidereal_time.rb +31 -0
- data/lib/astronoby/time/greenwich_mean_sidereal_time.rb +101 -0
- data/lib/astronoby/time/greenwich_sidereal_time.rb +41 -58
- data/lib/astronoby/time/local_apparent_sidereal_time.rb +63 -0
- data/lib/astronoby/time/local_mean_sidereal_time.rb +63 -0
- data/lib/astronoby/time/local_sidereal_time.rb +59 -26
- data/lib/astronoby/time/sidereal_time.rb +64 -0
- data/lib/astronoby/true_obliquity.rb +4 -0
- data/lib/astronoby/util/maths.rb +8 -0
- data/lib/astronoby/util/time.rb +10 -467
- data/lib/astronoby/vector.rb +10 -0
- data/lib/astronoby/velocity.rb +44 -0
- data/lib/astronoby/version.rb +1 -1
- data/lib/astronoby.rb +33 -0
- metadata +58 -6
data/docs/instant.md
CHANGED
|
@@ -14,7 +14,9 @@ from the irregularities in the rotation of Earth and the irregularly fluctuating
|
|
|
14
14
|
mean solar time.
|
|
15
15
|
|
|
16
16
|
Astronoby handles this situation by implementing an `Astronoby::Instant` class,
|
|
17
|
-
used in most calculations instead of `Time`.
|
|
17
|
+
used in most calculations instead of `Time`. Converting between UTC and
|
|
18
|
+
Terrestrial Time requires knowing [Delta T (TT - UT1)][Delta T], which
|
|
19
|
+
Astronoby obtains from [IERS data](iers.md).
|
|
18
20
|
|
|
19
21
|
`Astronoby::Instant` is a value object that stores an instant in time on Earth
|
|
20
22
|
in [Terrestrial Time], an astronomical time standard defined by the
|
|
@@ -28,9 +30,10 @@ standards can be expressed, such as the
|
|
|
28
30
|
## Initialization
|
|
29
31
|
|
|
30
32
|
An `Astronoby::Instant` object can be instantiated from:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
- Terrestrial time (`Numeric`): `.from_terrestrial_time`
|
|
35
|
+
- Ruby `Time` object: `.from_time`
|
|
36
|
+
- UTC Julian date (`Numeric`): `.from_utc_julian_date`
|
|
34
37
|
|
|
35
38
|
```rb
|
|
36
39
|
Astronoby::Instant.from_terrestrial_time(2460796)
|
|
@@ -48,7 +51,7 @@ Astronoby::Instant.from_utc_julian_date(2460796)
|
|
|
48
51
|
|
|
49
52
|
From the same instant, it is possible to extract different time standards.
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
- Gregorian `Date`
|
|
52
55
|
|
|
53
56
|
```rb
|
|
54
57
|
instant = Astronoby::Instant.from_terrestrial_time(2460796)
|
|
@@ -57,34 +60,34 @@ instant.to_date
|
|
|
57
60
|
# => #<Date: 2025-04-30 ((2460796j,0s,0n),+0s,2299161j)>
|
|
58
61
|
```
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
- UTC `DateTime`
|
|
61
64
|
|
|
62
65
|
```rb
|
|
63
66
|
instant = Astronoby::Instant.from_terrestrial_time(2460796)
|
|
64
67
|
|
|
65
68
|
instant.to_datetime
|
|
66
|
-
# => #<DateTime: 2025-04-30T11:58:
|
|
69
|
+
# => #<DateTime: 2025-04-30T11:58:50+00:00 ((2460796j,43130s,845637619n),+0s,2299161j)>
|
|
67
70
|
```
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
- UTC `Time`
|
|
70
73
|
|
|
71
74
|
```rb
|
|
72
75
|
instant = Astronoby::Instant.from_terrestrial_time(2460796)
|
|
73
76
|
|
|
74
77
|
instant.to_datetime
|
|
75
|
-
# => 2025-04-
|
|
78
|
+
# => 2025-04-30T11:58:50+00:00 UTC
|
|
76
79
|
```
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
- Greenwich Sidereal Time
|
|
79
82
|
|
|
80
83
|
```rb
|
|
81
84
|
instant = Astronoby::Instant.from_terrestrial_time(2460796)
|
|
82
85
|
|
|
83
86
|
instant.gmst
|
|
84
|
-
# => 2.
|
|
87
|
+
# => 2.5597070126923764
|
|
85
88
|
```
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
- International Atomic Time
|
|
88
91
|
|
|
89
92
|
```rb
|
|
90
93
|
instant = Astronoby::Instant.from_terrestrial_time(2460796)
|
|
@@ -93,16 +96,16 @@ instant.tai.to_f
|
|
|
93
96
|
# => 2460795.9996275003
|
|
94
97
|
```
|
|
95
98
|
|
|
96
|
-
|
|
99
|
+
- UTC offset (difference with UTC in days)
|
|
97
100
|
|
|
98
101
|
```rb
|
|
99
102
|
instant = Astronoby::Instant.from_terrestrial_time(2460796)
|
|
100
103
|
|
|
101
104
|
instant.utc_offset.to_f
|
|
102
|
-
# => 0.
|
|
105
|
+
# => 0.0008003974106626159
|
|
103
106
|
```
|
|
104
107
|
|
|
105
|
-
|
|
108
|
+
- Barycentric Dynamic Time
|
|
106
109
|
|
|
107
110
|
```rb
|
|
108
111
|
# This is not handled for now, and returns TT
|
|
@@ -131,9 +134,11 @@ instant1 < instant2
|
|
|
131
134
|
[Gregorian calendar]: https://en.wikipedia.org/wiki/Gregorian_calendar
|
|
132
135
|
[Terrestrial Time]: https://en.wikipedia.org/wiki/Terrestrial_Time
|
|
133
136
|
[Julian Date]: https://en.wikipedia.org/wiki/Julian_day
|
|
137
|
+
[Delta T]: https://en.wikipedia.org/wiki/ΔT_(timekeeping)
|
|
134
138
|
|
|
135
139
|
## See also
|
|
140
|
+
|
|
136
141
|
- [Ephemerides](ephem.md) - for time-based calculations
|
|
137
|
-
- [
|
|
142
|
+
- [Solar System Bodies](solar_system_bodies.md) - for object positions
|
|
138
143
|
- [Reference Frames](reference_frames.md) - for coordinate systems
|
|
139
144
|
- [Configuration](configuration.md) - for performance settings
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Lunar Eclipses
|
|
2
|
+
|
|
3
|
+
Astronoby computes lunar eclipses: the passages of the Moon through Earth's shadow. A lunar eclipse is a geocentric event, the same for every observer who can see the Moon, so no observer is involved. The geometry is built from the apparent geocentric positions of the Sun and Moon, which matches the standard reduction used by [NASA's Five Millennium Canon of Lunar Eclipses] and by IMCCE.
|
|
4
|
+
|
|
5
|
+
There are three kinds of lunar eclipses. A penumbral eclipse is when the Moon only enters Earth's penumbra, the outer, partial shadow. A partial eclipse is when part of the Moon enters the umbra, the inner, total shadow. A total eclipse is when the whole Moon enters the umbra.
|
|
6
|
+
|
|
7
|
+
## Finding eclipses
|
|
8
|
+
|
|
9
|
+
`Astronoby::Moon.eclipse_events` takes an ephemeris and a time range, and returns the lunar eclipses whose greatest instant falls in that range, sorted by time.
|
|
10
|
+
|
|
11
|
+
```rb
|
|
12
|
+
ephem = Astronoby::Ephem.load("inpop19a.bsp")
|
|
13
|
+
|
|
14
|
+
eclipses = Astronoby::Moon.eclipse_events(
|
|
15
|
+
ephem: ephem,
|
|
16
|
+
start_time: Time.utc(2025, 1, 1),
|
|
17
|
+
end_time: Time.utc(2026, 1, 1)
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
eclipses.map { |eclipse| [eclipse.instant.to_time, eclipse.kind] }
|
|
21
|
+
# => [[2025-03-14 06:58:47 UTC, :total], [2025-09-07 18:11:49 UTC, :total]]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## An eclipse
|
|
25
|
+
|
|
26
|
+
Each eclipse is an `Astronoby::LunarEclipse`. Its `#instant` (also available as `#greatest_eclipse`) is the moment of greatest eclipse, when the Moon's centre is least distant from the axis of Earth's shadow.
|
|
27
|
+
|
|
28
|
+
```rb
|
|
29
|
+
eclipse = eclipses.first
|
|
30
|
+
|
|
31
|
+
eclipse.kind # => :total
|
|
32
|
+
eclipse.total? # => true
|
|
33
|
+
eclipse.instant.to_time # => 2025-03-14 06:58:47 UTC
|
|
34
|
+
eclipse.greatest_eclipse # => same as #instant
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The umbral and penumbral magnitudes are the fractions of the Moon's diameter immersed in the umbra and the penumbra at greatest eclipse. The umbral magnitude is negative for a penumbral eclipse (the Moon misses the umbra), between 0 and 1 for a partial eclipse, and 1 or more for a total eclipse.
|
|
38
|
+
|
|
39
|
+
```rb
|
|
40
|
+
eclipse.umbral_magnitude # => 1.179
|
|
41
|
+
eclipse.penumbral_magnitude # => 2.26
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`#gamma` is the least distance of the Moon's centre from the axis of Earth's shadow at greatest eclipse, in Earth radii, positive when the Moon passes north of the axis and negative when it passes south. It is the standard, dimensionless eclipse parameter used by IMCCE and NASA. The same quantity is also available as a `Astronoby::Distance` through `#shadow_axis_distance`.
|
|
45
|
+
|
|
46
|
+
```rb
|
|
47
|
+
eclipse.gamma # => 0.348
|
|
48
|
+
eclipse.shadow_axis_distance.km # => 2222.37
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Phases
|
|
52
|
+
|
|
53
|
+
An eclipse exposes its phases as `Astronoby::EclipsePhase` objects, each with a `#starting_instant`, an `#ending_instant`, and a `#duration` (an `Astronoby::Duration`). The penumbral phase is always present. The partial phase is present for partial and total eclipses, and the total phase (totality) only for total eclipses. A phase that does not occur is `nil`.
|
|
54
|
+
|
|
55
|
+
```rb
|
|
56
|
+
eclipse.penumbral.starting_instant.to_time # => 2025-03-14 03:57:29 UTC (P1)
|
|
57
|
+
eclipse.partial.starting_instant.to_time # => 2025-03-14 05:09:37 UTC (U1)
|
|
58
|
+
eclipse.total.starting_instant.to_time # => 2025-03-14 06:26:01 UTC (U2)
|
|
59
|
+
eclipse.total.ending_instant.to_time # => 2025-03-14 07:31:32 UTC (U3)
|
|
60
|
+
eclipse.partial.ending_instant.to_time # => 2025-03-14 08:47:55 UTC (U4)
|
|
61
|
+
eclipse.penumbral.ending_instant.to_time # => 2025-03-14 10:00:08 UTC (P4)
|
|
62
|
+
|
|
63
|
+
eclipse.total.duration.seconds # => 3931 (seconds of totality)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For a penumbral eclipse, `#partial` and `#total` are `nil`. For a partial eclipse, `#total` is `nil`.
|
|
67
|
+
|
|
68
|
+
```rb
|
|
69
|
+
penumbral_eclipse = Astronoby::Moon.eclipse_events(
|
|
70
|
+
ephem: ephem,
|
|
71
|
+
start_time: Time.utc(2024, 3, 1),
|
|
72
|
+
end_time: Time.utc(2024, 4, 1)
|
|
73
|
+
).first
|
|
74
|
+
|
|
75
|
+
penumbral_eclipse.kind # => :penumbral
|
|
76
|
+
penumbral_eclipse.partial # => nil
|
|
77
|
+
penumbral_eclipse.total # => nil
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Precision
|
|
81
|
+
|
|
82
|
+
Earth's shadow is enlarged by its atmosphere. Astronoby enlarges Earth's radius by 1/99 before building the shadow cones, a factor calibrated against IMCCE. Validated across the 2023 to 2025 eclipses, the eclipse kind, greatest eclipse instant, magnitudes, and contact times all match IMCCE to within a second or two.
|
|
83
|
+
|
|
84
|
+
## See also
|
|
85
|
+
|
|
86
|
+
- [Moon Phases](moon_phases.md) - for lunar phases
|
|
87
|
+
- [Lunar Observation](lunar_observation.md) - for libration, axis and limb angles
|
|
88
|
+
- [Planetary Phenomena](planetary_phenomena.md) - for conjunctions, oppositions and elongations
|
|
89
|
+
- [Solar System Bodies](solar_system_bodies.md) - for moon object details
|
|
90
|
+
- [Ephemerides](ephem.md) - for data sources
|
|
91
|
+
|
|
92
|
+
[NASA's Five Millennium Canon of Lunar Eclipses]: https://eclipse.gsfc.nasa.gov/SEpubs/5MCLE.html
|
|
93
|
+
[IMCCE]: https://www.imcce.fr/
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Lunar Observation
|
|
2
|
+
|
|
3
|
+
Beyond phases and apsides, Astronoby exposes the quantities lunar observers rely on to describe the Moon's appearance and orientation in the sky: its libration, the position angle of its rotation axis, the position angle of its bright limb, and the parallactic angle. By default they follow Jean Meeus, *Astronomical Algorithms*, 2nd edition, and are derived from the Moon's and the Sun's apparent positions, which Astronoby already computes from the ephemeris. The libration and the position angle of the axis can additionally use the integrated lunar orientation from a JPL DE kernel to reach arcsecond accuracy, as described below.
|
|
4
|
+
|
|
5
|
+
All of these are available directly on a `Astronoby::Moon` instance.
|
|
6
|
+
|
|
7
|
+
```rb
|
|
8
|
+
ephem = Astronoby::Ephem.load("inpop19a.bsp")
|
|
9
|
+
instant = Astronoby::Instant.from_time(Time.utc(2025, 3, 1))
|
|
10
|
+
moon = Astronoby::Moon.new(instant: instant, ephem: ephem)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Libration
|
|
14
|
+
|
|
15
|
+
Libration is the apparent oscillation that lets an observer on Earth see slightly more than half of the lunar surface over time. `Astronoby::Moon#libration` returns a `Astronoby::Libration` value object holding the total (optical plus physical) libration in longitude and latitude, both as `Astronoby::Angle` objects. A positive longitude exposes more of the Moon's eastern limb (Mare Crisium side); a positive latitude exposes more of its northern limb.
|
|
16
|
+
|
|
17
|
+
```rb
|
|
18
|
+
libration = moon.libration
|
|
19
|
+
|
|
20
|
+
libration.longitude.str(:dms) # => "-2° 5′ 4.4219″"
|
|
21
|
+
libration.latitude.str(:dms) # => "+0° 28′ 45.9616″"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
By default this is the analytic optical plus physical libration from Meeus's series. Compared with the lunar orientation integrated in the JPL DE solution (as reported by JPL Horizons), the libration in longitude and the position angle of the axis agree to within a few arcseconds, while the libration in latitude agrees to about 0.02 degrees. That residual is the well known difference between the mean lunar equator used by the classical Meeus method and the DE mean-Earth frame. It is eliminated by loading an orientation kernel.
|
|
25
|
+
|
|
26
|
+
## Arcsecond accuracy with an orientation kernel
|
|
27
|
+
|
|
28
|
+
For the libration and the position angle of the axis, you can reach the accuracy of JPL Horizons, Skyfield and IMCCE by also loading a binary PCK lunar orientation kernel, such as `moon_pa_de440_200625.bpc`, which carries the integrated DE440 orientation of the Moon. Load it once with `Astronoby::Orientation` and pass it to the Moon alongside the ephemeris.
|
|
29
|
+
|
|
30
|
+
```rb
|
|
31
|
+
ephem = Astronoby::Ephem.load("de440.bsp")
|
|
32
|
+
orientation = Astronoby::Orientation.load("moon_pa_de440_200625.bpc")
|
|
33
|
+
|
|
34
|
+
moon = Astronoby::Moon.new(instant: instant, ephem: ephem, orientation: orientation)
|
|
35
|
+
|
|
36
|
+
moon.libration.latitude.str(:dms) # => "+0° 27′ 27.7258″"
|
|
37
|
+
moon.position_angle_of_axis.str(:dms) # => "-21° 48′ 32.9625″"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The libration is then computed as the selenographic longitude and latitude of the sub-Earth point in the Moon's mean-Earth body-fixed frame, and matches JPL Horizons to better than an arcsecond. Without an orientation kernel the Moon keeps using the analytic method, so this is an opt-in refinement, not a requirement. The `bright_limb_position_angle` and `parallactic_angle` are unaffected and do not need a kernel.
|
|
41
|
+
|
|
42
|
+
If you do not already have the kernel, Astronoby can download it for you.
|
|
43
|
+
|
|
44
|
+
```rb
|
|
45
|
+
Astronoby::Orientation.download(
|
|
46
|
+
name: "moon_pa_de440_200625.bpc",
|
|
47
|
+
target: "moon_pa_de440_200625.bpc"
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Position angle of the axis
|
|
52
|
+
|
|
53
|
+
`Astronoby::Moon#position_angle_of_axis` returns the position angle of the Moon's axis of rotation, the angle of the projection of the lunar north pole, measured eastward from the north point of the disk. It is returned as an `Astronoby::Angle`.
|
|
54
|
+
|
|
55
|
+
```rb
|
|
56
|
+
moon.position_angle_of_axis.str(:dms) # => "-21° 48′ 46.657″"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Position angle of the bright limb
|
|
60
|
+
|
|
61
|
+
`Astronoby::Moon#bright_limb_position_angle` returns the position angle of the midpoint of the illuminated limb, measured eastward from the north point of the disk, between 0 and 360 degrees. It is a geocentric quantity computed from the apparent equatorial coordinates of the Moon and the Sun, and it points towards the Sun, since the bright limb is the limb facing the Sun.
|
|
62
|
+
|
|
63
|
+
```rb
|
|
64
|
+
moon.bright_limb_position_angle.str(:dms) # => "+248° 1′ 57.9467″"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Parallactic angle
|
|
68
|
+
|
|
69
|
+
The parallactic angle is the angle at the Moon between the direction of the north celestial pole and the direction of the observer's zenith. Unlike the previous quantities it depends on the observer, so it is computed from the topocentric place, where lunar parallax is significant. `Astronoby::Moon#parallactic_angle` takes an observer and returns an `Astronoby::Angle`.
|
|
70
|
+
|
|
71
|
+
```rb
|
|
72
|
+
observer = Astronoby::Observer.new(
|
|
73
|
+
latitude: Astronoby::Angle.from_degrees(48.8566),
|
|
74
|
+
longitude: Astronoby::Angle.from_degrees(2.3522)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
moon.parallactic_angle(observer: observer).str(:dms) # => "+11° 42′ 47.1246″"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## See also
|
|
81
|
+
|
|
82
|
+
- [Solar System Bodies](solar_system_bodies.md) - for the Moon's other properties
|
|
83
|
+
- [Moon Phases](moon_phases.md) - for lunar phase events
|
|
84
|
+
- [Lunar Eclipses](lunar_eclipses.md) - for eclipses of the Moon
|
|
85
|
+
- [Observer](observer.md) - for setting up observation locations
|
|
86
|
+
- [Reference Frames](reference_frames.md) - for coordinate systems
|
|
87
|
+
- [Angles](angles.md) - for working with angular measurements
|
data/docs/moon_phases.md
CHANGED
|
@@ -69,11 +69,14 @@ phases.each { puts "#{_1.phase}: #{_1.time}" }
|
|
|
69
69
|
# new_moon: 2024-05-08 03:21:56 UTC
|
|
70
70
|
# first_quarter: 2024-05-15 11:48:02 UTC
|
|
71
71
|
# full_moon: 2024-05-23 13:53:12 UTC
|
|
72
|
-
# last_quarter: 2024-05-30 17:12:
|
|
72
|
+
# last_quarter: 2024-05-30 17:12:42 UTC
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
## See also
|
|
76
|
+
|
|
76
77
|
- [Twilight Times](twilight_times.md) - for sun-related events
|
|
77
78
|
- [Rise, Transit and Set Times](rise_transit_set_times.md) - for moon events
|
|
78
|
-
- [
|
|
79
|
+
- [Lunar Observation](lunar_observation.md) - for libration, axis and limb angles
|
|
80
|
+
- [Lunar Eclipses](lunar_eclipses.md) - for eclipses of the Moon
|
|
81
|
+
- [Solar System Bodies](solar_system_bodies.md) - for moon object details
|
|
79
82
|
- [Ephemerides](ephem.md) - for data sources
|
data/docs/observer.md
CHANGED
|
@@ -6,19 +6,31 @@ events computed by Astronoby are location and date based.
|
|
|
6
6
|
## Initialization
|
|
7
7
|
|
|
8
8
|
The two required key arguments to instantiate an observer are:
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
- `latitude` (`Astronoby::Angle`): the angle from the equator to the observer,
|
|
10
11
|
from 90° to -90°, with positive angles for the Northern Hemisphere.
|
|
11
|
-
|
|
12
|
+
- `longitude` (`Astronoby::Angle`): the angle from the Greenwich meridian to the
|
|
12
13
|
observer, from 180° to -180°, with positive angles eastward of the Greenwich
|
|
13
14
|
meridian.
|
|
14
15
|
|
|
15
|
-
Latitude and longitude are defined according to the [World Geodetic System]
|
|
16
|
-
In other words, they are the same as those used for the [GPS].
|
|
16
|
+
Latitude and longitude are defined according to the [World Geodetic System]
|
|
17
|
+
(WGS-84). In other words, they are the same as those used for the [GPS].
|
|
18
|
+
|
|
19
|
+
Internally, the observer's geodetic coordinates are converted to geocentric
|
|
20
|
+
Cartesian coordinates in the **International Terrestrial Reference System
|
|
21
|
+
(ITRS)**, also known as Earth-Centered Earth-Fixed (ECEF). These are then
|
|
22
|
+
rotated into the celestial frame using Earth rotation (GAST) via
|
|
23
|
+
`Astronoby::EarthRotation` and IERS polar motion corrections. See
|
|
24
|
+
[Reference Frames](reference_frames.md) for details.
|
|
25
|
+
|
|
26
|
+
The reverse conversion (ECEF → geodetic) is available via
|
|
27
|
+
[`Astronoby::Coordinates::Geodetic.from_ecef`][Coordinates page].
|
|
17
28
|
|
|
18
29
|
It is also possible to give the following optional key arguments:
|
|
19
|
-
|
|
30
|
+
|
|
31
|
+
- `elevation` (`Astronoby::Distance`): the distance above or below the average
|
|
20
32
|
sea level
|
|
21
|
-
|
|
33
|
+
- `utc_offset`: local time difference with UTC. Check the [timezone specifiers]
|
|
22
34
|
for the format.
|
|
23
35
|
|
|
24
36
|
```rb
|
|
@@ -57,9 +69,11 @@ observer1 == observer2
|
|
|
57
69
|
[GPS]: https://en.wikipedia.org/wiki/GPS
|
|
58
70
|
[timezone specifiers]: https://ruby-doc.org/3.4.1/Time.html#class-Time-label-Timezone+Specifiers
|
|
59
71
|
[Angles page]: angles.md
|
|
72
|
+
[Coordinates page]: coordinates.md#geodetic
|
|
60
73
|
|
|
61
74
|
## See also
|
|
75
|
+
|
|
62
76
|
- [Angles](angles.md) - for working with latitude and longitude
|
|
63
77
|
- [Coordinates](coordinates.md) - for understanding position systems
|
|
64
78
|
- [Reference Frames](reference_frames.md) - for topocentric calculations
|
|
65
|
-
- [
|
|
79
|
+
- [Solar System Bodies](solar_system_bodies.md) - for observing objects
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Planetary Phenomena
|
|
2
|
+
|
|
3
|
+
Astronoby computes the classic planetary phenomena relative to the Sun: conjunctions, oppositions, and greatest elongations. They are all defined in the apparent geocentric ecliptic frame of date.
|
|
4
|
+
|
|
5
|
+
The available phenomena depend on the planet. Inferior planets (Mercury and Venus) have conjunctions and greatest elongations. Superior planets (Mars to Neptune) have conjunctions and oppositions. Requesting a phenomenon that cannot occur for a given body raises an `Astronoby::UnsupportedEventError`.
|
|
6
|
+
|
|
7
|
+
Each method takes an ephemeris and a time range, and returns the events found within that range.
|
|
8
|
+
|
|
9
|
+
## Oppositions
|
|
10
|
+
|
|
11
|
+
An opposition is the instant when a superior planet and the Sun have opposite apparent ecliptic longitudes (a difference of 180 degrees), so the planet is opposite the Sun in the sky.
|
|
12
|
+
|
|
13
|
+
```rb
|
|
14
|
+
ephem = Astronoby::Ephem.load("inpop19a.bsp")
|
|
15
|
+
|
|
16
|
+
opposition = Astronoby::Mars.opposition_events(
|
|
17
|
+
ephem: ephem,
|
|
18
|
+
start_time: Time.utc(2025, 1, 1),
|
|
19
|
+
end_time: Time.utc(2026, 1, 1)
|
|
20
|
+
).first
|
|
21
|
+
|
|
22
|
+
opposition.instant.to_time # => 2025-01-16 02:38:35 UTC
|
|
23
|
+
opposition.body # => Astronoby::Mars
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Conjunctions
|
|
27
|
+
|
|
28
|
+
A conjunction is the instant when a planet and the Sun share the same apparent ecliptic longitude. Each conjunction is classified as inferior (the planet passes between the Earth and the Sun) or superior (the planet passes behind the Sun), determined from the apparent distances. Superior planets only ever have superior conjunctions.
|
|
29
|
+
|
|
30
|
+
```rb
|
|
31
|
+
conjunction = Astronoby::Venus.conjunction_events(
|
|
32
|
+
ephem: ephem,
|
|
33
|
+
start_time: Time.utc(2025, 1, 1),
|
|
34
|
+
end_time: Time.utc(2026, 1, 1)
|
|
35
|
+
).first
|
|
36
|
+
|
|
37
|
+
conjunction.instant.to_time # => 2025-03-23 01:07:30 UTC
|
|
38
|
+
conjunction.inferior? # => true
|
|
39
|
+
conjunction.superior? # => false
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Greatest elongations
|
|
43
|
+
|
|
44
|
+
A greatest elongation is the instant when an inferior planet reaches its maximum apparent angular separation from the Sun. It is eastern when the planet is east of the Sun (visible in the evening sky) and western when it is west of the Sun (visible in the morning sky).
|
|
45
|
+
|
|
46
|
+
```rb
|
|
47
|
+
elongation = Astronoby::Mercury.greatest_elongation_events(
|
|
48
|
+
ephem: ephem,
|
|
49
|
+
start_time: Time.utc(2025, 1, 1),
|
|
50
|
+
end_time: Time.utc(2026, 1, 1)
|
|
51
|
+
).first
|
|
52
|
+
|
|
53
|
+
elongation.instant.to_time # => 2025-03-08 06:09:18 UTC
|
|
54
|
+
elongation.angle.degrees # => 18.25
|
|
55
|
+
elongation.eastern? # => true
|
|
56
|
+
elongation.western? # => false
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Elongation of a body
|
|
60
|
+
|
|
61
|
+
The elongation of any Solar System body, the apparent Sun-Earth-body angle, is also available directly on a body instance, along with the side of the Sun it lies on.
|
|
62
|
+
|
|
63
|
+
```rb
|
|
64
|
+
instant = Astronoby::Instant.from_time(Time.utc(2025, 7, 14))
|
|
65
|
+
venus = Astronoby::Venus.new(instant: instant, ephem: ephem)
|
|
66
|
+
|
|
67
|
+
venus.elongation.degrees # => 41.47
|
|
68
|
+
venus.eastern? # => false
|
|
69
|
+
venus.western? # => true
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## See also
|
|
73
|
+
|
|
74
|
+
- [Solar System Bodies](solar_system_bodies.md) - for planets and their properties
|
|
75
|
+
- [Equinoxes and Solstices Times](equinoxes_solstices_times.md) - for solar events
|
|
76
|
+
- [Moon Phases](moon_phases.md) - for lunar events
|
|
77
|
+
- [Reference Frames](reference_frames.md) - for coordinate systems
|
|
78
|
+
- [Ephemerides](ephem.md) - for data sources
|