Class: Astronoby::Coordinates::Equatorial

Inherits:
Object
  • Object
show all
Defined in:
lib/astronoby/coordinates/equatorial.rb

Overview

Equatorial coordinate system (right ascension and declination).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(declination:, right_ascension:, hour_angle: nil, epoch: JulianDate::DEFAULT_EPOCH) ⇒ Equatorial

Returns a new instance of Equatorial.

Parameters:

  • declination (Astronoby::Angle)

    declination

  • right_ascension (Astronoby::Angle)

    right ascension

  • hour_angle (Astronoby::Angle, nil) (defaults to: nil)

    hour angle

  • epoch (Numeric) (defaults to: JulianDate::DEFAULT_EPOCH)

    Julian Date epoch (default: J2000.0 = 2451545.0)



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/astronoby/coordinates/equatorial.rb', line 23

def initialize(
  declination:,
  right_ascension:,
  hour_angle: nil,
  epoch: JulianDate::DEFAULT_EPOCH
)
  @right_ascension = right_ascension
  @declination = declination
  @hour_angle = hour_angle
  @epoch = epoch
end

Instance Attribute Details

#declinationAstronoby::Angle (readonly)

Returns declination.

Returns:



8
9
10
# File 'lib/astronoby/coordinates/equatorial.rb', line 8

def declination
  @declination
end

#epochNumeric (readonly)

Returns the Julian Date epoch.

Returns:

  • (Numeric)

    the Julian Date epoch



17
18
19
# File 'lib/astronoby/coordinates/equatorial.rb', line 17

def epoch
  @epoch
end

#hour_angleAstronoby::Angle? (readonly)

Returns hour angle, if set.

Returns:



14
15
16
# File 'lib/astronoby/coordinates/equatorial.rb', line 14

def hour_angle
  @hour_angle
end

#right_ascensionAstronoby::Angle (readonly)

Returns right ascension.

Returns:



11
12
13
# File 'lib/astronoby/coordinates/equatorial.rb', line 11

def right_ascension
  @right_ascension
end

Class Method Details

.from_position_vector(position) ⇒ Astronoby::Coordinates::Equatorial

Derives equatorial coordinates from a position vector.

Parameters:

Returns:



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/astronoby/coordinates/equatorial.rb', line 44

def self.from_position_vector(position)
  return zero if position.zero?

  term1 = position.z.m
  term2 = position.magnitude.m
  declination = Angle.asin(term1 / term2)

  term1 = position.y.m
  term2 = position.x.m
  angle = Angle.atan(term1 / term2)
  right_ascension =
    Astronoby::Util::Trigonometry.adjustement_for_arctangent(
      term1,
      term2,
      angle
    )

  new(declination: declination, right_ascension: right_ascension)
end

.zeroAstronoby::Coordinates::Equatorial

Returns zero coordinates.

Returns:



36
37
38
# File 'lib/astronoby/coordinates/equatorial.rb', line 36

def self.zero
  new(declination: Angle.zero, right_ascension: Angle.zero)
end

Instance Method Details

#compute_hour_angle(time:, longitude:) ⇒ Astronoby::Angle

Computes the hour angle for a given time and observer longitude.

Parameters:

  • time (Time)

    the UTC time

  • longitude (Astronoby::Angle)

    the observer’s longitude

Returns:



69
70
71
72
73
74
75
# File 'lib/astronoby/coordinates/equatorial.rb', line 69

def compute_hour_angle(time:, longitude:)
  last = LocalApparentSiderealTime.from_utc(time.utc, longitude: longitude)
  ha = (last.time - @right_ascension.hours)
  ha += Constants::HOURS_PER_DAY if ha.negative?

  Angle.from_hours(ha)
end

#position_angle_to(other) ⇒ Astronoby::Angle

Position angle of another point as seen from this one, measured eastward (counterclockwise) from the direction of the north celestial pole. Both points must be expressed in the same frame.

Parameters:

Returns:



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/astronoby/coordinates/equatorial.rb', line 147

def position_angle_to(other)
  delta_right_ascension = other.right_ascension - @right_ascension

  Angle.from_radians(
    Math.atan2(
      other.declination.cos * delta_right_ascension.sin,
      other.declination.sin * @declination.cos -
        other.declination.cos * @declination.sin *
          delta_right_ascension.cos
    )
  )
end

#to_ecliptic(instant:, obliquity: MeanObliquity.at(instant)) ⇒ Astronoby::Coordinates::Ecliptic

Converts to ecliptic coordinates.

Source:

Title: Celestial Calculations
Author: J. L. Lawrence
Edition: MIT Press
Chapter: 4 - Orbits and Coordinate Systems

Parameters:

  • instant (Astronoby::Instant)

    the time instant for the obliquity

  • obliquity (Astronoby::Angle) (defaults to: MeanObliquity.at(instant))

    the obliquity of the ecliptic to rotate by. Defaults to the mean obliquity of date; pass the true obliquity when the equatorial coordinates already include nutation (true-of-date apparent and topocentric places).

Returns:



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/astronoby/coordinates/equatorial.rb', line 121

def to_ecliptic(instant:, obliquity: MeanObliquity.at(instant))
  y = Angle.from_radians(
    @right_ascension.sin * obliquity.cos +
    @declination.tan * obliquity.sin
  )
  x = Angle.from_radians(@right_ascension.cos)
  r = Angle.atan(y.radians / x.radians)
  longitude = Util::Trigonometry.adjustement_for_arctangent(y, x, r)

  latitude = Angle.asin(
    @declination.sin * obliquity.cos -
    @declination.cos * obliquity.sin * @right_ascension.sin
  )

  Ecliptic.new(
    latitude: latitude,
    longitude: longitude
  )
end

#to_horizontal(time:, observer:) ⇒ Astronoby::Coordinates::Horizontal

Converts to horizontal coordinates for a given observer and time.

Parameters:

Returns:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/astronoby/coordinates/equatorial.rb', line 82

def to_horizontal(time:, observer:)
  latitude = observer.latitude
  longitude = observer.longitude
  ha = @hour_angle || compute_hour_angle(time: time, longitude: longitude)
  t0 = @declination.sin * latitude.sin +
    @declination.cos * latitude.cos * ha.cos
  altitude = Angle.asin(t0)

  t1 = @declination.sin - latitude.sin * altitude.sin
  t2 = t1 / (latitude.cos * altitude.cos)
  t2 = t2.clamp(-1, 1)
  azimuth = Angle.acos(t2)

  if ha.sin.positive?
    azimuth =
      Angle.from_degrees(Constants::DEGREES_PER_CIRCLE - azimuth.degrees)
  end

  Horizontal.new(
    azimuth: azimuth,
    altitude: altitude,
    observer: observer
  )
end