astronoby 0.7.0 → 0.9.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 +145 -3
- data/README.md +59 -33
- data/UPGRADING.md +75 -21
- data/docs/README.md +224 -0
- data/docs/angles.md +137 -0
- data/docs/configuration.md +98 -0
- data/docs/coordinates.md +167 -0
- data/docs/deep_sky_bodies.md +101 -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/solar_system_bodies.md +107 -0
- data/docs/twilight_times.md +123 -0
- data/lib/astronoby/angle.rb +6 -2
- data/lib/astronoby/angular_velocity.rb +76 -0
- data/lib/astronoby/bodies/deep_sky_object.rb +44 -0
- data/lib/astronoby/bodies/deep_sky_object_position.rb +127 -0
- data/lib/astronoby/bodies/earth.rb +12 -2
- data/lib/astronoby/bodies/jupiter.rb +17 -0
- data/lib/astronoby/bodies/mars.rb +17 -0
- data/lib/astronoby/bodies/mercury.rb +21 -0
- data/lib/astronoby/bodies/moon.rb +50 -36
- data/lib/astronoby/bodies/neptune.rb +21 -0
- data/lib/astronoby/bodies/saturn.rb +26 -0
- data/lib/astronoby/bodies/solar_system_body.rb +162 -27
- data/lib/astronoby/bodies/sun.rb +25 -2
- data/lib/astronoby/bodies/uranus.rb +5 -0
- data/lib/astronoby/bodies/venus.rb +25 -0
- data/lib/astronoby/cache.rb +189 -0
- data/lib/astronoby/configuration.rb +92 -0
- data/lib/astronoby/constants.rb +11 -3
- 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/equatorial.rb +5 -8
- 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/distance.rb +6 -0
- data/lib/astronoby/equinox_solstice.rb +2 -2
- data/lib/astronoby/events/extremum_calculator.rb +233 -0
- data/lib/astronoby/events/extremum_event.rb +15 -0
- data/lib/astronoby/events/moon_phases.rb +15 -14
- data/lib/astronoby/events/rise_transit_set_calculator.rb +39 -12
- data/lib/astronoby/events/twilight_calculator.rb +116 -61
- data/lib/astronoby/events/twilight_events.rb +28 -0
- data/lib/astronoby/instant.rb +34 -6
- data/lib/astronoby/julian_date.rb +78 -0
- data/lib/astronoby/mean_obliquity.rb +8 -10
- data/lib/astronoby/nutation.rb +11 -3
- data/lib/astronoby/observer.rb +1 -1
- data/lib/astronoby/precession.rb +48 -38
- data/lib/astronoby/reference_frame.rb +2 -1
- data/lib/astronoby/reference_frames/apparent.rb +1 -11
- data/lib/astronoby/reference_frames/mean_of_date.rb +1 -1
- data/lib/astronoby/reference_frames/topocentric.rb +2 -12
- data/lib/astronoby/stellar_propagation.rb +162 -0
- data/lib/astronoby/time/greenwich_apparent_sidereal_time.rb +22 -0
- data/lib/astronoby/time/greenwich_mean_sidereal_time.rb +64 -0
- data/lib/astronoby/time/greenwich_sidereal_time.rb +20 -58
- data/lib/astronoby/time/local_apparent_sidereal_time.rb +42 -0
- data/lib/astronoby/time/local_mean_sidereal_time.rb +42 -0
- data/lib/astronoby/time/local_sidereal_time.rb +35 -26
- data/lib/astronoby/time/sidereal_time.rb +42 -0
- data/lib/astronoby/true_obliquity.rb +2 -3
- data/lib/astronoby/util/time.rb +62 -44
- data/lib/astronoby/velocity.rb +5 -0
- data/lib/astronoby/version.rb +1 -1
- data/lib/astronoby.rb +19 -1
- metadata +71 -11
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -102
- 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/epoch.rb +0 -22
data/lib/astronoby/precession.rb
CHANGED
|
@@ -16,41 +16,43 @@ module Astronoby
|
|
|
16
16
|
# https://syrte.obspm.fr/iau2006/aa03_412_P03.pdf
|
|
17
17
|
# P(t) = R3(χA) R1(−ωA) R3(−ψA) R1(ϵ0)
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
19
|
+
cache.fetch(cache_key) do
|
|
20
|
+
# Precession in right ascension
|
|
21
|
+
psi_a = ((((
|
|
22
|
+
-0.0000000951 * t +
|
|
23
|
+
+0.000132851) * t +
|
|
24
|
+
-0.00114045) * t +
|
|
25
|
+
-1.0790069) * t +
|
|
26
|
+
+5038.481507) * t
|
|
27
|
+
|
|
28
|
+
# Precession in declination
|
|
29
|
+
omega_a = ((((
|
|
30
|
+
+0.0000003337 * t +
|
|
31
|
+
-0.000000467) * t +
|
|
32
|
+
-0.00772503) * t +
|
|
33
|
+
+0.0512623) * t +
|
|
34
|
+
-0.025754) * t +
|
|
35
|
+
eps0
|
|
36
|
+
|
|
37
|
+
# Precession of the ecliptic
|
|
38
|
+
chi_a = ((((
|
|
39
|
+
-0.0000000560 * t +
|
|
40
|
+
+0.000170663) * t +
|
|
41
|
+
-0.00121197) * t +
|
|
42
|
+
-2.3814292) * t +
|
|
43
|
+
+10.556403) * t
|
|
44
|
+
|
|
45
|
+
psi_a = Angle.from_degree_arcseconds(psi_a)
|
|
46
|
+
omega_a = Angle.from_degree_arcseconds(omega_a)
|
|
47
|
+
chi_a = Angle.from_degree_arcseconds(chi_a)
|
|
48
|
+
|
|
49
|
+
r3_psi = rotation_z(-psi_a)
|
|
50
|
+
r1_omega = rotation_x(-omega_a)
|
|
51
|
+
r3_chi = rotation_z(chi_a)
|
|
52
|
+
r1_eps0 = rotation_x(MeanObliquity.obliquity_of_reference)
|
|
53
|
+
|
|
54
|
+
r3_chi * r1_omega * r3_psi * r1_eps0
|
|
55
|
+
end
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def rotation_x(angle)
|
|
@@ -106,7 +108,7 @@ module Astronoby
|
|
|
106
108
|
end
|
|
107
109
|
|
|
108
110
|
def self.matrix_for_epoch(epoch)
|
|
109
|
-
t = (epoch -
|
|
111
|
+
t = (epoch - JulianDate::DEFAULT_EPOCH) / Constants::DAYS_PER_JULIAN_CENTURY
|
|
110
112
|
|
|
111
113
|
zeta = Angle.from_degrees(
|
|
112
114
|
0.6406161 * t + 0.0000839 * t * t + 0.000005 * t * t * t
|
|
@@ -146,15 +148,23 @@ module Astronoby
|
|
|
146
148
|
|
|
147
149
|
private
|
|
148
150
|
|
|
151
|
+
def cache_key
|
|
152
|
+
@_cache_key ||= CacheKey.generate(:precession, @instant)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def cache
|
|
156
|
+
Astronoby.cache
|
|
157
|
+
end
|
|
158
|
+
|
|
149
159
|
def t
|
|
150
160
|
@t ||= Rational(
|
|
151
|
-
@instant.tdb -
|
|
161
|
+
@instant.tdb - JulianDate::DEFAULT_EPOCH,
|
|
152
162
|
Constants::DAYS_PER_JULIAN_CENTURY
|
|
153
163
|
)
|
|
154
164
|
end
|
|
155
165
|
|
|
156
166
|
def eps0
|
|
157
|
-
@eps0 ||= MeanObliquity.
|
|
167
|
+
@eps0 ||= MeanObliquity.obliquity_of_reference_in_arcseconds
|
|
158
168
|
end
|
|
159
169
|
end
|
|
160
170
|
end
|
|
@@ -34,7 +34,8 @@ module Astronoby
|
|
|
34
34
|
@ecliptic ||= begin
|
|
35
35
|
return Coordinates::Ecliptic.zero if distance.zero?
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
j2000 = Instant.from_terrestrial_time(JulianDate::J2000)
|
|
38
|
+
equatorial.to_ecliptic(instant: j2000)
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
|
|
@@ -43,17 +43,7 @@ module Astronoby
|
|
|
43
43
|
@ecliptic ||= begin
|
|
44
44
|
return Coordinates::Ecliptic.zero if distance.zero?
|
|
45
45
|
|
|
46
|
-
equatorial.to_ecliptic(
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def angular_diameter
|
|
51
|
-
@angular_radius ||= begin
|
|
52
|
-
return Angle.zero if @position.zero?
|
|
53
|
-
|
|
54
|
-
Angle.from_radians(
|
|
55
|
-
Math.atan(@target_body.class::EQUATORIAL_RADIUS.m / distance.m) * 2
|
|
56
|
-
)
|
|
46
|
+
equatorial.to_ecliptic(instant: @instant)
|
|
57
47
|
end
|
|
58
48
|
end
|
|
59
49
|
end
|
|
@@ -14,7 +14,7 @@ module Astronoby
|
|
|
14
14
|
matrix * observer.geocentric_position.map(&:m)
|
|
15
15
|
)
|
|
16
16
|
observer_velocity = Velocity.vector_from_mps(
|
|
17
|
-
matrix * observer.geocentric_velocity.map(&:
|
|
17
|
+
matrix * observer.geocentric_velocity.map(&:mps)
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
position = apparent.position - observer_position
|
|
@@ -48,21 +48,11 @@ module Astronoby
|
|
|
48
48
|
@observer = observer
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def angular_diameter
|
|
52
|
-
@angular_radius ||= begin
|
|
53
|
-
return Angle.zero if @position.zero?
|
|
54
|
-
|
|
55
|
-
Angle.from_radians(
|
|
56
|
-
Math.atan(@target_body.class::EQUATORIAL_RADIUS.m / distance.m) * 2
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
51
|
def ecliptic
|
|
62
52
|
@ecliptic ||= begin
|
|
63
53
|
return Coordinates::Ecliptic.zero if distance.zero?
|
|
64
54
|
|
|
65
|
-
equatorial.to_ecliptic(
|
|
55
|
+
equatorial.to_ecliptic(instant: @instant)
|
|
66
56
|
end
|
|
67
57
|
end
|
|
68
58
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Astronoby
|
|
4
|
+
class StellarPropagation
|
|
5
|
+
# @return [Astronoby::Vector] Propagated position vector of
|
|
6
|
+
# Astronoby::Distance components
|
|
7
|
+
def self.position_for(**kwargs)
|
|
8
|
+
new(**kwargs).position
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [Astronoby::Vector] Propagated position vector of
|
|
12
|
+
# Astronoby::Velocity components
|
|
13
|
+
def self.velocity_vector_for(**kwargs)
|
|
14
|
+
new(**kwargs).velocity_vector
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [Astronoby::Coordinates::Equatorial] Propagated equatorial
|
|
18
|
+
# coordinates
|
|
19
|
+
def self.equatorial_coordinates_for(**kwargs)
|
|
20
|
+
new(**kwargs).equatorial_coordinates
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @param instant [Astronoby::Instant] Instant of the observation
|
|
24
|
+
# @param equatorial_coordinates [Astronoby::Coordinates::Equatorial]
|
|
25
|
+
# Equatorial coordinates at epoch J2000.0
|
|
26
|
+
# @param proper_motion_ra [Astronoby::AngularVelocity] Proper motion in
|
|
27
|
+
# right ascension
|
|
28
|
+
# @param proper_motion_dec [Astronoby::AngularVelocity] Proper motion in
|
|
29
|
+
# declination
|
|
30
|
+
# @param parallax [Astronoby::Angle] Parallax angle
|
|
31
|
+
# @param radial_velocity [Astronoby::Velocity] Radial velocity
|
|
32
|
+
# @param earth_geometric [Astronoby::ReferenceFrame::Geometric, nil]
|
|
33
|
+
# Geometric reference frame of the Earth
|
|
34
|
+
def initialize(
|
|
35
|
+
instant:,
|
|
36
|
+
equatorial_coordinates:,
|
|
37
|
+
proper_motion_ra:,
|
|
38
|
+
proper_motion_dec:,
|
|
39
|
+
parallax:,
|
|
40
|
+
radial_velocity:,
|
|
41
|
+
earth_geometric: nil
|
|
42
|
+
)
|
|
43
|
+
@instant = instant
|
|
44
|
+
@right_ascension = equatorial_coordinates.right_ascension
|
|
45
|
+
@declination = equatorial_coordinates.declination
|
|
46
|
+
@initial_epoch = equatorial_coordinates.epoch
|
|
47
|
+
@proper_motion_ra = proper_motion_ra
|
|
48
|
+
@proper_motion_dec = proper_motion_dec
|
|
49
|
+
@parallax = parallax
|
|
50
|
+
@radial_velocity = radial_velocity
|
|
51
|
+
@earth_geometric = earth_geometric
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @return [Astronoby::Vector] Propagated position vector of
|
|
55
|
+
# Astronoby::Distance components
|
|
56
|
+
def position
|
|
57
|
+
@position ||= Distance.vector_from_meters(
|
|
58
|
+
initial_position_vector +
|
|
59
|
+
tangential_velocity.map(&:mps) * time_elapsed_seconds
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [Astronoby::Vector] Propagated position vector of
|
|
64
|
+
# Astronoby::Velocity components
|
|
65
|
+
def velocity_vector
|
|
66
|
+
@velocity_vector ||= if @earth_geometric
|
|
67
|
+
@earth_geometric.velocity - tangential_velocity
|
|
68
|
+
else
|
|
69
|
+
tangential_velocity
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Astronoby::Coordinates::Equatorial] Propagated equatorial
|
|
74
|
+
# coordinates
|
|
75
|
+
def equatorial_coordinates
|
|
76
|
+
@equatorial_coordinates ||= begin
|
|
77
|
+
right_ascension = Util::Trigonometry.adjustement_for_arctangent(
|
|
78
|
+
position.y.m,
|
|
79
|
+
position.x.m,
|
|
80
|
+
Angle.atan(position.y.m / position.x.m)
|
|
81
|
+
)
|
|
82
|
+
declination = Angle.asin(position.z.m / position.magnitude.m)
|
|
83
|
+
|
|
84
|
+
Coordinates::Equatorial.new(
|
|
85
|
+
right_ascension: right_ascension,
|
|
86
|
+
declination: declination,
|
|
87
|
+
epoch: @instant.tt
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def distance
|
|
95
|
+
@distance ||= Distance.from_parsecs(
|
|
96
|
+
1 / (@parallax.degrees * Constants::ARCSECONDS_PER_DEGREE)
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def unit_position_vector
|
|
101
|
+
@unit_position_vector ||= Vector[
|
|
102
|
+
@right_ascension.cos * @declination.cos,
|
|
103
|
+
@right_ascension.sin * @declination.cos,
|
|
104
|
+
@declination.sin
|
|
105
|
+
]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def right_ascension_unit_vector
|
|
109
|
+
@right_ascension_unit_vector ||= Vector[
|
|
110
|
+
-@right_ascension.sin,
|
|
111
|
+
@right_ascension.cos,
|
|
112
|
+
0.0
|
|
113
|
+
]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def declination_unit_vector
|
|
117
|
+
@declination_unit_vector ||= Vector[
|
|
118
|
+
-@right_ascension.cos * @declination.sin,
|
|
119
|
+
-@right_ascension.sin * @declination.sin,
|
|
120
|
+
@declination.cos
|
|
121
|
+
]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def initial_position_vector
|
|
125
|
+
@initial_position_vector ||= unit_position_vector * distance.meters
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def tangential_velocity
|
|
129
|
+
@tangential_velocity ||= begin
|
|
130
|
+
# Doppler factor for light travel time correction
|
|
131
|
+
k = 1.0 / (1.0 - @radial_velocity.kmps / Velocity.light_speed.kmps)
|
|
132
|
+
|
|
133
|
+
proper_motion_ra_component =
|
|
134
|
+
@proper_motion_ra.mas_per_year / (
|
|
135
|
+
@parallax.degree_milliarcseconds * Constants::DAYS_PER_JULIAN_YEAR
|
|
136
|
+
) * k
|
|
137
|
+
proper_motion_dec_component =
|
|
138
|
+
@proper_motion_dec.mas_per_year / (
|
|
139
|
+
@parallax.degree_milliarcseconds * Constants::DAYS_PER_JULIAN_YEAR
|
|
140
|
+
) * k
|
|
141
|
+
radial_velocity_component = Velocity
|
|
142
|
+
.from_kmps(@radial_velocity.kmps * k)
|
|
143
|
+
|
|
144
|
+
Velocity.vector_from_astronomical_units_per_day([
|
|
145
|
+
-proper_motion_ra_component * @right_ascension.sin -
|
|
146
|
+
proper_motion_dec_component * @declination.sin * @right_ascension.cos +
|
|
147
|
+
radial_velocity_component.aupd * @declination.cos * @right_ascension.cos,
|
|
148
|
+
proper_motion_ra_component * @right_ascension.cos -
|
|
149
|
+
proper_motion_dec_component * @declination.sin * @right_ascension.sin +
|
|
150
|
+
radial_velocity_component.aupd * @declination.cos * @right_ascension.sin,
|
|
151
|
+
proper_motion_dec_component * @declination.cos +
|
|
152
|
+
radial_velocity_component.aupd * @declination.sin
|
|
153
|
+
])
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def time_elapsed_seconds
|
|
158
|
+
@time_elapsed_seconds ||=
|
|
159
|
+
(@instant.tt - @initial_epoch) * Constants::SECONDS_PER_DAY
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Astronoby
|
|
4
|
+
class GreenwichApparentSiderealTime < GreenwichSiderealTime
|
|
5
|
+
def self.from_utc(utc)
|
|
6
|
+
gmst = GreenwichMeanSiderealTime.from_utc(utc)
|
|
7
|
+
instant = Instant.from_time(utc)
|
|
8
|
+
nutation = Nutation.new(instant: instant)
|
|
9
|
+
mean_obliquity = MeanObliquity.at(instant)
|
|
10
|
+
|
|
11
|
+
equation_of_equinoxes = nutation.nutation_in_longitude.hours *
|
|
12
|
+
mean_obliquity.cos
|
|
13
|
+
gast_time = normalize_time(gmst.time + equation_of_equinoxes)
|
|
14
|
+
|
|
15
|
+
new(date: gmst.date, time: gast_time)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(date:, time:)
|
|
19
|
+
super(date: date, time: time, type: APPARENT)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Astronoby
|
|
4
|
+
class GreenwichMeanSiderealTime < GreenwichSiderealTime
|
|
5
|
+
JULIAN_CENTURIES_EXPONENTS = [
|
|
6
|
+
6.697374558,
|
|
7
|
+
2400.051336,
|
|
8
|
+
0.000025862
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
SIDEREAL_MINUTE_IN_UT_MINUTE = 0.9972695663
|
|
12
|
+
|
|
13
|
+
# Source:
|
|
14
|
+
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
15
|
+
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
16
|
+
# Edition: Cambridge University Press
|
|
17
|
+
# Chapter: 12 - Conversion of UT to Greenwich sidereal time (GST)
|
|
18
|
+
def self.from_utc(utc)
|
|
19
|
+
date = utc.to_date
|
|
20
|
+
julian_day = utc.to_date.ajd
|
|
21
|
+
t = (julian_day - JulianDate::J2000) / Constants::DAYS_PER_JULIAN_CENTURY
|
|
22
|
+
t0 = (
|
|
23
|
+
(JULIAN_CENTURIES_EXPONENTS[0] +
|
|
24
|
+
(JULIAN_CENTURIES_EXPONENTS[1] * t) +
|
|
25
|
+
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) % Constants::HOURS_PER_DAY
|
|
26
|
+
).abs
|
|
27
|
+
|
|
28
|
+
ut_in_hours = utc.hour +
|
|
29
|
+
utc.min / Constants::MINUTES_PER_HOUR +
|
|
30
|
+
(utc.sec + utc.subsec) / Constants::SECONDS_PER_HOUR
|
|
31
|
+
|
|
32
|
+
gmst = normalize_time(1.002737909 * ut_in_hours + t0)
|
|
33
|
+
|
|
34
|
+
new(date: date, time: gmst)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize(date:, time:)
|
|
38
|
+
super(date: date, time: time, type: MEAN)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Source:
|
|
42
|
+
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
43
|
+
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
44
|
+
# Edition: Cambridge University Press
|
|
45
|
+
# Chapter: 13 - Conversion of GST to UT
|
|
46
|
+
def to_utc
|
|
47
|
+
date = @date
|
|
48
|
+
julian_day = @date.ajd
|
|
49
|
+
t = (julian_day - JulianDate::J2000) / Constants::DAYS_PER_JULIAN_CENTURY
|
|
50
|
+
|
|
51
|
+
t0 = (
|
|
52
|
+
(JULIAN_CENTURIES_EXPONENTS[0] +
|
|
53
|
+
(JULIAN_CENTURIES_EXPONENTS[1] * t) +
|
|
54
|
+
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) % Constants::HOURS_PER_DAY
|
|
55
|
+
).abs
|
|
56
|
+
|
|
57
|
+
a = normalize_time(@time - t0)
|
|
58
|
+
|
|
59
|
+
utc = SIDEREAL_MINUTE_IN_UT_MINUTE * a
|
|
60
|
+
|
|
61
|
+
Util::Time.decimal_hour_to_time(date, 0, utc)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -1,71 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Astronoby
|
|
4
|
-
class GreenwichSiderealTime
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# Source:
|
|
16
|
-
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
17
|
-
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
18
|
-
# Edition: Cambridge University Press
|
|
19
|
-
# Chapter: 12 - Conversion of UT to Greenwich sidereal time (GST)
|
|
20
|
-
def self.from_utc(utc)
|
|
21
|
-
date = utc.to_date
|
|
22
|
-
julian_day = utc.to_date.ajd
|
|
23
|
-
t = (julian_day - Epoch::J2000) / Constants::DAYS_PER_JULIAN_CENTURY
|
|
24
|
-
t0 = (
|
|
25
|
-
(JULIAN_CENTURIES_EXPONENTS[0] +
|
|
26
|
-
(JULIAN_CENTURIES_EXPONENTS[1] * t) +
|
|
27
|
-
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) % Constants::HOURS_PER_DAY
|
|
28
|
-
).abs
|
|
29
|
-
|
|
30
|
-
ut_in_hours = utc.hour +
|
|
31
|
-
utc.min / Constants::MINUTES_PER_HOUR +
|
|
32
|
-
(utc.sec + utc.subsec) / Constants::SECONDS_PER_HOUR
|
|
33
|
-
|
|
34
|
-
gmst = 1.002737909 * ut_in_hours + t0
|
|
35
|
-
gmst += Constants::HOURS_PER_DAY if gmst.negative?
|
|
36
|
-
gmst -= Constants::HOURS_PER_DAY if gmst > Constants::HOURS_PER_DAY
|
|
4
|
+
class GreenwichSiderealTime < SiderealTime
|
|
5
|
+
def self.from_utc(utc, type: MEAN)
|
|
6
|
+
validate_type!(type)
|
|
7
|
+
case type
|
|
8
|
+
when MEAN
|
|
9
|
+
GreenwichMeanSiderealTime.from_utc(utc)
|
|
10
|
+
when APPARENT
|
|
11
|
+
GreenwichApparentSiderealTime.from_utc(utc)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
37
14
|
|
|
38
|
-
|
|
15
|
+
def self.mean_from_utc(utc)
|
|
16
|
+
GreenwichMeanSiderealTime.from_utc(utc)
|
|
39
17
|
end
|
|
40
18
|
|
|
41
|
-
def
|
|
42
|
-
|
|
43
|
-
@time = time
|
|
19
|
+
def self.apparent_from_utc(utc)
|
|
20
|
+
GreenwichApparentSiderealTime.from_utc(utc)
|
|
44
21
|
end
|
|
45
22
|
|
|
46
|
-
# Source:
|
|
47
|
-
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
48
|
-
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
49
|
-
# Edition: Cambridge University Press
|
|
50
|
-
# Chapter: 13 - Conversion of GST to UT
|
|
51
23
|
def to_utc
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
t0 = (
|
|
57
|
-
(JULIAN_CENTURIES_EXPONENTS[0] +
|
|
58
|
-
(JULIAN_CENTURIES_EXPONENTS[1] * t) +
|
|
59
|
-
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) % Constants::HOURS_PER_DAY
|
|
60
|
-
).abs
|
|
61
|
-
|
|
62
|
-
a = @time - t0
|
|
63
|
-
a += Constants::HOURS_PER_DAY if a.negative?
|
|
64
|
-
a -= Constants::HOURS_PER_DAY if a > Constants::HOURS_PER_DAY
|
|
65
|
-
|
|
66
|
-
utc = SIDEREAL_MINUTE_IN_UT_MINUTE * a
|
|
24
|
+
unless mean?
|
|
25
|
+
raise NotImplementedError,
|
|
26
|
+
"UTC conversion only supported for mean sidereal time"
|
|
27
|
+
end
|
|
67
28
|
|
|
68
|
-
|
|
29
|
+
gmst = GreenwichMeanSiderealTime.new(date: @date, time: @time)
|
|
30
|
+
gmst.to_utc
|
|
69
31
|
end
|
|
70
32
|
|
|
71
33
|
def to_lst(longitude:)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Astronoby
|
|
4
|
+
class LocalApparentSiderealTime < LocalSiderealTime
|
|
5
|
+
# Source:
|
|
6
|
+
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
7
|
+
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
8
|
+
# Edition: Cambridge University Press
|
|
9
|
+
# Chapter: 14 - Local sidereal time (LST)
|
|
10
|
+
def self.from_gst(gst:, longitude:)
|
|
11
|
+
unless gst.apparent?
|
|
12
|
+
raise ArgumentError, "GST must be apparent sidereal time"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
date = gst.date
|
|
16
|
+
time = normalize_time(gst.time + longitude.hours)
|
|
17
|
+
|
|
18
|
+
new(date: date, time: time, longitude: longitude)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.from_utc(utc, longitude:)
|
|
22
|
+
gast = GreenwichApparentSiderealTime.from_utc(utc)
|
|
23
|
+
from_gst(gst: gast, longitude: longitude)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(date:, time:, longitude:)
|
|
27
|
+
super(date: date, time: time, longitude: longitude, type: APPARENT)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Source:
|
|
31
|
+
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
32
|
+
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
33
|
+
# Edition: Cambridge University Press
|
|
34
|
+
# Chapter: 15 - Converting LST to GST
|
|
35
|
+
def to_gst
|
|
36
|
+
date = @date
|
|
37
|
+
time = normalize_time(@time - @longitude.hours)
|
|
38
|
+
|
|
39
|
+
GreenwichApparentSiderealTime.new(date: date, time: time)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Astronoby
|
|
4
|
+
class LocalMeanSiderealTime < LocalSiderealTime
|
|
5
|
+
# Source:
|
|
6
|
+
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
7
|
+
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
8
|
+
# Edition: Cambridge University Press
|
|
9
|
+
# Chapter: 14 - Local sidereal time (LST)
|
|
10
|
+
def self.from_gst(gst:, longitude:)
|
|
11
|
+
unless gst.mean?
|
|
12
|
+
raise ArgumentError, "GST must be mean sidereal time"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
date = gst.date
|
|
16
|
+
time = normalize_time(gst.time + longitude.hours)
|
|
17
|
+
|
|
18
|
+
new(date: date, time: time, longitude: longitude)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.from_utc(utc, longitude:)
|
|
22
|
+
gmst = GreenwichMeanSiderealTime.from_utc(utc)
|
|
23
|
+
from_gst(gst: gmst, longitude: longitude)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(date:, time:, longitude:)
|
|
27
|
+
super(date: date, time: time, longitude: longitude, type: MEAN)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Source:
|
|
31
|
+
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
|
32
|
+
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
|
33
|
+
# Edition: Cambridge University Press
|
|
34
|
+
# Chapter: 15 - Converting LST to GST
|
|
35
|
+
def to_gst
|
|
36
|
+
date = @date
|
|
37
|
+
time = normalize_time(@time - @longitude.hours)
|
|
38
|
+
|
|
39
|
+
GreenwichMeanSiderealTime.new(date: date, time: time)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|