astronoby 0.9.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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +101 -0
  4. data/README.md +6 -1
  5. data/UPGRADING.md +84 -0
  6. data/docs/README.md +80 -15
  7. data/docs/angles.md +1 -0
  8. data/docs/configuration.md +20 -17
  9. data/docs/coordinates.md +72 -12
  10. data/docs/deep_sky_bodies.md +1 -1
  11. data/docs/ephem.md +5 -2
  12. data/docs/equinoxes_solstices_times.md +4 -3
  13. data/docs/glossary.md +97 -1
  14. data/docs/iers.md +40 -0
  15. data/docs/instant.md +20 -15
  16. data/docs/lunar_eclipses.md +93 -0
  17. data/docs/lunar_observation.md +87 -0
  18. data/docs/moon_phases.md +4 -1
  19. data/docs/observer.md +20 -6
  20. data/docs/planetary_phenomena.md +78 -0
  21. data/docs/reference_frames.md +192 -34
  22. data/docs/rise_transit_set_times.md +6 -4
  23. data/docs/solar_system_bodies.md +26 -4
  24. data/docs/twilight_times.md +25 -21
  25. data/lib/astronoby/angle.rb +63 -2
  26. data/lib/astronoby/angles/dms.rb +18 -1
  27. data/lib/astronoby/angles/hms.rb +14 -1
  28. data/lib/astronoby/angular_velocity.rb +21 -0
  29. data/lib/astronoby/bodies/deep_sky_object.rb +6 -1
  30. data/lib/astronoby/bodies/deep_sky_object_position.rb +32 -17
  31. data/lib/astronoby/bodies/earth.rb +7 -44
  32. data/lib/astronoby/bodies/jupiter.rb +10 -0
  33. data/lib/astronoby/bodies/mars.rb +10 -0
  34. data/lib/astronoby/bodies/mercury.rb +10 -0
  35. data/lib/astronoby/bodies/moon.rb +158 -32
  36. data/lib/astronoby/bodies/neptune.rb +10 -0
  37. data/lib/astronoby/bodies/saturn.rb +10 -0
  38. data/lib/astronoby/bodies/solar_system_body.rb +240 -61
  39. data/lib/astronoby/bodies/sun.rb +79 -4
  40. data/lib/astronoby/bodies/uranus.rb +10 -0
  41. data/lib/astronoby/bodies/venus.rb +10 -0
  42. data/lib/astronoby/body.rb +6 -0
  43. data/lib/astronoby/center.rb +84 -0
  44. data/lib/astronoby/constellation.rb +9 -1
  45. data/lib/astronoby/coordinates/ecliptic.rb +10 -1
  46. data/lib/astronoby/coordinates/equatorial.rb +64 -8
  47. data/lib/astronoby/coordinates/geodetic.rb +102 -0
  48. data/lib/astronoby/coordinates/horizontal.rb +13 -1
  49. data/lib/astronoby/distance.rb +35 -0
  50. data/lib/astronoby/duration.rb +116 -0
  51. data/lib/astronoby/earth_rotation.rb +70 -0
  52. data/lib/astronoby/equinox_solstice.rb +31 -8
  53. data/lib/astronoby/errors.rb +11 -0
  54. data/lib/astronoby/events/conjunction.rb +51 -0
  55. data/lib/astronoby/events/conjunction_opposition_calculator.rb +84 -0
  56. data/lib/astronoby/events/eclipse_phase.rb +27 -0
  57. data/lib/astronoby/events/extremum_calculator.rb +23 -176
  58. data/lib/astronoby/events/greatest_elongation.rb +58 -0
  59. data/lib/astronoby/events/greatest_elongation_calculator.rb +56 -0
  60. data/lib/astronoby/events/lunar_eclipse.rb +99 -0
  61. data/lib/astronoby/events/lunar_eclipse_calculator.rb +285 -0
  62. data/lib/astronoby/events/opposition.rb +19 -0
  63. data/lib/astronoby/events/rise_transit_set_event.rb +12 -1
  64. data/lib/astronoby/events/rise_transit_set_events.rb +12 -1
  65. data/lib/astronoby/events/twilight_event.rb +24 -6
  66. data/lib/astronoby/events/twilight_events.rb +26 -6
  67. data/lib/astronoby/extremum_finder.rb +148 -0
  68. data/lib/astronoby/instant.rb +10 -7
  69. data/lib/astronoby/libration.rb +25 -0
  70. data/lib/astronoby/mean_obliquity.rb +8 -0
  71. data/lib/astronoby/moon_orientation_ephemeris.rb +69 -0
  72. data/lib/astronoby/moon_physical_ephemeris.rb +263 -0
  73. data/lib/astronoby/nutation.rb +10 -20
  74. data/lib/astronoby/observer.rb +67 -49
  75. data/lib/astronoby/orientation.rb +107 -0
  76. data/lib/astronoby/position.rb +16 -0
  77. data/lib/astronoby/precession.rb +61 -60
  78. data/lib/astronoby/reference_frame.rb +73 -7
  79. data/lib/astronoby/reference_frames/apparent.rb +26 -7
  80. data/lib/astronoby/reference_frames/astrometric.rb +14 -1
  81. data/lib/astronoby/reference_frames/geometric.rb +7 -1
  82. data/lib/astronoby/reference_frames/mean_of_date.rb +13 -1
  83. data/lib/astronoby/reference_frames/teme.rb +153 -0
  84. data/lib/astronoby/reference_frames/topocentric.rb +30 -4
  85. data/lib/astronoby/refraction.rb +26 -5
  86. data/lib/astronoby/root_finder.rb +83 -0
  87. data/lib/astronoby/rotation.rb +49 -0
  88. data/lib/astronoby/time/greenwich_apparent_sidereal_time.rb +9 -0
  89. data/lib/astronoby/time/greenwich_mean_sidereal_time.rb +42 -5
  90. data/lib/astronoby/time/greenwich_sidereal_time.rb +21 -0
  91. data/lib/astronoby/time/local_apparent_sidereal_time.rb +21 -0
  92. data/lib/astronoby/time/local_mean_sidereal_time.rb +21 -0
  93. data/lib/astronoby/time/local_sidereal_time.rb +24 -0
  94. data/lib/astronoby/time/sidereal_time.rb +23 -1
  95. data/lib/astronoby/true_obliquity.rb +4 -0
  96. data/lib/astronoby/util/maths.rb +8 -0
  97. data/lib/astronoby/util/time.rb +10 -485
  98. data/lib/astronoby/vector.rb +10 -0
  99. data/lib/astronoby/velocity.rb +39 -0
  100. data/lib/astronoby/version.rb +1 -1
  101. data/lib/astronoby.rb +22 -0
  102. metadata +45 -5
@@ -1,12 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Astronoby
4
+ # Local Mean Sidereal Time (LMST). Derived from GMST by adding the
5
+ # observer's longitude.
4
6
  class LocalMeanSiderealTime < LocalSiderealTime
7
+ # Creates LMST from a Greenwich Mean Sidereal Time and longitude.
8
+ #
5
9
  # Source:
6
10
  # Title: Practical Astronomy with your Calculator or Spreadsheet
7
11
  # Authors: Peter Duffett-Smith and Jonathan Zwart
8
12
  # Edition: Cambridge University Press
9
13
  # Chapter: 14 - Local sidereal time (LST)
14
+ #
15
+ # @param gst [Astronoby::GreenwichMeanSiderealTime] GMST
16
+ # @param longitude [Astronoby::Angle] the observer's longitude
17
+ # @return [Astronoby::LocalMeanSiderealTime]
18
+ # @raise [ArgumentError] if gst is not mean sidereal time
10
19
  def self.from_gst(gst:, longitude:)
11
20
  unless gst.mean?
12
21
  raise ArgumentError, "GST must be mean sidereal time"
@@ -18,20 +27,32 @@ module Astronoby
18
27
  new(date: date, time: time, longitude: longitude)
19
28
  end
20
29
 
30
+ # Creates LMST from UTC and longitude.
31
+ #
32
+ # @param utc [Time] the UTC time
33
+ # @param longitude [Astronoby::Angle] the observer's longitude
34
+ # @return [Astronoby::LocalMeanSiderealTime]
21
35
  def self.from_utc(utc, longitude:)
22
36
  gmst = GreenwichMeanSiderealTime.from_utc(utc)
23
37
  from_gst(gst: gmst, longitude: longitude)
24
38
  end
25
39
 
40
+ # @param date [Date] the calendar date
41
+ # @param time [Numeric] LMST in hours
42
+ # @param longitude [Astronoby::Angle] the observer's longitude
26
43
  def initialize(date:, time:, longitude:)
27
44
  super(date: date, time: time, longitude: longitude, type: MEAN)
28
45
  end
29
46
 
47
+ # Converts to Greenwich Mean Sidereal Time.
48
+ #
30
49
  # Source:
31
50
  # Title: Practical Astronomy with your Calculator or Spreadsheet
32
51
  # Authors: Peter Duffett-Smith and Jonathan Zwart
33
52
  # Edition: Cambridge University Press
34
53
  # Chapter: 15 - Converting LST to GST
54
+ #
55
+ # @return [Astronoby::GreenwichMeanSiderealTime]
35
56
  def to_gst
36
57
  date = @date
37
58
  time = normalize_time(@time - @longitude.hours)
@@ -1,9 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Astronoby
4
+ # Local Sidereal Time base class. Dispatches to mean or apparent subclasses
5
+ # based on the type of the source GST.
4
6
  class LocalSiderealTime < SiderealTime
7
+ # @return [Astronoby::Angle] the observer's longitude
5
8
  attr_reader :longitude
6
9
 
10
+ # Creates an LST from a Greenwich Sidereal Time and longitude.
11
+ #
12
+ # @param gst [Astronoby::GreenwichSiderealTime] Greenwich Sidereal Time
13
+ # @param longitude [Astronoby::Angle] the observer's longitude
14
+ # @return [Astronoby::LocalMeanSiderealTime,
15
+ # Astronoby::LocalApparentSiderealTime]
7
16
  def self.from_gst(gst:, longitude:)
8
17
  case gst.type
9
18
  when MEAN
@@ -13,6 +22,13 @@ module Astronoby
13
22
  end
14
23
  end
15
24
 
25
+ # Creates an LST from UTC and longitude.
26
+ #
27
+ # @param utc [Time] the UTC time
28
+ # @param longitude [Astronoby::Angle] the observer's longitude
29
+ # @param type [Symbol] :mean or :apparent
30
+ # @return [Astronoby::LocalMeanSiderealTime,
31
+ # Astronoby::LocalApparentSiderealTime]
16
32
  def self.from_utc(utc, longitude:, type: MEAN)
17
33
  validate_type!(type)
18
34
  case type
@@ -23,11 +39,19 @@ module Astronoby
23
39
  end
24
40
  end
25
41
 
42
+ # @param date [Date] the calendar date
43
+ # @param time [Numeric] the sidereal time in hours
44
+ # @param longitude [Astronoby::Angle] the observer's longitude
45
+ # @param type [Symbol] :mean or :apparent
26
46
  def initialize(date:, time:, longitude:, type: MEAN)
27
47
  super(date: date, time: time, type: type)
28
48
  @longitude = longitude
29
49
  end
30
50
 
51
+ # Converts to Greenwich Sidereal Time.
52
+ #
53
+ # @return [Astronoby::GreenwichMeanSiderealTime,
54
+ # Astronoby::GreenwichApparentSiderealTime]
31
55
  def to_gst
32
56
  case @type
33
57
  when MEAN
@@ -1,40 +1,62 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Astronoby
4
+ # Base class for sidereal time representations. Sidereal time measures the
5
+ # rotation of the Earth relative to the vernal equinox.
4
6
  class SiderealTime
5
7
  TYPES = [
6
8
  MEAN = :mean,
7
9
  APPARENT = :apparent
8
10
  ].freeze
9
11
 
10
- attr_reader :date, :time, :type
12
+ # @return [Date] the calendar date
13
+ attr_reader :date
11
14
 
15
+ # @return [Numeric] the sidereal time in hours
16
+ attr_reader :time
17
+
18
+ # @return [Symbol] :mean or :apparent
19
+ attr_reader :type
20
+
21
+ # Normalizes a time value to the range [0, 24) hours.
22
+ #
23
+ # @param time [Numeric] time in hours
24
+ # @return [Numeric] normalized time in hours
12
25
  def self.normalize_time(time)
13
26
  time += Constants::HOURS_PER_DAY if time.negative?
14
27
  time -= Constants::HOURS_PER_DAY if time > Constants::HOURS_PER_DAY
15
28
  time
16
29
  end
17
30
 
31
+ # @param type [Symbol] :mean or :apparent
32
+ # @raise [ArgumentError] if type is invalid
18
33
  def self.validate_type!(type)
19
34
  unless TYPES.include?(type)
20
35
  raise ArgumentError, "Invalid type: #{type}. Must be one of #{TYPES}"
21
36
  end
22
37
  end
23
38
 
39
+ # @param date [Date] the calendar date
40
+ # @param time [Numeric] the sidereal time in hours
41
+ # @param type [Symbol] :mean or :apparent
24
42
  def initialize(date:, time:, type: MEAN)
25
43
  @date = date
26
44
  @time = time
27
45
  @type = type
28
46
  end
29
47
 
48
+ # @return [Boolean] true if this is mean sidereal time
30
49
  def mean?
31
50
  @type == MEAN
32
51
  end
33
52
 
53
+ # @return [Boolean] true if this is apparent sidereal time
34
54
  def apparent?
35
55
  @type == APPARENT
36
56
  end
37
57
 
58
+ # @param time [Numeric] time in hours
59
+ # @return [Numeric] normalized time in hours
38
60
  def normalize_time(time)
39
61
  self.class.normalize_time(time)
40
62
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Astronoby
4
+ # Computes the true obliquity of the ecliptic (mean obliquity + nutation
5
+ # in obliquity).
4
6
  class TrueObliquity
7
+ # @param instant [Astronoby::Instant] the time instant
8
+ # @return [Astronoby::Angle] the true obliquity
5
9
  def self.at(instant)
6
10
  mean_obliquity = MeanObliquity.at(instant)
7
11
  nutation = Nutation.new(instant: instant).nutation_in_obliquity
@@ -9,6 +9,14 @@ module Astronoby
9
9
  a.zip(b).sum { |x, y| x * y }
10
10
  end
11
11
 
12
+ def cross_product(a, b)
13
+ [
14
+ a[1] * b[2] - a[2] * b[1],
15
+ a[2] * b[0] - a[0] * b[2],
16
+ a[0] * b[1] - a[1] * b[0]
17
+ ]
18
+ end
19
+
12
20
  # Find maximum altitude using quadratic interpolation
13
21
  # @param t1, t2, t3 [Time] Three consecutive times
14
22
  # @param alt1, alt2, alt3 [Float] Corresponding altitudes