Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rhannequin committed Mar 18, 2024
1 parent 2a48ab6 commit e484760
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 31 deletions.
26 changes: 26 additions & 0 deletions lib/astronoby/bodies/sun.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ def rising_time(observer:)
).to_gst.to_utc
end

# @param observer [Astronoby::Observer] Observer of the event
# @return [Astronoby::Angle, nil] Azimuth of sunrise
def rising_azimuth(observer:)
equatorial_coordinates = ecliptic_coordinates.to_equatorial(epoch: @epoch)
Body.new(equatorial_coordinates).rising_azimuth(
latitude: observer.latitude,
vertical_shift: vertical_shift
)
end

# @param observer [Astronoby::Observer] Observer of the event
# @return [Time] Time of sunset
def setting_time(observer:)
Expand All @@ -72,6 +82,16 @@ def setting_time(observer:)
).to_gst.to_utc
end

# @param observer [Astronoby::Observer] Observer of the event
# @return [Astronoby::Angle, nil] Azimuth of sunset
def setting_azimuth(observer:)
equatorial_coordinates = ecliptic_coordinates.to_equatorial(epoch: @epoch)
Body.new(equatorial_coordinates).setting_azimuth(
latitude: observer.latitude,
vertical_shift: vertical_shift
)
end

# @return [Numeric] Earth-Sun distance in meters
def earth_distance
SEMI_MAJOR_AXIS_IN_METERS / distance_angular_size_factor
Expand Down Expand Up @@ -172,5 +192,11 @@ def event_local_sidereal_time_for_date(date, observer, event)
.to_lst(longitude: observer.longitude)
.time
end

def vertical_shift
Astronoby::Body::DEFAULT_REFRACTION_VERTICAL_SHIFT +
Astronoby::GeocentricParallax.angle(distance: earth_distance) +
Astronoby::Angle.as_degrees(angular_size.degrees / 2)
end
end
end
66 changes: 41 additions & 25 deletions lib/astronoby/body.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ def rising_time(
apparent: true,
vertical_shift: nil
)
ratio = ratio(latitude, apparent, vertical_shift)
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(ratio)
time_ratio = time_ratio(latitude, apparent, vertical_shift)
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)

hour_angle = Angle.acos(ratio)
hour_angle = Angle.acos(time_ratio)
local_sidereal_time = LocalSiderealTime.new(
date: date,
time: @equatorial_coordinates.right_ascension.hours - hour_angle.hours,
Expand All @@ -35,15 +35,17 @@ def rising_time(
end

# Source:
# Title: Celestial Calculations
# Author: J. L. Lawrence
# Edition: MIT Press
# Chapter: 5 - Stars in the Nighttime Sky
def rising_azimuth(latitude:)
ar = azimuth_component(latitude)
return nil if ar >= 1

Angle.acos(ar)
# Title: Practical Astronomy with your Calculator or Spreadsheet
# Authors: Peter Duffett-Smith and Jonathan Zwart
# Edition: Cambridge University Press
# Chapter: 33 - Rising and setting
def rising_azimuth(latitude:, apparent: true, vertical_shift: nil)
time_ratio = time_ratio(latitude, apparent, vertical_shift)
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)

azimuth_ratio = azimuth_ratio(latitude, apparent, vertical_shift)

Angle.acos(azimuth_ratio)
end

# Source:
Expand All @@ -58,10 +60,10 @@ def setting_time(
apparent: true,
vertical_shift: nil
)
ratio = ratio(latitude, apparent, vertical_shift)
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(ratio)
time_ratio = time_ratio(latitude, apparent, vertical_shift)
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)

hour_angle = Angle.acos(ratio)
hour_angle = Angle.acos(time_ratio)
local_sidereal_time = LocalSiderealTime.new(
date: date,
time: @equatorial_coordinates.right_ascension.hours + hour_angle.hours,
Expand All @@ -72,20 +74,22 @@ def setting_time(
end

# Source:
# Title: Celestial Calculations
# Author: J. L. Lawrence
# Edition: MIT Press
# Chapter: 5 - Stars in the Nighttime Sky
def setting_azimuth(latitude:)
rising_az = rising_azimuth(latitude: latitude)
return nil if rising_az.nil?

Angle.as_degrees(360 - rising_az.degrees)
# Title: Practical Astronomy with your Calculator or Spreadsheet
# Authors: Peter Duffett-Smith and Jonathan Zwart
# Edition: Cambridge University Press
# Chapter: 33 - Rising and setting
def setting_azimuth(latitude:, apparent: true, vertical_shift: nil)
time_ratio = time_ratio(latitude, apparent, vertical_shift)
return nil unless RISING_SETTING_HOUR_ANGLE_RATIO_RANGE.cover?(time_ratio)

azimuth_ratio = azimuth_ratio(latitude, apparent, vertical_shift)

Angle.as_degrees(360 - Angle.acos(azimuth_ratio).degrees)
end

private

def ratio(latitude, apparent, vertical_shift)
def time_ratio(latitude, apparent, vertical_shift)
shift = if vertical_shift
vertical_shift
elsif apparent
Expand All @@ -99,6 +103,18 @@ def ratio(latitude, apparent, vertical_shift)
)
end

def azimuth_ratio(latitude, apparent, vertical_shift)
shift = if vertical_shift
vertical_shift
elsif apparent
DEFAULT_REFRACTION_VERTICAL_SHIFT
else
Angle.zero
end

(@equatorial_coordinates.declination.sin + shift.sin * latitude.cos) / (shift.cos * latitude.cos)
end

def azimuth_component(latitude)
@equatorial_coordinates.declination.sin / latitude.cos
end
Expand Down
122 changes: 122 additions & 0 deletions spec/astronoby/bodies/sun_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,67 @@
end
end

describe "#rising_azimuth" do
it "returns an Angle" do
date = Date.new
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.zero,
longitude: Astronoby::Angle.zero
)
sun = described_class.new(epoch: epoch)

rising_azimuth = sun.rising_azimuth(observer: observer)

expect(rising_azimuth).to be_a(Astronoby::Angle)
end

it "returns the Sun's rising azimuth on 2015-02-05" do
date = Date.new(2015, 2, 5)
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.as_degrees(38),
longitude: Astronoby::Angle.as_degrees(-78)
)
sun = Astronoby::Sun.new(epoch: epoch)

rising_azimuth = sun.rising_azimuth(observer: observer)

expect(rising_azimuth&.str(:dms)).to eq "+109° 41′ 24.0917″"
# Time from IMCCE: +109° 53′
end

it "returns the Sun's rising azimuth on 1986-03-10" do
date = Date.new(1986, 3, 10)
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.as_degrees(42.37),
longitude: Astronoby::Angle.as_degrees(-71.05)
)
sun = described_class.new(epoch: epoch)

rising_azimuth = sun.rising_azimuth(observer: observer)

expect(rising_azimuth&.str(:dms)).to eq "+94° 59′ 15.7852″"
# Time from IMCCE: +95° 02′
end

it "returns the Sun's rising azimuth on 1991-03-14" do
date = Date.new(1991, 3, 14)
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.as_degrees(48.8566),
longitude: Astronoby::Angle.as_degrees(2.3522)
)
sun = described_class.new(epoch: epoch)

rising_azimuth = sun.rising_azimuth(observer: observer)

expect(rising_azimuth&.str(:dms)).to eq "+93° 26′ 26.8564″"
# Time from IMCCE: +93° 26′
end
end

describe "#setting_time" do
it "returns a time" do
date = Date.new
Expand Down Expand Up @@ -450,4 +511,65 @@
# Time from IMCCE: 1991-03-14T17:52:00
end
end

describe "#setting_azimuth" do
it "returns an Angle" do
date = Date.new
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.zero,
longitude: Astronoby::Angle.zero
)
sun = described_class.new(epoch: epoch)

setting_azimuth = sun.setting_azimuth(observer: observer)

expect(setting_azimuth).to be_a(Astronoby::Angle)
end

it "returns the Sun's setting azimuth on 2015-02-05" do
date = Date.new(2015, 2, 5)
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.as_degrees(38),
longitude: Astronoby::Angle.as_degrees(-78)
)
sun = Astronoby::Sun.new(epoch: epoch)

setting_azimuth = sun.setting_azimuth(observer: observer)

expect(setting_azimuth&.str(:dms)).to eq "+250° 18′ 35.9082″"
# Time from IMCCE: +250° 18′
end

it "returns the Sun's setting azimuth on 1986-03-10" do
date = Date.new(1986, 3, 10)
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.as_degrees(42.37),
longitude: Astronoby::Angle.as_degrees(-71.05)
)
sun = described_class.new(epoch: epoch)

setting_azimuth = sun.setting_azimuth(observer: observer)

expect(setting_azimuth&.str(:dms)).to eq "+265° 0′ 44.2147″"
# Time from IMCCE: +265° 14′
end

it "returns the Sun's setting azimuth on 1991-03-14" do
date = Date.new(1991, 3, 14)
epoch = Astronoby::Epoch.from_time(date)
observer = Astronoby::Observer.new(
latitude: Astronoby::Angle.as_degrees(48.8566),
longitude: Astronoby::Angle.as_degrees(2.3522)
)
sun = described_class.new(epoch: epoch)

setting_azimuth = sun.setting_azimuth(observer: observer)

expect(setting_azimuth&.str(:dms)).to eq "+266° 33′ 33.1435″"
# Time from IMCCE: +266° 52′
end
end
end
14 changes: 8 additions & 6 deletions spec/astronoby/body_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
# Authors: Peter Duffett-Smith and Jonathan Zwart
# Edition: Cambridge University Press
# Chapter: 33 - Rising and setting
it "bob returns the body's rising time" do
it "returns the body's rising time" do
coordinates = Astronoby::Coordinates::Equatorial.new(
right_ascension: Astronoby::Angle.as_hms(23, 39, 20),
declination: Astronoby::Angle.as_dms(21, 42, 0)
Expand Down Expand Up @@ -113,10 +113,11 @@
body = described_class.new(coordinates)

rising_azimuth = body.rising_azimuth(
latitude: Astronoby::Angle.as_degrees(38)
latitude: Astronoby::Angle.as_degrees(38),
apparent: false
)

expect(rising_azimuth&.degrees).to be_within(10**-9).of(80.465577913)
expect(rising_azimuth&.degrees&.ceil(6)).to eq 80.465578
end
end

Expand Down Expand Up @@ -197,7 +198,7 @@
# Authors: Peter Duffett-Smith and Jonathan Zwart
# Edition: Cambridge University Press
# Chapter: 33 - Rising and setting
it "bob returns the body's rising time" do
it "returns the body's rising time" do
coordinates = Astronoby::Coordinates::Equatorial.new(
right_ascension: Astronoby::Angle.as_hms(23, 39, 20),
declination: Astronoby::Angle.as_dms(21, 42, 0)
Expand Down Expand Up @@ -230,10 +231,11 @@
body = described_class.new(coordinates)

setting_azimuth = body.setting_azimuth(
latitude: Astronoby::Angle.as_degrees(38)
latitude: Astronoby::Angle.as_degrees(38),
apparent: false
)

expect(setting_azimuth&.degrees).to be_within(10**-7).of(279.534422)
expect(setting_azimuth&.degrees&.ceil(6)).to eq 279.534423
end
end
end

0 comments on commit e484760

Please sign in to comment.