astronoby 0.3.0 → 0.4.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/CHANGELOG.md +72 -0
- data/Gemfile.lock +3 -3
- data/README.md +52 -17
- data/UPGRADING.md +24 -0
- data/lib/astronoby/aberration.rb +7 -5
- data/lib/astronoby/angle.rb +26 -34
- data/lib/astronoby/bodies/sun.rb +117 -122
- data/lib/astronoby/constants.rb +25 -0
- data/lib/astronoby/coordinates/ecliptic.rb +4 -4
- data/lib/astronoby/coordinates/equatorial.rb +3 -2
- data/lib/astronoby/coordinates/horizontal.rb +6 -2
- data/lib/astronoby/epoch.rb +0 -2
- data/lib/astronoby/equinox_solstice.rb +3 -2
- data/lib/astronoby/events/observation_events.rb +319 -0
- data/lib/astronoby/events/twilight_events.rb +121 -0
- data/lib/astronoby/geocentric_parallax.rb +2 -2
- data/lib/astronoby/mean_obliquity.rb +2 -2
- data/lib/astronoby/nutation.rb +5 -3
- data/lib/astronoby/observer.rb +33 -14
- data/lib/astronoby/precession.rb +1 -1
- 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 +5 -1
- metadata +8 -4
- data/lib/astronoby/body.rb +0 -155
@@ -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"
|
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,10 @@
|
|
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"
|
6
7
|
require "astronoby/epoch"
|
7
|
-
require "astronoby/body"
|
8
8
|
require "astronoby/bodies/sun"
|
9
9
|
require "astronoby/coordinates/ecliptic"
|
10
10
|
require "astronoby/coordinates/equatorial"
|
@@ -12,6 +12,8 @@ require "astronoby/coordinates/horizontal"
|
|
12
12
|
require "astronoby/aberration"
|
13
13
|
require "astronoby/equinox_solstice"
|
14
14
|
require "astronoby/errors"
|
15
|
+
require "astronoby/events/observation_events"
|
16
|
+
require "astronoby/events/twilight_events"
|
15
17
|
require "astronoby/geocentric_parallax"
|
16
18
|
require "astronoby/mean_obliquity"
|
17
19
|
require "astronoby/nutation"
|
@@ -21,6 +23,8 @@ require "astronoby/refraction"
|
|
21
23
|
require "astronoby/time/greenwich_sidereal_time"
|
22
24
|
require "astronoby/time/local_sidereal_time"
|
23
25
|
require "astronoby/util/astrodynamics"
|
26
|
+
require "astronoby/util/maths"
|
27
|
+
require "astronoby/util/time"
|
24
28
|
require "astronoby/util/trigonometry"
|
25
29
|
require "astronoby/true_obliquity"
|
26
30
|
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.4.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-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: matrix
|
@@ -92,13 +92,15 @@ files:
|
|
92
92
|
- lib/astronoby/angles/dms.rb
|
93
93
|
- lib/astronoby/angles/hms.rb
|
94
94
|
- lib/astronoby/bodies/sun.rb
|
95
|
-
- lib/astronoby/
|
95
|
+
- lib/astronoby/constants.rb
|
96
96
|
- lib/astronoby/coordinates/ecliptic.rb
|
97
97
|
- lib/astronoby/coordinates/equatorial.rb
|
98
98
|
- lib/astronoby/coordinates/horizontal.rb
|
99
99
|
- lib/astronoby/epoch.rb
|
100
100
|
- lib/astronoby/equinox_solstice.rb
|
101
101
|
- lib/astronoby/errors.rb
|
102
|
+
- lib/astronoby/events/observation_events.rb
|
103
|
+
- lib/astronoby/events/twilight_events.rb
|
102
104
|
- lib/astronoby/geocentric_parallax.rb
|
103
105
|
- lib/astronoby/mean_obliquity.rb
|
104
106
|
- lib/astronoby/nutation.rb
|
@@ -109,6 +111,8 @@ files:
|
|
109
111
|
- lib/astronoby/time/local_sidereal_time.rb
|
110
112
|
- lib/astronoby/true_obliquity.rb
|
111
113
|
- lib/astronoby/util/astrodynamics.rb
|
114
|
+
- lib/astronoby/util/maths.rb
|
115
|
+
- lib/astronoby/util/time.rb
|
112
116
|
- lib/astronoby/util/trigonometry.rb
|
113
117
|
- lib/astronoby/version.rb
|
114
118
|
homepage: https://github.com/rhannequin/astronoby
|
@@ -126,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
130
|
requirements:
|
127
131
|
- - ">="
|
128
132
|
- !ruby/object:Gem::Version
|
129
|
-
version: 3.
|
133
|
+
version: 3.0.0
|
130
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
135
|
requirements:
|
132
136
|
- - ">="
|
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
|