astronoby 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +132 -0
- data/Gemfile.lock +19 -17
- data/README.md +195 -25
- data/UPGRADING.md +72 -0
- data/lib/astronoby/aberration.rb +7 -5
- data/lib/astronoby/angle.rb +26 -34
- data/lib/astronoby/astronomical_models/ephemeride_lunaire_parisienne.rb +143 -0
- data/lib/astronoby/astronomical_models/moon_phases_periodic_terms.rb +249 -0
- data/lib/astronoby/bodies/moon.rb +335 -0
- data/lib/astronoby/bodies/sun.rb +129 -132
- data/lib/astronoby/constants.rb +31 -0
- data/lib/astronoby/coordinates/ecliptic.rb +4 -4
- data/lib/astronoby/coordinates/equatorial.rb +7 -5
- data/lib/astronoby/coordinates/horizontal.rb +24 -12
- data/lib/astronoby/distance.rb +83 -0
- data/lib/astronoby/epoch.rb +0 -2
- data/lib/astronoby/equinox_solstice.rb +3 -2
- data/lib/astronoby/events/moon_phases.rb +143 -0
- data/lib/astronoby/events/observation_events.rb +259 -0
- data/lib/astronoby/events/rise_transit_set_iteration.rb +215 -0
- data/lib/astronoby/events/twilight_events.rb +121 -0
- data/lib/astronoby/geocentric_parallax.rb +36 -56
- data/lib/astronoby/mean_obliquity.rb +2 -2
- data/lib/astronoby/moon_phase.rb +43 -0
- data/lib/astronoby/nutation.rb +5 -3
- data/lib/astronoby/observer.rb +39 -18
- data/lib/astronoby/precession.rb +1 -1
- data/lib/astronoby/refraction.rb +8 -10
- data/lib/astronoby/time/greenwich_sidereal_time.rb +18 -29
- data/lib/astronoby/time/local_sidereal_time.rb +4 -4
- data/lib/astronoby/util/maths.rb +72 -0
- data/lib/astronoby/util/time.rb +88 -0
- data/lib/astronoby/util/trigonometry.rb +4 -4
- data/lib/astronoby/version.rb +1 -1
- data/lib/astronoby.rb +12 -1
- metadata +15 -4
- data/lib/astronoby/body.rb +0 -155
data/lib/astronoby/refraction.rb
CHANGED
@@ -5,17 +5,16 @@ module Astronoby
|
|
5
5
|
LOW_ALTITUDE_BODY_ANGLE = Angle.from_degrees(15)
|
6
6
|
ZENITH = Angle.from_degrees(90)
|
7
7
|
|
8
|
-
def self.angle(coordinates
|
9
|
-
new(coordinates
|
8
|
+
def self.angle(coordinates:)
|
9
|
+
new(coordinates).refraction_angle
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.correct_horizontal_coordinates(coordinates
|
13
|
-
new(coordinates
|
12
|
+
def self.correct_horizontal_coordinates(coordinates:)
|
13
|
+
new(coordinates).refract
|
14
14
|
end
|
15
15
|
|
16
|
-
def initialize(coordinates
|
16
|
+
def initialize(coordinates)
|
17
17
|
@coordinates = coordinates
|
18
|
-
@observer = observer
|
19
18
|
end
|
20
19
|
|
21
20
|
# Source:
|
@@ -27,8 +26,7 @@ module Astronoby
|
|
27
26
|
Coordinates::Horizontal.new(
|
28
27
|
azimuth: @coordinates.azimuth,
|
29
28
|
altitude: @coordinates.altitude + refraction_angle,
|
30
|
-
|
31
|
-
longitude: @coordinates.longitude
|
29
|
+
observer: @coordinates.observer
|
32
30
|
)
|
33
31
|
end
|
34
32
|
|
@@ -43,11 +41,11 @@ module Astronoby
|
|
43
41
|
private
|
44
42
|
|
45
43
|
def pressure
|
46
|
-
@_pressure ||= @observer.pressure
|
44
|
+
@_pressure ||= @coordinates.observer.pressure
|
47
45
|
end
|
48
46
|
|
49
47
|
def temperature
|
50
|
-
@_temperature ||= @observer.temperature
|
48
|
+
@_temperature ||= @coordinates.observer.temperature
|
51
49
|
end
|
52
50
|
|
53
51
|
def altitude_in_degrees
|
@@ -3,11 +3,13 @@
|
|
3
3
|
module Astronoby
|
4
4
|
class GreenwichSiderealTime
|
5
5
|
JULIAN_CENTURIES_EXPONENTS = [
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
6.697374558,
|
7
|
+
2400.051336,
|
8
|
+
0.000025862
|
9
9
|
].freeze
|
10
10
|
|
11
|
+
SIDEREAL_MINUTE_IN_UT_MINUTE = 0.9972695663
|
12
|
+
|
11
13
|
attr_reader :date, :time
|
12
14
|
|
13
15
|
# Source:
|
@@ -18,20 +20,20 @@ module Astronoby
|
|
18
20
|
def self.from_utc(utc)
|
19
21
|
date = utc.to_date
|
20
22
|
julian_day = utc.to_date.ajd
|
21
|
-
t = (julian_day - Epoch::J2000) /
|
23
|
+
t = (julian_day - Epoch::J2000) / Constants::DAYS_PER_JULIAN_CENTURY
|
22
24
|
t0 = (
|
23
25
|
(JULIAN_CENTURIES_EXPONENTS[0] +
|
24
26
|
(JULIAN_CENTURIES_EXPONENTS[1] * t) +
|
25
|
-
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) %
|
27
|
+
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) % Constants::HOURS_PER_DAY
|
26
28
|
).abs
|
27
29
|
|
28
30
|
ut_in_hours = utc.hour +
|
29
|
-
utc.min /
|
30
|
-
(utc.sec + utc.subsec) /
|
31
|
+
utc.min / Constants::MINUTES_PER_HOUR +
|
32
|
+
(utc.sec + utc.subsec) / Constants::SECONDS_PER_HOUR
|
31
33
|
|
32
|
-
gmst =
|
33
|
-
gmst +=
|
34
|
-
gmst -=
|
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
|
35
37
|
|
36
38
|
new(date: date, time: gmst)
|
37
39
|
end
|
@@ -49,38 +51,25 @@ module Astronoby
|
|
49
51
|
def to_utc
|
50
52
|
date = @date
|
51
53
|
julian_day = @date.ajd
|
52
|
-
t = (julian_day - Epoch::J2000) /
|
54
|
+
t = (julian_day - Epoch::J2000) / Constants::DAYS_PER_JULIAN_CENTURY
|
53
55
|
|
54
56
|
t0 = (
|
55
57
|
(JULIAN_CENTURIES_EXPONENTS[0] +
|
56
58
|
(JULIAN_CENTURIES_EXPONENTS[1] * t) +
|
57
|
-
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) %
|
59
|
+
(JULIAN_CENTURIES_EXPONENTS[2] * t * t)) % Constants::HOURS_PER_DAY
|
58
60
|
).abs
|
59
61
|
|
60
62
|
a = @time - t0
|
61
|
-
a +=
|
62
|
-
a -=
|
63
|
+
a += Constants::HOURS_PER_DAY if a.negative?
|
64
|
+
a -= Constants::HOURS_PER_DAY if a > Constants::HOURS_PER_DAY
|
63
65
|
|
64
|
-
utc =
|
66
|
+
utc = SIDEREAL_MINUTE_IN_UT_MINUTE * a
|
65
67
|
|
66
|
-
decimal_hour_to_time(date, utc)
|
68
|
+
Util::Time.decimal_hour_to_time(date, utc)
|
67
69
|
end
|
68
70
|
|
69
71
|
def to_lst(longitude:)
|
70
72
|
LocalSiderealTime.from_gst(gst: self, longitude: longitude)
|
71
73
|
end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def decimal_hour_to_time(date, decimal)
|
76
|
-
absolute_hour = decimal.abs
|
77
|
-
hour = absolute_hour.floor
|
78
|
-
decimal_minute = 60 * (absolute_hour - hour)
|
79
|
-
absolute_decimal_minute = (60 * (absolute_hour - hour)).abs
|
80
|
-
minute = decimal_minute.floor
|
81
|
-
second = 60 * (absolute_decimal_minute - absolute_decimal_minute.floor)
|
82
|
-
|
83
|
-
::Time.utc(date.year, date.month, date.day, hour, minute, second).round
|
84
|
-
end
|
85
74
|
end
|
86
75
|
end
|
@@ -12,8 +12,8 @@ module Astronoby
|
|
12
12
|
def self.from_gst(gst:, longitude:)
|
13
13
|
date = gst.date
|
14
14
|
time = gst.time + longitude.hours
|
15
|
-
time +=
|
16
|
-
time -=
|
15
|
+
time += Constants::HOURS_PER_DAY if time.negative?
|
16
|
+
time -= Constants::HOURS_PER_DAY if time > Constants::HOURS_PER_DAY
|
17
17
|
|
18
18
|
new(date: date, time: time, longitude: longitude)
|
19
19
|
end
|
@@ -32,8 +32,8 @@ module Astronoby
|
|
32
32
|
def to_gst
|
33
33
|
date = @date
|
34
34
|
time = @time - @longitude.hours
|
35
|
-
time +=
|
36
|
-
time -=
|
35
|
+
time += Constants::HOURS_PER_DAY if time.negative?
|
36
|
+
time -= Constants::HOURS_PER_DAY if time > Constants::HOURS_PER_DAY
|
37
37
|
|
38
38
|
GreenwichSiderealTime.new(date: date, time: time)
|
39
39
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Astronoby
|
4
|
+
module Util
|
5
|
+
module Maths
|
6
|
+
class << self
|
7
|
+
# Source:
|
8
|
+
# Title: Astronomical Algorithms
|
9
|
+
# Author: Jean Meeus
|
10
|
+
# Edition: 2nd edition
|
11
|
+
# Chapter: 3 - Interpolation
|
12
|
+
|
13
|
+
# @param values [Array<Numeric>] First term
|
14
|
+
# @param factor [Numeric] Interpolation factor
|
15
|
+
# @return [Float] Interpolated value
|
16
|
+
def interpolate(values, factor)
|
17
|
+
unless factor.between?(0, 1)
|
18
|
+
raise IncompatibleArgumentsError,
|
19
|
+
"Interpolation factor must be between 0 and 1, got #{factor}"
|
20
|
+
end
|
21
|
+
|
22
|
+
if values.length == 3
|
23
|
+
return interpolate_3_terms(values, factor)
|
24
|
+
elsif values.length == 5
|
25
|
+
return interpolate_5_terms(values, factor)
|
26
|
+
end
|
27
|
+
|
28
|
+
raise IncompatibleArgumentsError,
|
29
|
+
"Only 3 or 5 terms are supported for interpolation"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# @return [Float] Interpolated value
|
35
|
+
def interpolate_3_terms(terms, factor)
|
36
|
+
y1, y2, y3 = terms
|
37
|
+
|
38
|
+
a = y2 - y1
|
39
|
+
b = y3 - y2
|
40
|
+
c = b - a
|
41
|
+
|
42
|
+
y2 + (factor / 2.0) * (a + b + factor * c)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Float] Interpolated value
|
46
|
+
def interpolate_5_terms(terms, factor)
|
47
|
+
y1, y2, y3, y4, y5 = terms
|
48
|
+
|
49
|
+
a = y2 - y1
|
50
|
+
b = y3 - y2
|
51
|
+
c = y4 - y3
|
52
|
+
d = y5 - y4
|
53
|
+
|
54
|
+
e = b - a
|
55
|
+
f = c - b
|
56
|
+
g = d - c
|
57
|
+
|
58
|
+
h = f - e
|
59
|
+
j = g - f
|
60
|
+
|
61
|
+
k = j - h
|
62
|
+
|
63
|
+
y3 +
|
64
|
+
factor * ((b + c) / 2.0 - (h + j) / 12.0) +
|
65
|
+
factor**2 * (f / 2.0 - k / 24.0) +
|
66
|
+
factor**3 * (h + j) / 12.0 +
|
67
|
+
factor**4 * k / 24.0
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Astronoby
|
4
|
+
module Util
|
5
|
+
module Time
|
6
|
+
# @param date [Date]
|
7
|
+
# @param decimal [Numeric] Hour of the day, in decimal hours
|
8
|
+
# @return [::Time] Date and time
|
9
|
+
def self.decimal_hour_to_time(date, decimal)
|
10
|
+
absolute_hour = decimal.abs
|
11
|
+
hour = absolute_hour.floor
|
12
|
+
|
13
|
+
unless hour.between?(0, Constants::HOURS_PER_DAY)
|
14
|
+
raise(
|
15
|
+
IncompatibleArgumentsError,
|
16
|
+
"Hour must be between 0 and #{Constants::HOURS_PER_DAY.to_i}, got #{hour}"
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
decimal_minute = Constants::MINUTES_PER_HOUR * (absolute_hour - hour)
|
21
|
+
absolute_decimal_minute = (
|
22
|
+
Constants::MINUTES_PER_HOUR * (absolute_hour - hour)
|
23
|
+
).abs
|
24
|
+
minute = decimal_minute.floor
|
25
|
+
second = Constants::SECONDS_PER_MINUTE *
|
26
|
+
(absolute_decimal_minute - absolute_decimal_minute.floor)
|
27
|
+
|
28
|
+
::Time.utc(date.year, date.month, date.day, hour, minute, second).round
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param instant [Numeric, Time, Date, DateTime]
|
32
|
+
# @return [Integer, Float] Number of leap seconds for the given instant
|
33
|
+
def self.terrestrial_universal_time_delta(instant)
|
34
|
+
# Source:
|
35
|
+
# Title: Astronomical Algorithms
|
36
|
+
# Author: Jean Meeus
|
37
|
+
# Edition: 2nd edition
|
38
|
+
# Chapter: 10 - Dynamical Time and Universal Time
|
39
|
+
|
40
|
+
jd = case instant
|
41
|
+
when Numeric
|
42
|
+
instant
|
43
|
+
when ::Time, ::Date, ::DateTime
|
44
|
+
Epoch.from_time(instant)
|
45
|
+
else
|
46
|
+
raise IncompatibleArgumentsError,
|
47
|
+
"Expected a Numeric, Time, Date or DateTime object, got #{instant.class}"
|
48
|
+
end
|
49
|
+
|
50
|
+
return 69 if jd >= 2457754.5
|
51
|
+
return 68 if jd >= 2457204.5
|
52
|
+
return 67 if jd >= 2456109.5
|
53
|
+
return 66 if jd >= 2454832.5
|
54
|
+
return 65 if jd >= 2453736.5
|
55
|
+
return 64 if jd >= 2451179.5
|
56
|
+
return 63 if jd >= 2450814.5
|
57
|
+
|
58
|
+
theta = ((jd - Epoch::J1900) / 365.25) / 100.0
|
59
|
+
if (2415020.5...2450814.5).cover?(jd) # 1900 - 1997
|
60
|
+
return -2.44 +
|
61
|
+
87.24 * theta +
|
62
|
+
815.20 * theta**2 -
|
63
|
+
2_637.80 * theta**3 -
|
64
|
+
18_756.33 * theta**4 +
|
65
|
+
124_906.15 * theta**5 -
|
66
|
+
303_191.19 * theta**6 +
|
67
|
+
372_919.88 * theta**7 -
|
68
|
+
232_424.66 * theta**8 +
|
69
|
+
58_353.42 * theta**9
|
70
|
+
elsif (2378496.5...2415020.5).cover?(jd) # 1800 - 1899
|
71
|
+
return -2.5 +
|
72
|
+
228.95 * theta +
|
73
|
+
5_218.61 * theta**2 +
|
74
|
+
56_282.84 * theta**3 +
|
75
|
+
324_011.78 * theta**4 +
|
76
|
+
1_061_660.75 * theta**5 +
|
77
|
+
2_087_298.89 * theta**6 +
|
78
|
+
2_513_807.78 * theta**7 +
|
79
|
+
1_818_961.41 * theta**8 +
|
80
|
+
727_058.63 * theta**9 +
|
81
|
+
123_563.95 * theta**10
|
82
|
+
end
|
83
|
+
|
84
|
+
0.0
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "bigdecimal/math"
|
4
|
-
|
5
3
|
module Astronoby
|
6
4
|
module Util
|
7
5
|
module Trigonometry
|
@@ -15,10 +13,12 @@ module Astronoby
|
|
15
13
|
return angle if y.positive? && x.positive?
|
16
14
|
|
17
15
|
if y.negative? && x.positive?
|
18
|
-
return Angle.from_degrees(
|
16
|
+
return Angle.from_degrees(
|
17
|
+
angle.degrees + Constants::DEGREES_PER_CIRCLE
|
18
|
+
)
|
19
19
|
end
|
20
20
|
|
21
|
-
Angle.from_degrees(angle.degrees +
|
21
|
+
Angle.from_degrees(angle.degrees + Constants::DEGREES_PER_CIRCLE / 2)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
data/lib/astronoby/version.rb
CHANGED
data/lib/astronoby.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "astronoby/constants"
|
3
4
|
require "astronoby/angle"
|
4
5
|
require "astronoby/angles/dms"
|
5
6
|
require "astronoby/angles/hms"
|
7
|
+
require "astronoby/distance"
|
6
8
|
require "astronoby/epoch"
|
7
|
-
require "astronoby/
|
9
|
+
require "astronoby/astronomical_models/ephemeride_lunaire_parisienne"
|
10
|
+
require "astronoby/astronomical_models/moon_phases_periodic_terms"
|
11
|
+
require "astronoby/bodies/moon"
|
8
12
|
require "astronoby/bodies/sun"
|
9
13
|
require "astronoby/coordinates/ecliptic"
|
10
14
|
require "astronoby/coordinates/equatorial"
|
@@ -12,8 +16,13 @@ require "astronoby/coordinates/horizontal"
|
|
12
16
|
require "astronoby/aberration"
|
13
17
|
require "astronoby/equinox_solstice"
|
14
18
|
require "astronoby/errors"
|
19
|
+
require "astronoby/events/moon_phases"
|
20
|
+
require "astronoby/events/observation_events"
|
21
|
+
require "astronoby/events/rise_transit_set_iteration"
|
22
|
+
require "astronoby/events/twilight_events"
|
15
23
|
require "astronoby/geocentric_parallax"
|
16
24
|
require "astronoby/mean_obliquity"
|
25
|
+
require "astronoby/moon_phase"
|
17
26
|
require "astronoby/nutation"
|
18
27
|
require "astronoby/observer"
|
19
28
|
require "astronoby/precession"
|
@@ -21,6 +30,8 @@ require "astronoby/refraction"
|
|
21
30
|
require "astronoby/time/greenwich_sidereal_time"
|
22
31
|
require "astronoby/time/local_sidereal_time"
|
23
32
|
require "astronoby/util/astrodynamics"
|
33
|
+
require "astronoby/util/maths"
|
34
|
+
require "astronoby/util/time"
|
24
35
|
require "astronoby/util/trigonometry"
|
25
36
|
require "astronoby/true_obliquity"
|
26
37
|
require "astronoby/version"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: astronoby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémy Hannequin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: matrix
|
@@ -91,16 +91,25 @@ files:
|
|
91
91
|
- lib/astronoby/angle.rb
|
92
92
|
- lib/astronoby/angles/dms.rb
|
93
93
|
- lib/astronoby/angles/hms.rb
|
94
|
+
- lib/astronoby/astronomical_models/ephemeride_lunaire_parisienne.rb
|
95
|
+
- lib/astronoby/astronomical_models/moon_phases_periodic_terms.rb
|
96
|
+
- lib/astronoby/bodies/moon.rb
|
94
97
|
- lib/astronoby/bodies/sun.rb
|
95
|
-
- lib/astronoby/
|
98
|
+
- lib/astronoby/constants.rb
|
96
99
|
- lib/astronoby/coordinates/ecliptic.rb
|
97
100
|
- lib/astronoby/coordinates/equatorial.rb
|
98
101
|
- lib/astronoby/coordinates/horizontal.rb
|
102
|
+
- lib/astronoby/distance.rb
|
99
103
|
- lib/astronoby/epoch.rb
|
100
104
|
- lib/astronoby/equinox_solstice.rb
|
101
105
|
- lib/astronoby/errors.rb
|
106
|
+
- lib/astronoby/events/moon_phases.rb
|
107
|
+
- lib/astronoby/events/observation_events.rb
|
108
|
+
- lib/astronoby/events/rise_transit_set_iteration.rb
|
109
|
+
- lib/astronoby/events/twilight_events.rb
|
102
110
|
- lib/astronoby/geocentric_parallax.rb
|
103
111
|
- lib/astronoby/mean_obliquity.rb
|
112
|
+
- lib/astronoby/moon_phase.rb
|
104
113
|
- lib/astronoby/nutation.rb
|
105
114
|
- lib/astronoby/observer.rb
|
106
115
|
- lib/astronoby/precession.rb
|
@@ -109,6 +118,8 @@ files:
|
|
109
118
|
- lib/astronoby/time/local_sidereal_time.rb
|
110
119
|
- lib/astronoby/true_obliquity.rb
|
111
120
|
- lib/astronoby/util/astrodynamics.rb
|
121
|
+
- lib/astronoby/util/maths.rb
|
122
|
+
- lib/astronoby/util/time.rb
|
112
123
|
- lib/astronoby/util/trigonometry.rb
|
113
124
|
- lib/astronoby/version.rb
|
114
125
|
homepage: https://github.com/rhannequin/astronoby
|
@@ -126,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
137
|
requirements:
|
127
138
|
- - ">="
|
128
139
|
- !ruby/object:Gem::Version
|
129
|
-
version: 3.
|
140
|
+
version: 3.0.0
|
130
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
142
|
requirements:
|
132
143
|
- - ">="
|
data/lib/astronoby/body.rb
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Astronoby
|
4
|
-
class Body
|
5
|
-
DEFAULT_REFRACTION_VERTICAL_SHIFT = Angle.from_dms(0, 34, 0)
|
6
|
-
RISING_SETTING_HOUR_ANGLE_RATIO_RANGE = (-1..1)
|
7
|
-
|
8
|
-
def initialize(equatorial_coordinates)
|
9
|
-
@equatorial_coordinates = equatorial_coordinates
|
10
|
-
end
|
11
|
-
|
12
|
-
# Source:
|
13
|
-
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
14
|
-
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
15
|
-
# Edition: Cambridge University Press
|
16
|
-
# Chapter: 33 - Rising and setting
|
17
|
-
|
18
|
-
# @param latitude [Astronoby::Angle] Latitude of the observer
|
19
|
-
# @param longitude [Astronoby::Angle] Longitude of the observer
|
20
|
-
# @param date [Date] Date of the event
|
21
|
-
# @param apparent [Boolean] Compute apparent or true data
|
22
|
-
# @param vertical_shift [Astronoby::Angle] Vertical shift correction angle
|
23
|
-
# @return [Time, nil] Sunrise time
|
24
|
-
def rising_time(
|
25
|
-
latitude:,
|
26
|
-
longitude:,
|
27
|
-
date:,
|
28
|
-
apparent: true,
|
29
|
-
vertical_shift: nil
|
30
|
-
)
|
31
|
-
time_ratio = time_ratio(latitude, apparent, vertical_shift)
|
32
|
-
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)
|
33
|
-
|
34
|
-
hour_angle = Angle.acos(time_ratio)
|
35
|
-
local_sidereal_time = LocalSiderealTime.new(
|
36
|
-
date: date,
|
37
|
-
time: right_ascension.hours - hour_angle.hours,
|
38
|
-
longitude: longitude
|
39
|
-
)
|
40
|
-
|
41
|
-
local_sidereal_time.to_gst.to_utc
|
42
|
-
end
|
43
|
-
|
44
|
-
# Source:
|
45
|
-
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
46
|
-
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
47
|
-
# Edition: Cambridge University Press
|
48
|
-
# Chapter: 33 - Rising and setting
|
49
|
-
|
50
|
-
# @param latitude [Astronoby::Angle] Latitude of the observer
|
51
|
-
# @param apparent [Boolean] Compute apparent or true data
|
52
|
-
# @param vertical_shift [Astronoby::Angle] Vertical shift correction angle
|
53
|
-
# @return [Astronoby::Angle, nil] Sunrise azimuth
|
54
|
-
def rising_azimuth(latitude:, apparent: true, vertical_shift: nil)
|
55
|
-
time_ratio = time_ratio(latitude, apparent, vertical_shift)
|
56
|
-
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)
|
57
|
-
|
58
|
-
azimuth_ratio = azimuth_ratio(latitude, apparent, vertical_shift)
|
59
|
-
|
60
|
-
Angle.acos(azimuth_ratio)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Source:
|
64
|
-
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
65
|
-
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
66
|
-
# Edition: Cambridge University Press
|
67
|
-
# Chapter: 33 - Rising and setting
|
68
|
-
|
69
|
-
# @param latitude [Astronoby::Angle] Latitude of the observer
|
70
|
-
# @param longitude [Astronoby::Angle] Longitude of the observer
|
71
|
-
# @param date [Date] Date of the event
|
72
|
-
# @param apparent [Boolean] Compute apparent or true data
|
73
|
-
# @param vertical_shift [Astronoby::Angle] Vertical shift correction angle
|
74
|
-
# @return [Time, nil] Sunset time
|
75
|
-
def setting_time(
|
76
|
-
latitude:,
|
77
|
-
longitude:,
|
78
|
-
date:,
|
79
|
-
apparent: true,
|
80
|
-
vertical_shift: nil
|
81
|
-
)
|
82
|
-
time_ratio = time_ratio(latitude, apparent, vertical_shift)
|
83
|
-
return unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)
|
84
|
-
|
85
|
-
hour_angle = Angle.acos(time_ratio)
|
86
|
-
local_sidereal_time = LocalSiderealTime.new(
|
87
|
-
date: date,
|
88
|
-
time: right_ascension.hours + hour_angle.hours,
|
89
|
-
longitude: longitude
|
90
|
-
)
|
91
|
-
|
92
|
-
local_sidereal_time.to_gst.to_utc
|
93
|
-
end
|
94
|
-
|
95
|
-
# Source:
|
96
|
-
# Title: Practical Astronomy with your Calculator or Spreadsheet
|
97
|
-
# Authors: Peter Duffett-Smith and Jonathan Zwart
|
98
|
-
# Edition: Cambridge University Press
|
99
|
-
# Chapter: 33 - Rising and setting
|
100
|
-
|
101
|
-
# @param latitude [Astronoby::Angle] Latitude of the observer
|
102
|
-
# @param apparent [Boolean] Compute apparent or true data
|
103
|
-
# @param vertical_shift [Astronoby::Angle] Vertical shift correction angle
|
104
|
-
# @return [Astronoby::Angle, nil] Sunset azimuth
|
105
|
-
def setting_azimuth(latitude:, apparent: true, vertical_shift: nil)
|
106
|
-
time_ratio = time_ratio(latitude, apparent, vertical_shift)
|
107
|
-
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)
|
108
|
-
|
109
|
-
azimuth_ratio = azimuth_ratio(latitude, apparent, vertical_shift)
|
110
|
-
|
111
|
-
Angle.from_degrees(360 - Angle.acos(azimuth_ratio).degrees)
|
112
|
-
end
|
113
|
-
|
114
|
-
private
|
115
|
-
|
116
|
-
def time_ratio(latitude, apparent, vertical_shift)
|
117
|
-
shift = if vertical_shift
|
118
|
-
vertical_shift
|
119
|
-
elsif apparent
|
120
|
-
DEFAULT_REFRACTION_VERTICAL_SHIFT
|
121
|
-
else
|
122
|
-
Angle.zero
|
123
|
-
end
|
124
|
-
|
125
|
-
term1 = shift.sin + latitude.sin * declination.sin
|
126
|
-
term2 = latitude.cos * declination.cos
|
127
|
-
|
128
|
-
-term1 / term2
|
129
|
-
end
|
130
|
-
|
131
|
-
def azimuth_ratio(latitude, apparent, vertical_shift)
|
132
|
-
shift = if vertical_shift
|
133
|
-
vertical_shift
|
134
|
-
elsif apparent
|
135
|
-
DEFAULT_REFRACTION_VERTICAL_SHIFT
|
136
|
-
else
|
137
|
-
Angle.zero
|
138
|
-
end
|
139
|
-
|
140
|
-
(declination.sin + shift.sin * latitude.cos) / (shift.cos * latitude.cos)
|
141
|
-
end
|
142
|
-
|
143
|
-
def azimuth_component(latitude)
|
144
|
-
declination.sin / latitude.cos
|
145
|
-
end
|
146
|
-
|
147
|
-
def right_ascension
|
148
|
-
@equatorial_coordinates.right_ascension
|
149
|
-
end
|
150
|
-
|
151
|
-
def declination
|
152
|
-
@equatorial_coordinates.declination
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|