astronoby 0.2.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.
@@ -3,31 +3,64 @@
3
3
  module Astronoby
4
4
  class Sun
5
5
  SEMI_MAJOR_AXIS_IN_METERS = 149_598_500_000
6
- ANGULAR_DIAMETER = Angle.as_degrees(0.533128)
7
- INTERPOLATION_FACTOR = BigDecimal("24.07")
6
+ ANGULAR_DIAMETER = Angle.from_degrees(0.533128)
7
+ INTERPOLATION_FACTOR = 24.07
8
+
9
+ TWILIGHTS = [
10
+ CIVIL = :civil,
11
+ NAUTICAL = :nautical,
12
+ ASTRONOMICAL = :astronomical
13
+ ].freeze
14
+
15
+ TWILIGHT_ANGLES = {
16
+ CIVIL => Angle.from_degrees(96),
17
+ NAUTICAL => Angle.from_degrees(102),
18
+ ASTRONOMICAL => Angle.from_degrees(108)
19
+ }.freeze
20
+
21
+ PERIODS_OF_THE_DAY = [
22
+ MORNING = :morning,
23
+ EVENING = :evening
24
+ ].freeze
25
+
26
+ attr_reader :time
8
27
 
9
28
  # Source:
10
- # Title: Practical Astronomy with your Calculator or Spreadsheet
11
- # Authors: Peter Duffett-Smith and Jonathan Zwart
12
- # Edition: Cambridge University Press
13
- # Chapter: 51 - The equation of time
29
+ # Title: Astronomical Algorithms
30
+ # Author: Jean Meeus
31
+ # Edition: 2nd edition
32
+ # Chapter: 28 - Equation of Time
14
33
 
15
- # @param date [Date] Requested date
34
+ # @param date_or_time [Date, Time] Requested date
16
35
  # @return [Integer] Equation of time in seconds
17
- def self.equation_of_time(date:)
18
- noon = Time.utc(date.year, date.month, date.day, 12)
19
- epoch_at_noon = Epoch.from_time(noon)
20
- sun_at_noon = new(epoch: epoch_at_noon)
21
- equatorial_hours = sun_at_noon
22
- .ecliptic_coordinates
23
- .to_equatorial(epoch: epoch_at_noon)
36
+ def self.equation_of_time(date_or_time:)
37
+ noon = Time.utc(date_or_time.year, date_or_time.month, date_or_time.day, 12)
38
+ time = date_or_time.is_a?(Time) ? date_or_time : noon
39
+ epoch = Epoch.from_time(time)
40
+ sun = new(time: time)
41
+ right_ascension = sun
42
+ .apparent_ecliptic_coordinates
43
+ .to_apparent_equatorial(epoch: epoch)
24
44
  .right_ascension
25
- .hours
26
- gst = GreenwichSiderealTime
27
- .new(date: date, time: equatorial_hours)
28
- .to_utc
29
-
30
- (noon - gst).to_i
45
+ t = (epoch - Epoch::J2000) / Constants::DAYS_PER_JULIAN_MILLENIA
46
+ l0 = (280.4664567 +
47
+ 360_007.6982779 * t +
48
+ 0.03032028 * t**2 +
49
+ t**3 / 49_931 -
50
+ t**4 / 15_300 -
51
+ t**5 / 2_000_000) % Constants::DEGREES_PER_CIRCLE
52
+ nutation = Nutation.for_ecliptic_longitude(epoch: epoch)
53
+ obliquity = TrueObliquity.for_epoch(epoch)
54
+
55
+ (
56
+ Angle
57
+ .from_degrees(
58
+ l0 -
59
+ Constants::EQUATION_OF_TIME_CONSTANT -
60
+ right_ascension.degrees +
61
+ nutation.degrees * obliquity.cos
62
+ ).hours * Constants::SECONDS_PER_HOUR
63
+ ).round
31
64
  end
32
65
 
33
66
  # Source:
@@ -36,18 +69,33 @@ module Astronoby
36
69
  # Edition: MIT Press
37
70
  # Chapter: 6 - The Sun
38
71
 
39
- # @param epoch [Numeric] Considered epoch, in Julian days
40
- def initialize(epoch:)
41
- @epoch = epoch
72
+ # @param time [Time] Considered time
73
+ def initialize(time:)
74
+ @time = time
75
+ end
76
+
77
+ def epoch
78
+ @epoch ||= Epoch.from_time(@time)
79
+ end
80
+
81
+ def true_ecliptic_coordinates
82
+ Coordinates::Ecliptic.new(
83
+ latitude: Angle.zero,
84
+ longitude: true_longitude
85
+ )
42
86
  end
43
87
 
44
- # @return [Astronoby::Coordinates::Ecliptic] Sun's ecliptic coordinates
45
- def ecliptic_coordinates
88
+ def apparent_ecliptic_coordinates
89
+ nutation = Nutation.for_ecliptic_longitude(epoch: epoch)
90
+ longitude_with_aberration = Aberration.for_ecliptic_coordinates(
91
+ coordinates: true_ecliptic_coordinates,
92
+ epoch: epoch
93
+ ).longitude
94
+ apparent_longitude = nutation + longitude_with_aberration
95
+
46
96
  Coordinates::Ecliptic.new(
47
97
  latitude: Angle.zero,
48
- longitude: Angle.as_degrees(
49
- (true_anomaly + longitude_at_perigee).degrees % 360
50
- )
98
+ longitude: apparent_longitude
51
99
  )
52
100
  end
53
101
 
@@ -57,63 +105,55 @@ module Astronoby
57
105
  # @param longitude [Astronoby::Angle] Longitude of the observer
58
106
  # @return [Astronoby::Coordinates::Horizontal] Sun's horizontal coordinates
59
107
  def horizontal_coordinates(latitude:, longitude:)
60
- time = Epoch.to_utc(@epoch)
61
-
62
- ecliptic_coordinates
63
- .to_equatorial(epoch: @epoch)
64
- .to_horizontal(time: time, latitude: latitude, longitude: longitude)
108
+ apparent_ecliptic_coordinates
109
+ .to_apparent_equatorial(epoch: epoch)
110
+ .to_horizontal(time: @time, latitude: latitude, longitude: longitude)
65
111
  end
66
112
 
67
113
  # @param observer [Astronoby::Observer] Observer of the event
68
- # @return [Time] Time of sunrise
69
- def rising_time(observer:)
70
- event_date = Epoch.to_utc(@epoch).to_date
71
- lst1 = event_local_sidereal_time_for_date(event_date, observer, :rising)
72
- next_day = event_date.next_day(1)
73
- lst2 = event_local_sidereal_time_for_date(next_day, observer, :rising)
74
- time = (INTERPOLATION_FACTOR * lst1) / (INTERPOLATION_FACTOR + lst1 - lst2)
75
-
76
- LocalSiderealTime.new(
77
- date: event_date,
78
- time: time,
79
- longitude: observer.longitude
80
- ).to_gst.to_utc
81
- end
82
-
83
- # @param observer [Astronoby::Observer] Observer of the event
84
- # @return [Astronoby::Angle, nil] Azimuth of sunrise
85
- def rising_azimuth(observer:)
86
- equatorial_coordinates = ecliptic_coordinates.to_equatorial(epoch: @epoch)
87
- Body.new(equatorial_coordinates).rising_azimuth(
88
- latitude: observer.latitude,
89
- vertical_shift: vertical_shift
114
+ # @return [Astronoby::Events::ObservationEvents] Sun's observation events
115
+ def observation_events(observer:)
116
+ today = @time.to_date
117
+ leap_seconds = Util::Time.terrestrial_universal_time_delta(today)
118
+ yesterday = today.prev_day
119
+ yesterday_midnight_terrestrial_time =
120
+ Time.utc(yesterday.year, yesterday.month, yesterday.day) - leap_seconds
121
+ yesterday_epoch = Epoch.from_time(yesterday_midnight_terrestrial_time)
122
+ today_midnight_terrestrial_time =
123
+ Time.utc(today.year, today.month, today.day) - leap_seconds
124
+ today_epoch = Epoch.from_time(today_midnight_terrestrial_time)
125
+ tomorrow = today.next_day
126
+ tomorrow_midnight_terrestrial_time =
127
+ Time.utc(tomorrow.year, tomorrow.month, tomorrow.day) - leap_seconds
128
+ tomorrow_epoch = Epoch.from_time(tomorrow_midnight_terrestrial_time)
129
+
130
+ coordinates_of_the_previous_day = self.class
131
+ .new(time: yesterday_midnight_terrestrial_time)
132
+ .apparent_ecliptic_coordinates
133
+ .to_apparent_equatorial(epoch: yesterday_epoch)
134
+ coordinates_of_the_day = self.class
135
+ .new(time: today_midnight_terrestrial_time)
136
+ .apparent_ecliptic_coordinates
137
+ .to_apparent_equatorial(epoch: today_epoch)
138
+ coordinates_of_the_next_day = self.class
139
+ .new(time: tomorrow_midnight_terrestrial_time)
140
+ .apparent_ecliptic_coordinates
141
+ .to_apparent_equatorial(epoch: tomorrow_epoch)
142
+
143
+ Events::ObservationEvents.new(
144
+ observer: observer,
145
+ date: today,
146
+ coordinates_of_the_previous_day: coordinates_of_the_previous_day,
147
+ coordinates_of_the_day: coordinates_of_the_day,
148
+ coordinates_of_the_next_day: coordinates_of_the_next_day,
149
+ additional_altitude: Angle.from_degrees(angular_size.degrees / 2)
90
150
  )
91
151
  end
92
152
 
93
- # @param observer [Astronoby::Observer] Observer of the event
94
- # @return [Time] Time of sunset
95
- def setting_time(observer:)
96
- event_date = Epoch.to_utc(@epoch).to_date
97
- lst1 = event_local_sidereal_time_for_date(event_date, observer, :setting)
98
- next_day = event_date.next_day(1)
99
- lst2 = event_local_sidereal_time_for_date(next_day, observer, :setting)
100
- time = (INTERPOLATION_FACTOR * lst1) / (INTERPOLATION_FACTOR + lst1 - lst2)
101
-
102
- LocalSiderealTime.new(
103
- date: event_date,
104
- time: time,
105
- longitude: observer.longitude
106
- ).to_gst.to_utc
107
- end
108
-
109
- # @param observer [Astronoby::Observer] Observer of the event
110
- # @return [Astronoby::Angle, nil] Azimuth of sunset
111
- def setting_azimuth(observer:)
112
- equatorial_coordinates = ecliptic_coordinates.to_equatorial(epoch: @epoch)
113
- Body.new(equatorial_coordinates).setting_azimuth(
114
- latitude: observer.latitude,
115
- vertical_shift: vertical_shift
116
- )
153
+ # @param observer [Astronoby::Observer] Observer of the events
154
+ # @return [Astronoby::Events::TwilightEvents] Sun's twilight events
155
+ def twilight_events(observer:)
156
+ Events::TwilightEvents.new(sun: self, observer: observer)
117
157
  end
118
158
 
119
159
  # @return [Numeric] Earth-Sun distance in meters
@@ -123,7 +163,9 @@ module Astronoby
123
163
 
124
164
  # @return [Astronoby::Angle] Apparent Sun's angular size
125
165
  def angular_size
126
- Angle.as_degrees(ANGULAR_DIAMETER.degrees * distance_angular_size_factor)
166
+ Angle.from_degrees(
167
+ ANGULAR_DIAMETER.degrees * distance_angular_size_factor
168
+ )
127
169
  end
128
170
 
129
171
  # @return [Astronoby::Angle] Sun's true anomaly
@@ -139,42 +181,55 @@ module Astronoby
139
181
  (1 + orbital_eccentricity.degrees) / (1 - orbital_eccentricity.degrees)
140
182
  ) * Math.tan(eccentric_anomaly.radians / 2)
141
183
 
142
- Angle.as_degrees((Angle.atan(tan).degrees * 2) % 360)
184
+ Angle.from_degrees(
185
+ (Angle.atan(tan).degrees * 2) % Constants::DEGREES_PER_CIRCLE
186
+ )
143
187
  end
144
188
 
145
189
  # @return [Astronoby::Angle] Sun's longitude at perigee
146
190
  def longitude_at_perigee
147
- Angle.as_degrees(
148
- (281.2208444 + 1.719175 * centuries + 0.000452778 * centuries**2) % 360
191
+ Angle.from_degrees(
192
+ (281.2208444 + 1.719175 * centuries + 0.000452778 * centuries**2) %
193
+ Constants::DEGREES_PER_CIRCLE
149
194
  )
150
195
  end
151
196
 
152
197
  # @return [Astronoby::Angle] Sun's orbital eccentricity
153
198
  def orbital_eccentricity
154
- Angle.as_degrees(
155
- (0.01675104 - 0.0000418 * centuries - 0.000000126 * centuries**2) % 360
199
+ Angle.from_degrees(
200
+ (0.01675104 - 0.0000418 * centuries - 0.000000126 * centuries**2) %
201
+ Constants::DEGREES_PER_CIRCLE
156
202
  )
157
203
  end
158
204
 
159
205
  private
160
206
 
207
+ def true_longitude
208
+ Angle.from_degrees(
209
+ (true_anomaly + longitude_at_perigee).degrees %
210
+ Constants::DEGREES_PER_CIRCLE
211
+ )
212
+ end
213
+
161
214
  def mean_anomaly
162
- Angle.as_degrees(
163
- (longitude_at_base_epoch - longitude_at_perigee).degrees % 360
215
+ Angle.from_degrees(
216
+ (longitude_at_base_epoch - longitude_at_perigee).degrees %
217
+ Constants::DEGREES_PER_CIRCLE
164
218
  )
165
219
  end
166
220
 
167
221
  def days_since_epoch
168
- Epoch::DEFAULT_EPOCH - @epoch
222
+ Epoch::DEFAULT_EPOCH - epoch
169
223
  end
170
224
 
171
225
  def centuries
172
- @centuries ||= (@epoch - Epoch::J1900) / Epoch::DAYS_PER_JULIAN_CENTURY
226
+ @centuries ||= (epoch - Epoch::J1900) / Constants::DAYS_PER_JULIAN_CENTURY
173
227
  end
174
228
 
175
229
  def longitude_at_base_epoch
176
- Angle.as_degrees(
177
- (279.6966778 + 36000.76892 * centuries + 0.0003025 * centuries**2) % 360
230
+ Angle.from_degrees(
231
+ (279.6966778 + 36000.76892 * centuries + 0.0003025 * centuries**2) %
232
+ Constants::DEGREES_PER_CIRCLE
178
233
  )
179
234
  end
180
235
 
@@ -184,43 +239,5 @@ module Astronoby
184
239
 
185
240
  term1 / term2
186
241
  end
187
-
188
- def event_local_sidereal_time_for_date(date, observer, event)
189
- midnight_utc = Time.utc(date.year, date.month, date.day)
190
- epoch = Epoch.from_time(midnight_utc)
191
- sun_at_midnight = self.class.new(epoch: epoch)
192
- shift = Body::DEFAULT_REFRACTION_VERTICAL_SHIFT +
193
- GeocentricParallax.angle(distance: sun_at_midnight.earth_distance) +
194
- Angle.as_degrees(sun_at_midnight.angular_size.degrees / 2)
195
- ecliptic_coordinates = sun_at_midnight.ecliptic_coordinates
196
- equatorial_coordinates = ecliptic_coordinates.to_equatorial(epoch: epoch)
197
-
198
- event_time = if event == :rising
199
- Body.new(equatorial_coordinates).rising_time(
200
- latitude: observer.latitude,
201
- longitude: observer.longitude,
202
- date: midnight_utc.to_date,
203
- vertical_shift: shift
204
- )
205
- else
206
- Body.new(equatorial_coordinates).setting_time(
207
- latitude: observer.latitude,
208
- longitude: observer.longitude,
209
- date: midnight_utc.to_date,
210
- vertical_shift: shift
211
- )
212
- end
213
-
214
- GreenwichSiderealTime
215
- .from_utc(event_time.utc)
216
- .to_lst(longitude: observer.longitude)
217
- .time
218
- end
219
-
220
- def vertical_shift
221
- Astronoby::Body::DEFAULT_REFRACTION_VERTICAL_SHIFT +
222
- Astronoby::GeocentricParallax.angle(distance: earth_distance) +
223
- Astronoby::Angle.as_degrees(angular_size.degrees / 2)
224
- end
225
242
  end
226
243
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Astronoby
4
+ class Constants
5
+ DAYS_PER_JULIAN_CENTURY = 36525.0
6
+ DAYS_PER_JULIAN_MILLENIA = DAYS_PER_JULIAN_CENTURY * 10
7
+
8
+ HOURS_PER_DAY = 24.0
9
+ DEGREES_PER_CIRCLE = 360.0
10
+ RADIANS_PER_CIRCLE = 2 * Math::PI
11
+
12
+ SECONDS_PER_MINUTE = 60.0
13
+ MINUTES_PER_HOUR = 60.0
14
+ MINUTES_PER_DEGREE = 60.0
15
+
16
+ SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR
17
+ SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY
18
+ SECONDS_PER_DEGREE = SECONDS_PER_MINUTE * MINUTES_PER_DEGREE
19
+ RADIAN_PER_HOUR = Math::PI / 12.0
20
+
21
+ PI_IN_DEGREES = 180.0
22
+
23
+ EQUATION_OF_TIME_CONSTANT = 0.0057183
24
+ end
25
+ end
@@ -15,20 +15,31 @@ module Astronoby
15
15
  # Author: J. L. Lawrence
16
16
  # Edition: MIT Press
17
17
  # Chapter: 4 - Orbits and Coordinate Systems
18
- def to_equatorial(epoch:)
18
+
19
+ def to_true_equatorial(epoch:)
19
20
  mean_obliquity = MeanObliquity.for_epoch(epoch)
21
+ to_equatorial(obliquity: mean_obliquity, epoch: epoch)
22
+ end
23
+
24
+ def to_apparent_equatorial(epoch:)
25
+ apparent_obliquity = TrueObliquity.for_epoch(epoch)
26
+ to_equatorial(obliquity: apparent_obliquity, epoch: epoch)
27
+ end
28
+
29
+ private
20
30
 
21
- y = Angle.as_radians(
22
- @longitude.sin * mean_obliquity.cos -
23
- @latitude.tan * mean_obliquity.sin
31
+ def to_equatorial(obliquity:, epoch:)
32
+ y = Angle.from_radians(
33
+ @longitude.sin * obliquity.cos -
34
+ @latitude.tan * obliquity.sin
24
35
  )
25
- x = Angle.as_radians(@longitude.cos)
36
+ x = Angle.from_radians(@longitude.cos)
26
37
  r = Angle.atan(y.radians / x.radians)
27
38
  right_ascension = Util::Trigonometry.adjustement_for_arctangent(y, x, r)
28
39
 
29
40
  declination = Angle.asin(
30
- @latitude.sin * mean_obliquity.cos +
31
- @latitude.cos * mean_obliquity.sin * @longitude.sin
41
+ @latitude.sin * obliquity.cos +
42
+ @latitude.cos * obliquity.sin * @longitude.sin
32
43
  )
33
44
 
34
45
  Equatorial.new(
@@ -23,9 +23,9 @@ module Astronoby
23
23
  .to_lst(longitude: longitude)
24
24
 
25
25
  ha = (lst.time - @right_ascension.hours)
26
- ha += 24 if ha.negative?
26
+ ha += Constants::HOURS_PER_DAY if ha.negative?
27
27
 
28
- Angle.as_hours(ha)
28
+ Angle.from_hours(ha)
29
29
  end
30
30
 
31
31
  def to_horizontal(time:, latitude:, longitude:)
@@ -39,7 +39,8 @@ module Astronoby
39
39
  azimuth = Angle.acos(t2)
40
40
 
41
41
  if ha.sin.positive?
42
- azimuth = Angle.as_degrees(BigDecimal("360") - azimuth.degrees)
42
+ azimuth =
43
+ Angle.from_degrees(Constants::DEGREES_PER_CIRCLE - azimuth.degrees)
43
44
  end
44
45
 
45
46
  Horizontal.new(
@@ -58,11 +59,11 @@ module Astronoby
58
59
  def to_ecliptic(epoch:)
59
60
  mean_obliquity = MeanObliquity.for_epoch(epoch)
60
61
 
61
- y = Angle.as_radians(
62
+ y = Angle.from_radians(
62
63
  @right_ascension.sin * mean_obliquity.cos +
63
64
  @declination.tan * mean_obliquity.sin
64
65
  )
65
- x = Angle.as_radians(@right_ascension.cos)
66
+ x = Angle.from_radians(@right_ascension.cos)
66
67
  r = Angle.atan(y.radians / x.radians)
67
68
  longitude = Util::Trigonometry.adjustement_for_arctangent(y, x, r)
68
69
 
@@ -31,17 +31,21 @@ module Astronoby
31
31
 
32
32
  if @azimuth.sin.positive?
33
33
  hour_angle_degrees = Angle
34
- .as_degrees(BigDecimal("360") - hour_angle_degrees)
34
+ .from_degrees(Constants::DEGREES_PER_CIRCLE - hour_angle_degrees)
35
35
  .degrees
36
36
  end
37
37
 
38
- hour_angle_hours = Angle.as_degrees(hour_angle_degrees).hours
38
+ hour_angle_hours = Angle.from_degrees(hour_angle_degrees).hours
39
39
  lst = GreenwichSiderealTime
40
40
  .from_utc(time.utc)
41
41
  .to_lst(longitude: @longitude)
42
42
  right_ascension_decimal = lst.time - hour_angle_hours
43
- right_ascension_decimal += 24 if right_ascension_decimal.negative?
44
- right_ascension = Angle.as_hours(right_ascension_decimal)
43
+
44
+ if right_ascension_decimal.negative?
45
+ right_ascension_decimal += Constants::HOURS_PER_DAY
46
+ end
47
+
48
+ right_ascension = Angle.from_hours(right_ascension_decimal)
45
49
 
46
50
  Equatorial.new(
47
51
  right_ascension: right_ascension,
@@ -9,8 +9,6 @@ module Astronoby
9
9
  J2000 = 2451545.0
10
10
 
11
11
  DEFAULT_EPOCH = J2000
12
- DAYS_PER_JULIAN_CENTURY = 36525.0
13
-
14
12
  JULIAN_DAY_NUMBER_OFFSET = 0.5
15
13
 
16
14
  def self.from_time(time)
@@ -101,14 +101,14 @@ module Astronoby
101
101
  end
102
102
 
103
103
  def compute
104
- t = (julian_day - Epoch::J2000) / Epoch::DAYS_PER_JULIAN_CENTURY
105
- w = Angle.as_degrees(35999.373 * t) - Angle.as_degrees(2.47)
104
+ t = (julian_day - Epoch::J2000) / Constants::DAYS_PER_JULIAN_CENTURY
105
+ w = Angle.from_degrees(35999.373 * t) - Angle.from_degrees(2.47)
106
106
  delta = 1 +
107
107
  0.0334 * w.cos +
108
- 0.0007 * Angle.as_degrees(w.degrees * 2).cos
108
+ 0.0007 * Angle.from_degrees(w.degrees * 2).cos
109
109
 
110
110
  s = PERIODIC_TERMS.sum do |a, b, c|
111
- a * (Angle.as_degrees(b) + Angle.as_degrees(c * t)).cos
111
+ a * (Angle.from_degrees(b) + Angle.from_degrees(c * t)).cos
112
112
  end
113
113
 
114
114
  delta_days = 0.00001 * s / delta
@@ -130,24 +130,11 @@ module Astronoby
130
130
  end
131
131
 
132
132
  def correction(epoch)
133
- sun = Sun.new(epoch: epoch)
133
+ time = Epoch.to_utc(epoch)
134
+ sun = Sun.new(time: time)
135
+ longitude = sun.apparent_ecliptic_coordinates.longitude
134
136
 
135
- nutation = Nutation.for_ecliptic_longitude(epoch: epoch)
136
-
137
- earth_radius_vector = 1 / (
138
- 1 +
139
- sun.orbital_eccentricity.degrees *
140
- (sun.true_anomaly - sun.longitude_at_perigee).cos
141
- )
142
- aberration = Angle.as_degrees(
143
- Angle.as_dms(0, 0, 20.4898).degrees / -earth_radius_vector
144
- )
145
-
146
- corrected_longitude = sun.ecliptic_coordinates.longitude +
147
- nutation +
148
- aberration
149
-
150
- 58 * Angle.as_degrees(@event * 90 - corrected_longitude.degrees).sin
137
+ 58 * Angle.from_degrees(@event * 90 - longitude.degrees).sin
151
138
  end
152
139
  end
153
140
  end