Class: Astronoby::Angle

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/astronoby/angle.rb

Constant Summary collapse

MIN_PRECISION =
10
FORMATS =
%i[dms hms].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(radians) ⇒ Angle

Returns a new instance of Angle.



63
64
65
66
# File 'lib/astronoby/angle.rb', line 63

def initialize(radians)
  @radians = radians
  freeze
end

Instance Attribute Details

#radiansObject (readonly)

Returns the value of attribute radians.



61
62
63
# File 'lib/astronoby/angle.rb', line 61

def radians
  @radians
end

Class Method Details

.acos(ratio) ⇒ Object



50
51
52
53
# File 'lib/astronoby/angle.rb', line 50

def acos(ratio)
  radians = Math.acos(ratio)
  from_radians(radians)
end

.asin(ratio) ⇒ Object



45
46
47
48
# File 'lib/astronoby/angle.rb', line 45

def asin(ratio)
  radians = Math.asin(ratio)
  from_radians(radians)
end

.atan(ratio) ⇒ Object



55
56
57
58
# File 'lib/astronoby/angle.rb', line 55

def atan(ratio)
  radians = Math.atan(ratio)
  from_radians(radians)
end

.from_degrees(degrees) ⇒ Object



20
21
22
23
# File 'lib/astronoby/angle.rb', line 20

def from_degrees(degrees)
  radians = degrees / Constants::PI_IN_DEGREES * Math::PI
  from_radians(radians)
end

.from_dms(degree, minute, second) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/astronoby/angle.rb', line 37

def from_dms(degree, minute, second)
  sign = degree.negative? ? -1 : 1
  degrees = degree.abs +
    minute / Constants::MINUTES_PER_HOUR +
    second / Constants::SECONDS_PER_HOUR
  from_degrees(sign * degrees)
end

.from_hms(hour, minute, second) ⇒ Object



30
31
32
33
34
35
# File 'lib/astronoby/angle.rb', line 30

def from_hms(hour, minute, second)
  hours = hour +
    minute / Constants::MINUTES_PER_HOUR +
    second / Constants::SECONDS_PER_HOUR
  from_hours(hours)
end

.from_hours(hours) ⇒ Object



25
26
27
28
# File 'lib/astronoby/angle.rb', line 25

def from_hours(hours)
  radians = hours * Constants::RADIAN_PER_HOUR
  from_radians(radians)
end

.from_radians(radians) ⇒ Object



15
16
17
18
# File 'lib/astronoby/angle.rb', line 15

def from_radians(radians)
  normalized_radians = radians.remainder(Constants::RADIANS_PER_CIRCLE)
  new(normalized_radians)
end

.zeroObject



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

def zero
  new(0)
end

Instance Method Details

#+(other) ⇒ Object



76
77
78
# File 'lib/astronoby/angle.rb', line 76

def +(other)
  self.class.from_radians(radians + other.radians)
end

#-(other) ⇒ Object



80
81
82
# File 'lib/astronoby/angle.rb', line 80

def -(other)
  self.class.from_radians(@radians - other.radians)
end

#-@Object



84
85
86
# File 'lib/astronoby/angle.rb', line 84

def -@
  self.class.from_radians(-@radians)
end

#<=>(other) ⇒ Object



116
117
118
119
120
# File 'lib/astronoby/angle.rb', line 116

def <=>(other)
  return unless other.is_a?(self.class)

  radians <=> other.radians
end

#cosObject



92
93
94
# File 'lib/astronoby/angle.rb', line 92

def cos
  Math.cos(radians)
end

#degreesObject



68
69
70
# File 'lib/astronoby/angle.rb', line 68

def degrees
  @radians * Constants::PI_IN_DEGREES / Math::PI
end

#hashObject



112
113
114
# File 'lib/astronoby/angle.rb', line 112

def hash
  [radians, self.class].hash
end

#hoursObject



72
73
74
# File 'lib/astronoby/angle.rb', line 72

def hours
  @radians / Constants::RADIAN_PER_HOUR
end

#negative?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/astronoby/angle.rb', line 104

def negative?
  radians < 0
end

#positive?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/astronoby/angle.rb', line 100

def positive?
  radians > 0
end

#sinObject



88
89
90
# File 'lib/astronoby/angle.rb', line 88

def sin
  Math.sin(radians)
end

#str(format) ⇒ Object



123
124
125
126
127
128
129
130
131
132
# File 'lib/astronoby/angle.rb', line 123

def str(format)
  case format
  when :dms then to_dms(degrees).format
  when :hms then to_hms(hours).format
  else
    raise UnsupportedFormatError.new(
      "Expected a format between #{FORMATS.join(", ")}, got #{format}"
    )
  end
end

#tanObject



96
97
98
# File 'lib/astronoby/angle.rb', line 96

def tan
  Math.tan(radians)
end

#to_dms(deg) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/astronoby/angle.rb', line 134

def to_dms(deg)
  sign = deg.negative? ? "-" : "+"
  absolute_degrees = deg.abs
  degrees = absolute_degrees.floor
  decimal_minutes = Constants::MINUTES_PER_DEGREE *
    (absolute_degrees - degrees)
  absolute_decimal_minutes = (
    Constants::MINUTES_PER_DEGREE * (absolute_degrees - degrees)
  ).abs
  minutes = decimal_minutes.floor
  seconds = Constants::SECONDS_PER_MINUTE * (
    absolute_decimal_minutes - absolute_decimal_minutes.floor
  )

  Dms.new(sign, degrees, minutes, seconds.floor(4))
end

#to_hms(hrs) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/astronoby/angle.rb', line 151

def to_hms(hrs)
  absolute_hours = hrs.abs
  hours = absolute_hours.floor
  decimal_minutes = Constants::MINUTES_PER_HOUR * (absolute_hours - hours)
  absolute_decimal_minutes = (
    Constants::MINUTES_PER_HOUR * (absolute_hours - hours)
  ).abs
  minutes = decimal_minutes.floor
  seconds = Constants::SECONDS_PER_MINUTE * (
    absolute_decimal_minutes - absolute_decimal_minutes.floor
  )

  Hms.new(hours, minutes, seconds.floor(4))
end

#zero?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/astronoby/angle.rb', line 108

def zero?
  radians.zero?
end