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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +145 -3
  4. data/README.md +59 -33
  5. data/UPGRADING.md +75 -21
  6. data/docs/README.md +224 -0
  7. data/docs/angles.md +137 -0
  8. data/docs/configuration.md +98 -0
  9. data/docs/coordinates.md +167 -0
  10. data/docs/deep_sky_bodies.md +101 -0
  11. data/docs/ephem.md +85 -0
  12. data/docs/equinoxes_solstices_times.md +31 -0
  13. data/docs/glossary.md +152 -0
  14. data/docs/instant.md +139 -0
  15. data/docs/moon_phases.md +79 -0
  16. data/docs/observer.md +65 -0
  17. data/docs/reference_frames.md +138 -0
  18. data/docs/rise_transit_set_times.md +119 -0
  19. data/docs/solar_system_bodies.md +107 -0
  20. data/docs/twilight_times.md +123 -0
  21. data/lib/astronoby/angle.rb +6 -2
  22. data/lib/astronoby/angular_velocity.rb +76 -0
  23. data/lib/astronoby/bodies/deep_sky_object.rb +44 -0
  24. data/lib/astronoby/bodies/deep_sky_object_position.rb +127 -0
  25. data/lib/astronoby/bodies/earth.rb +12 -2
  26. data/lib/astronoby/bodies/jupiter.rb +17 -0
  27. data/lib/astronoby/bodies/mars.rb +17 -0
  28. data/lib/astronoby/bodies/mercury.rb +21 -0
  29. data/lib/astronoby/bodies/moon.rb +50 -36
  30. data/lib/astronoby/bodies/neptune.rb +21 -0
  31. data/lib/astronoby/bodies/saturn.rb +26 -0
  32. data/lib/astronoby/bodies/solar_system_body.rb +162 -27
  33. data/lib/astronoby/bodies/sun.rb +25 -2
  34. data/lib/astronoby/bodies/uranus.rb +5 -0
  35. data/lib/astronoby/bodies/venus.rb +25 -0
  36. data/lib/astronoby/cache.rb +189 -0
  37. data/lib/astronoby/configuration.rb +92 -0
  38. data/lib/astronoby/constants.rb +11 -3
  39. data/lib/astronoby/constellation.rb +12 -0
  40. data/lib/astronoby/constellations/data.rb +42 -0
  41. data/lib/astronoby/constellations/finder.rb +35 -0
  42. data/lib/astronoby/constellations/repository.rb +20 -0
  43. data/lib/astronoby/coordinates/equatorial.rb +5 -8
  44. data/lib/astronoby/data/constellations/constellation_names.dat +88 -0
  45. data/lib/astronoby/data/constellations/indexed_abbreviations.dat +88 -0
  46. data/lib/astronoby/data/constellations/radec_to_index.dat +238 -0
  47. data/lib/astronoby/data/constellations/sorted_declinations.dat +202 -0
  48. data/lib/astronoby/data/constellations/sorted_right_ascensions.dat +237 -0
  49. data/lib/astronoby/distance.rb +6 -0
  50. data/lib/astronoby/equinox_solstice.rb +2 -2
  51. data/lib/astronoby/events/extremum_calculator.rb +233 -0
  52. data/lib/astronoby/events/extremum_event.rb +15 -0
  53. data/lib/astronoby/events/moon_phases.rb +15 -14
  54. data/lib/astronoby/events/rise_transit_set_calculator.rb +39 -12
  55. data/lib/astronoby/events/twilight_calculator.rb +116 -61
  56. data/lib/astronoby/events/twilight_events.rb +28 -0
  57. data/lib/astronoby/instant.rb +34 -6
  58. data/lib/astronoby/julian_date.rb +78 -0
  59. data/lib/astronoby/mean_obliquity.rb +8 -10
  60. data/lib/astronoby/nutation.rb +11 -3
  61. data/lib/astronoby/observer.rb +1 -1
  62. data/lib/astronoby/precession.rb +48 -38
  63. data/lib/astronoby/reference_frame.rb +2 -1
  64. data/lib/astronoby/reference_frames/apparent.rb +1 -11
  65. data/lib/astronoby/reference_frames/mean_of_date.rb +1 -1
  66. data/lib/astronoby/reference_frames/topocentric.rb +2 -12
  67. data/lib/astronoby/stellar_propagation.rb +162 -0
  68. data/lib/astronoby/time/greenwich_apparent_sidereal_time.rb +22 -0
  69. data/lib/astronoby/time/greenwich_mean_sidereal_time.rb +64 -0
  70. data/lib/astronoby/time/greenwich_sidereal_time.rb +20 -58
  71. data/lib/astronoby/time/local_apparent_sidereal_time.rb +42 -0
  72. data/lib/astronoby/time/local_mean_sidereal_time.rb +42 -0
  73. data/lib/astronoby/time/local_sidereal_time.rb +35 -26
  74. data/lib/astronoby/time/sidereal_time.rb +42 -0
  75. data/lib/astronoby/true_obliquity.rb +2 -3
  76. data/lib/astronoby/util/time.rb +62 -44
  77. data/lib/astronoby/velocity.rb +5 -0
  78. data/lib/astronoby/version.rb +1 -1
  79. data/lib/astronoby.rb +19 -1
  80. metadata +71 -11
  81. data/Gemfile +0 -5
  82. data/Gemfile.lock +0 -102
  83. data/benchmark/README.md +0 -131
  84. data/benchmark/benchmark.rb +0 -259
  85. data/benchmark/data/imcce.csv.zip +0 -0
  86. data/benchmark/data/sun_calc.csv.zip +0 -0
  87. data/lib/astronoby/epoch.rb +0 -22
@@ -3,11 +3,28 @@
3
3
  module Astronoby
4
4
  class Sun < SolarSystemBody
5
5
  EQUATORIAL_RADIUS = Distance.from_meters(695_700_000)
6
+ ABSOLUTE_MAGNITUDE = -26.74
6
7
 
7
8
  def self.ephemeris_segments(_ephem_source)
8
9
  [[SOLAR_SYSTEM_BARYCENTER, SUN]]
9
10
  end
10
11
 
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
15
+
16
+ # Source:
17
+ # Title: Explanatory Supplement to the Astronomical Almanac
18
+ # Authors: Sean E. Urban and P. Kenneth Seidelmann
19
+ # Edition: University Science Books
20
+ # Chapter: 10.3 - Phases and Magnitudes
21
+ # Apparent magnitude of the body, as seen from Earth.
22
+ # @return [Float] Apparent magnitude of the body.
23
+ def apparent_magnitude
24
+ @apparent_magnitude ||=
25
+ self.class.absolute_magnitude + 5 * Math.log10(astrometric.distance.au)
26
+ end
27
+
11
28
  # Source:
12
29
  # Title: Astronomical Algorithms
13
30
  # Author: Jean Meeus
@@ -17,7 +34,7 @@ module Astronoby
17
34
  # @return [Integer] Equation of time in seconds
18
35
  def equation_of_time
19
36
  right_ascension = apparent.equatorial.right_ascension
20
- t = (@instant.julian_date - Epoch::J2000) / Constants::DAYS_PER_JULIAN_MILLENIA
37
+ t = (@instant.julian_date - JulianDate::J2000) / Constants::DAYS_PER_JULIAN_MILLENIA
21
38
  l0 = (280.4664567 +
22
39
  360_007.6982779 * t +
23
40
  0.03032028 * t**2 +
@@ -25,7 +42,7 @@ module Astronoby
25
42
  t**4 / 15_300 -
26
43
  t**5 / 2_000_000) % Constants::DEGREES_PER_CIRCLE
27
44
  nutation = Nutation.new(instant: instant).nutation_in_longitude
28
- obliquity = TrueObliquity.for_epoch(@instant.julian_date)
45
+ obliquity = TrueObliquity.at(@instant)
29
46
 
30
47
  (
31
48
  Angle
@@ -37,5 +54,11 @@ module Astronoby
37
54
  ).hours * Constants::SECONDS_PER_HOUR
38
55
  ).round
39
56
  end
57
+
58
+ private
59
+
60
+ def requires_sun_data?
61
+ false
62
+ end
40
63
  end
41
64
  end
@@ -3,9 +3,14 @@
3
3
  module Astronoby
4
4
  class Uranus < SolarSystemBody
5
5
  EQUATORIAL_RADIUS = Distance.from_meters(25_559_000)
6
+ ABSOLUTE_MAGNITUDE = -7.11
6
7
 
7
8
  def self.ephemeris_segments(_ephem_source)
8
9
  [[SOLAR_SYSTEM_BARYCENTER, URANUS_BARYCENTER]]
9
10
  end
11
+
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
10
15
  end
11
16
  end
@@ -3,9 +3,34 @@
3
3
  module Astronoby
4
4
  class Venus < SolarSystemBody
5
5
  EQUATORIAL_RADIUS = Distance.from_meters(6_051_800)
6
+ ABSOLUTE_MAGNITUDE = -4.384
6
7
 
7
8
  def self.ephemeris_segments(_ephem_source)
8
9
  [[SOLAR_SYSTEM_BARYCENTER, VENUS_BARYCENTER]]
9
10
  end
11
+
12
+ def self.absolute_magnitude
13
+ ABSOLUTE_MAGNITUDE
14
+ end
15
+
16
+ private
17
+
18
+ # Source:
19
+ # Title: Computing Apparent Planetary Magnitudes for The Astronomical
20
+ # Almanac (2018)
21
+ # Authors: Anthony Mallama and James L. Hilton
22
+ def magnitude_correction_term
23
+ phase_angle_degrees = phase_angle.degrees
24
+ if phase_angle_degrees < 163.7
25
+ -1.044 * 10**-3 * phase_angle_degrees +
26
+ 3.687 * 10**-4 * phase_angle_degrees * phase_angle_degrees -
27
+ 2.814 * 10**-6 * phase_angle_degrees**3 +
28
+ 8.938 * 10**-9 * phase_angle_degrees**4
29
+
30
+ else
31
+ 240.44228 - 2.81914 * phase_angle_degrees +
32
+ 8.39034 * 10**-3 * phase_angle_degrees * phase_angle_degrees
33
+ end
34
+ end
10
35
  end
11
36
  end
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+ require "singleton"
5
+
6
+ module Astronoby
7
+ class Cache
8
+ include Singleton
9
+
10
+ Entry = Struct.new(:key, :value, :prev, :next)
11
+
12
+ DEFAULT_MAX_SIZE = 10_000
13
+
14
+ attr_reader :max_size
15
+
16
+ # @param max_size [Integer] Maximum number of entries allowed in the cache
17
+ # @return [void]
18
+ def initialize(max_size = DEFAULT_MAX_SIZE)
19
+ @max_size = max_size
20
+ @hash = {}
21
+ @head = nil
22
+ @tail = nil
23
+ @mutex = Monitor.new
24
+ end
25
+
26
+ # @param key [Object] the cache key
27
+ # @return [Object, nil] the value, or nil if not found
28
+ def [](key)
29
+ @mutex.synchronize do
30
+ entry = @hash[key]
31
+ if entry
32
+ move_to_head(entry)
33
+ entry.value
34
+ end
35
+ end
36
+ end
37
+
38
+ # @param key [Object]
39
+ # @param value [Object]
40
+ # @return [Object] the value set
41
+ def []=(key, value)
42
+ @mutex.synchronize do
43
+ entry = @hash[key]
44
+ if entry
45
+ entry.value = value
46
+ move_to_head(entry)
47
+ else
48
+ entry = Entry.new(key, value)
49
+ add_to_head(entry)
50
+ @hash[key] = entry
51
+ evict_last_recently_used if @hash.size > @max_size
52
+ end
53
+ end
54
+ end
55
+
56
+ # @param key [Object]
57
+ # @yieldreturn [Object] Value to store if key is missing.
58
+ # @return [Object] Cached or computed value.
59
+ def fetch(key)
60
+ return self[key] if @mutex.synchronize { @hash.key?(key) }
61
+
62
+ value = yield
63
+
64
+ @mutex.synchronize do
65
+ self[key] = value unless @hash.key?(key)
66
+ end
67
+
68
+ value
69
+ end
70
+
71
+ # @return [void]
72
+ def clear
73
+ @mutex.synchronize do
74
+ @hash.clear
75
+ @head = @tail = nil
76
+ end
77
+ end
78
+
79
+ # @return [Integer]
80
+ def size
81
+ @mutex.synchronize { @hash.size }
82
+ end
83
+
84
+ # @param new_size [Integer] the new cache limit.
85
+ # @return [void]
86
+ def max_size=(new_size)
87
+ raise ArgumentError, "max_size must be positive" unless new_size > 0
88
+
89
+ @mutex.synchronize do
90
+ @max_size = new_size
91
+ while @hash.size > @max_size
92
+ evict_last_recently_used
93
+ end
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ def add_to_head(entry)
100
+ entry.prev = nil
101
+ entry.next = @head
102
+ @head.prev = entry if @head
103
+ @head = entry
104
+ @tail ||= entry
105
+ end
106
+
107
+ def move_to_head(entry)
108
+ return if @head == entry
109
+
110
+ # Unlink
111
+ entry.prev.next = entry.next if entry.prev
112
+ entry.next.prev = entry.prev if entry.next
113
+
114
+ # Update tail if needed
115
+ @tail = entry.prev if @tail == entry
116
+
117
+ # Insert as new head
118
+ entry.prev = nil
119
+ entry.next = @head
120
+ @head.prev = entry if @head
121
+ @head = entry
122
+ end
123
+
124
+ def evict_last_recently_used
125
+ if @tail
126
+ @hash.delete(@tail.key)
127
+ if @tail.prev
128
+ @tail = @tail.prev
129
+ @tail.next = nil
130
+ else
131
+ @head = @tail = nil
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ class NullCache
138
+ include Singleton
139
+
140
+ def [](key)
141
+ nil
142
+ end
143
+
144
+ def []=(key, value)
145
+ value
146
+ end
147
+
148
+ def fetch(key)
149
+ yield
150
+ end
151
+
152
+ def clear
153
+ end
154
+
155
+ def size
156
+ 0
157
+ end
158
+
159
+ def max_size=(new_size)
160
+ end
161
+ end
162
+
163
+ class CacheKey
164
+ class << self
165
+ # Generate a cache key with appropriate precision
166
+ # @param type [Symbol] The calculation type (e.g., :geometric, :nutation)
167
+ # @param instant [Astronoby::Instant] The time instant
168
+ # @param components [Array] Additional components for the key
169
+ # @return [Array] The complete cache key
170
+ def generate(type, instant, *components)
171
+ return nil unless Astronoby.configuration.cache_enabled?
172
+
173
+ precision = Astronoby.configuration.cache_precision(type)
174
+ rounded_tt = round_terrestrial_time(instant.tt, precision)
175
+ [type, rounded_tt, *components]
176
+ end
177
+
178
+ # Round terrestrial time to specified precision
179
+ # @param tt [Numeric] Terrestrial time value
180
+ # @param precision [Numeric] Precision in seconds
181
+ # @return [Numeric] Rounded time value
182
+ def round_terrestrial_time(tt, precision)
183
+ return tt if precision <= 0
184
+
185
+ tt.round(precision)
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Configuration
5
+ DEFAULT_PRECISIONS = {
6
+ geometric: 9, # 8.64e-5 seconds
7
+ nutation: 2, # 864 seconds
8
+ precession: 2, # 864 seconds
9
+ rise_transit_set: 5 # 0.1 seconds
10
+ }.freeze
11
+
12
+ attr_accessor :cache_enabled
13
+ attr_reader :cache_precisions
14
+
15
+ def initialize
16
+ @cache_enabled = false
17
+ @cache_precisions = DEFAULT_PRECISIONS.dup
18
+ @cache_instance = nil
19
+ end
20
+
21
+ # Configure cache precision for specific calculation types
22
+ # @param type [Symbol] The calculation type
23
+ # @param precision [Numeric] Precision in rounding of terrestrial time
24
+ # @return [Numeric] the precision for the given type
25
+ def cache_precision(type, precision = nil)
26
+ if precision.nil?
27
+ @cache_precisions[type] || DEFAULT_PRECISIONS[:geometric]
28
+ else
29
+ @cache_precisions[type] = precision
30
+ end
31
+ end
32
+
33
+ # Set all cache precisions at once
34
+ # @param precisions [Hash] Hash of calculation type to precision in rounding
35
+ # of terrestrial time
36
+ # @return [void]
37
+ def cache_precisions=(precisions)
38
+ @cache_precisions = DEFAULT_PRECISIONS.merge(precisions)
39
+ end
40
+
41
+ # Get the cache instance (singleton or null cache)
42
+ # @return [Astronoby::Cache, Astronoby::NullCache] the cache instance
43
+ def cache
44
+ if cache_enabled?
45
+ Cache.instance
46
+ else
47
+ NullCache.instance
48
+ end
49
+ end
50
+
51
+ def cache_enabled?
52
+ @cache_enabled
53
+ end
54
+
55
+ # Reset cache instance (useful for testing or configuration changes)
56
+ # @return [void]
57
+ def reset_cache!
58
+ cache.clear
59
+ end
60
+ end
61
+
62
+ class << self
63
+ # Global configuration instance
64
+ # @return [Astronoby::Configuration] the global configuration instance
65
+ def configuration
66
+ @configuration ||= Configuration.new
67
+ end
68
+
69
+ # Configuration block for setup
70
+ # @example
71
+ # Astronoby.configure do |config|
72
+ # config.cache_enabled = false
73
+ # config.cache_precision(:geometric, 9)
74
+ # end
75
+ def configure
76
+ yield(configuration)
77
+ configuration.reset_cache!
78
+ end
79
+
80
+ # Quick access to cache
81
+ # @return [Astronoby::Cache, Astronoby::NullCache] the cache instance
82
+ def cache
83
+ configuration.cache
84
+ end
85
+
86
+ # Reset configuration to defaults
87
+ # @return [void]
88
+ def reset_configuration!
89
+ @configuration = Configuration.new
90
+ end
91
+ end
92
+ end
@@ -2,28 +2,36 @@
2
2
 
3
3
  module Astronoby
4
4
  class Constants
5
- DAYS_PER_JULIAN_CENTURY = 36525.0
5
+ DAYS_PER_JULIAN_YEAR = 365.25
6
+ DAYS_PER_JULIAN_CENTURY = DAYS_PER_JULIAN_YEAR * 100
6
7
  DAYS_PER_JULIAN_MILLENIA = DAYS_PER_JULIAN_CENTURY * 10
7
8
 
9
+ TROPICAL_YEAR_AT_B1900 = 365.242198781
10
+
8
11
  HOURS_PER_DAY = 24.0
9
12
  DEGREES_PER_CIRCLE = 360.0
10
13
  RADIANS_PER_CIRCLE = 2 * Math::PI
11
14
 
12
15
  SECONDS_PER_MINUTE = 60.0
13
16
  MINUTES_PER_HOUR = 60.0
14
- MINUTES_PER_DEGREE = 60.0
15
-
16
17
  SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR
17
18
  SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY
19
+ SECONDS_PER_JULIAN_YEAR = SECONDS_PER_DAY * DAYS_PER_JULIAN_YEAR
18
20
  RADIAN_PER_HOUR = Math::PI / 12.0
19
21
  MICROSECOND_IN_DAYS = 1.0 / SECONDS_PER_DAY / 1e6
20
22
 
23
+ ARCMINUTES_PER_DEGREE = 60.0
24
+ ARC_SECONDS_PER_ARCMINUTE = 60.0
25
+ ARCSECONDS_PER_DEGREE = ARC_SECONDS_PER_ARCMINUTE * ARCMINUTES_PER_DEGREE
26
+ MILLIARCSECONDS_PER_DEGREE = ARCSECONDS_PER_DEGREE * 1000
27
+
21
28
  PI_IN_DEGREES = 180.0
22
29
 
23
30
  EQUATION_OF_TIME_CONSTANT = 0.0057183
24
31
 
25
32
  KILOMETER_IN_METERS = 1_000
26
33
  ASTRONOMICAL_UNIT_IN_METERS = 149_597_870_700
34
+ PARSEC_IN_METERS = 3.0856775814913673e16
27
35
  EARTH_EQUATORIAL_RADIUS_IN_METERS = 6378140
28
36
 
29
37
  # WGS84 Earth Constants
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Constellation
5
+ attr_reader :name, :abbreviation
6
+
7
+ def initialize(name, abbreviation)
8
+ @name = name
9
+ @abbreviation = abbreviation
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ module Constellations
5
+ class Data
6
+ def self.sorted_right_ascensions
7
+ @sorted_right_ascensions ||=
8
+ read_file("sorted_right_ascensions.dat").map(&:to_f)
9
+ end
10
+
11
+ def self.sorted_declinations
12
+ @sorted_declinations ||=
13
+ read_file("sorted_declinations.dat").map(&:to_f)
14
+ end
15
+
16
+ def self.radec_to_index
17
+ @radec_to_index ||=
18
+ read_file("radec_to_index.dat").map do |line|
19
+ line.split.map(&:to_i)
20
+ end
21
+ end
22
+
23
+ def self.indexed_abbreviations
24
+ @indexed_abbreviations ||=
25
+ read_file("indexed_abbreviations.dat")
26
+ end
27
+
28
+ def self.constellation_names
29
+ @constellation_names ||=
30
+ read_file("constellation_names.dat").map(&:split)
31
+ end
32
+
33
+ def self.read_file(filename)
34
+ File.readlines(data_path(filename)).map(&:strip)
35
+ end
36
+
37
+ def self.data_path(filename)
38
+ File.join(__dir__, "..", "data", "constellations", filename)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ module Constellations
5
+ class Finder
6
+ # Finds the constellation that contains the given B1875 equatorial
7
+ # coordinates.
8
+ # @param equatorial_coordinates [Astronoby::Coordinates::Equatorial] The
9
+ # B1875 coordinates to search for.
10
+ # @return [Astronoby::Constellation, nil] The constellation that contains
11
+ # the coordinates, or nil if none is found.
12
+ def self.find(equatorial_coordinates)
13
+ ra_hours = equatorial_coordinates.right_ascension.hours
14
+ dec_degrees = equatorial_coordinates.declination.degrees
15
+ ra_index = Data
16
+ .sorted_right_ascensions
17
+ .bsearch_index { _1 >= ra_hours }
18
+ dec_index = Data
19
+ .sorted_declinations
20
+ .bsearch_index { _1 > dec_degrees }
21
+
22
+ return if ra_index.nil? || dec_index.nil?
23
+
24
+ abbreviation_index = Data.radec_to_index.dig(ra_index, dec_index)
25
+
26
+ return if abbreviation_index.nil?
27
+
28
+ constellation_abbreviation =
29
+ Data.indexed_abbreviations[abbreviation_index]
30
+
31
+ Repository.get(constellation_abbreviation)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ module Constellations
5
+ class Repository
6
+ # Returns a constellation object for the given abbreviation.
7
+ # @param abbreviation [String] The abbreviation of the constellation.
8
+ # @return [Astronoby::Constellation, nil] The constellation object or nil
9
+ # if not found.
10
+ def self.get(abbreviation)
11
+ @constellations ||= Data.constellation_names.map do |abbr, name|
12
+ constellation = Constellation.new(name, abbr)
13
+ [abbr, constellation]
14
+ end.to_h
15
+
16
+ @constellations[abbreviation]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -9,7 +9,7 @@ module Astronoby
9
9
  declination:,
10
10
  right_ascension:,
11
11
  hour_angle: nil,
12
- epoch: Epoch::DEFAULT_EPOCH
12
+ epoch: JulianDate::DEFAULT_EPOCH
13
13
  )
14
14
  @right_ascension = right_ascension
15
15
  @declination = declination
@@ -42,11 +42,8 @@ module Astronoby
42
42
  end
43
43
 
44
44
  def compute_hour_angle(time:, longitude:)
45
- lst = GreenwichSiderealTime
46
- .from_utc(time.utc)
47
- .to_lst(longitude: longitude)
48
-
49
- ha = (lst.time - @right_ascension.hours)
45
+ last = LocalApparentSiderealTime.from_utc(time.utc, longitude: longitude)
46
+ ha = (last.time - @right_ascension.hours)
50
47
  ha += Constants::HOURS_PER_DAY if ha.negative?
51
48
 
52
49
  Angle.from_hours(ha)
@@ -82,8 +79,8 @@ module Astronoby
82
79
  # Author: J. L. Lawrence
83
80
  # Edition: MIT Press
84
81
  # Chapter: 4 - Orbits and Coordinate Systems
85
- def to_ecliptic(epoch:)
86
- mean_obliquity = MeanObliquity.for_epoch(epoch)
82
+ def to_ecliptic(instant:)
83
+ mean_obliquity = MeanObliquity.at(instant)
87
84
 
88
85
  y = Angle.from_radians(
89
86
  @right_ascension.sin * mean_obliquity.cos +
@@ -0,0 +1,88 @@
1
+ And Andromeda
2
+ Ant Antlia
3
+ Aps Apus
4
+ Aql Aquila
5
+ Aqr Aquarius
6
+ Ara Ara
7
+ Ari Aries
8
+ Aur Auriga
9
+ Boo Boötes
10
+ Cae Caelum
11
+ Cam Camelopardalis
12
+ Cap Capricornus
13
+ Car Carina
14
+ Cas Cassiopeia
15
+ Cen Centaurus
16
+ Cep Cepheus
17
+ Cet Cetus
18
+ Cha Chamaeleon
19
+ Cir Circinus
20
+ CMa Canis Major
21
+ CMi Canis Minor
22
+ Cnc Cancer
23
+ Col Columba
24
+ Com Coma Berenices
25
+ CrA Corona Australis
26
+ CrB Corona Borealis
27
+ Crt Crater
28
+ Cru Crux
29
+ Crv Corvus
30
+ CVn Canes Venatici
31
+ Cyg Cygnus
32
+ Del Delphinus
33
+ Dor Dorado
34
+ Dra Draco
35
+ Equ Equuleus
36
+ Eri Eridanus
37
+ For Fornax
38
+ Gem Gemini
39
+ Gru Grus
40
+ Her Hercules
41
+ Hor Horologium
42
+ Hya Hydra
43
+ Hyi Hydrus
44
+ Ind Indus
45
+ Lac Lacerta
46
+ Leo Leo
47
+ Lep Lepus
48
+ Lib Libra
49
+ LMi Leo Minor
50
+ Lup Lupus
51
+ Lyn Lynx
52
+ Lyr Lyra
53
+ Men Mensa
54
+ Mic Microscopium
55
+ Mon Monoceros
56
+ Mus Musca
57
+ Nor Norma
58
+ Oct Octans
59
+ Oph Ophiuchus
60
+ Ori Orion
61
+ Pav Pavo
62
+ Peg Pegasus
63
+ Per Perseus
64
+ Phe Phoenix
65
+ Pic Pictor
66
+ PsA Piscis Austrinus
67
+ Psc Pisces
68
+ Pup Puppis
69
+ Pyx Pyxis
70
+ Ret Reticulum
71
+ Scl Sculptor
72
+ Sco Scorpius
73
+ Sct Scutum
74
+ Ser Serpens
75
+ Sex Sextans
76
+ Sge Sagitta
77
+ Sgr Sagittarius
78
+ Tau Taurus
79
+ Tel Telescopium
80
+ TrA Triangulum Australe
81
+ Tri Triangulum
82
+ Tuc Tucana
83
+ UMa Ursa Major
84
+ UMi Ursa Minor
85
+ Vel Vela
86
+ Vir Virgo
87
+ Vol Volans
88
+ Vul Vulpecula