Class: SGS::Bearing

Inherits:
Object
  • Object
show all
Defined in:
lib/sgs/bearing.rb

Overview

Class for dealing with the angle/distance vector.

 Note that for convenience, we retain the angle in Radians. The distance is in nautical miles.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(angle = 0.0, distance = 0.0) ⇒ Bearing

Create the Bearing instance.



52
53
54
55
# File 'lib/sgs/bearing.rb', line 52

def initialize(angle = 0.0, distance = 0.0)
  self.angle = angle.to_f
  self.distance = distance.to_f
end

Instance Attribute Details

#distanceObject

Returns the value of attribute distance.



48
49
50
# File 'lib/sgs/bearing.rb', line 48

def distance
  @distance
end

Class Method Details

.absolute(angle) ⇒ Object

Handy function to re-adjust an angle away from negative



77
78
79
# File 'lib/sgs/bearing.rb', line 77

def self.absolute(angle)
  (angle + 2.0 * Math::PI) % (2.0 * Math::PI)
end

.absolute_d(angle) ⇒ Object

Another handy function to re-adjust an angle (in degrees) away from negative.



84
85
86
# File 'lib/sgs/bearing.rb', line 84

def self.absolute_d(angle)
  (angle + 360) % 360
end

.compute(loc1, loc2) ⇒ Object

Haversine formula for calculating distance and angle, given two locations.

To calculate an angle and distance from two positions:

This code was derived from formulae on the Movable Type site: www.movable-type.co.uk/scripts/latlong.html

var d = Math.acos(Math.sin(lat1)*Math.sin(lat2) +

Math.cos(lat1)*Math.cos(lat2) *
Math.cos(lon2-lon1)) * R;

var y = Math.sin(dLon) * Math.cos(lat2); var x = Math.cos(lat1)*Math.sin(lat2) -

Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);

var angle = Math.atan2(y, x).toDeg();



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/sgs/bearing.rb', line 104

def self.compute(loc1, loc2)
  bearing = new
  sin_lat1 = Math.sin(loc1.latitude)
  sin_lat2 = Math.sin(loc2.latitude)
  cos_lat1 = Math.cos(loc1.latitude)
  cos_lat2 = Math.cos(loc2.latitude)
  sin_dlon = Math.sin(loc2.longitude - loc1.longitude)
  cos_dlon = Math.cos(loc2.longitude - loc1.longitude)
  bearing.distance = Math.acos(sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos_dlon) *
                            SGS::EARTH_RADIUS
  y = sin_dlon * cos_lat2
  x = cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon
  bearing.angle = Math.atan2(y, x)
  bearing
end

.degrees(angle, distance) ⇒ Object

Create a bearing from an angle in degrees.



59
60
61
# File 'lib/sgs/bearing.rb', line 59

def self.degrees(angle, distance)
  new(Bearing.dtor(angle), distance)
end

.dtor(deg) ⇒ Object

Handy function to translate degrees to radians



65
66
67
# File 'lib/sgs/bearing.rb', line 65

def self.dtor(deg)
  deg.to_f * Math::PI / 180.0
end

.rtod(rad) ⇒ Object

Handy function to translate radians to degrees



71
72
73
# File 'lib/sgs/bearing.rb', line 71

def self.rtod(rad)
  rad.to_f * 180.0 / Math::PI
end

Instance Method Details

#angleObject

Get the angle



128
129
130
# File 'lib/sgs/bearing.rb', line 128

def angle
  @angle
end

#angle=(angle) ⇒ Object

Set the angle



122
123
124
# File 'lib/sgs/bearing.rb', line 122

def angle=(angle)
  @angle = Bearing.absolute(angle)
end

#angle_dObject

Return the angle (in degrees)



134
135
136
# File 'lib/sgs/bearing.rb', line 134

def angle_d
  Bearing.rtod(@angle).to_i
end

#back_angleObject

Get the back-angle (the angle viewed from the opposite end of the line)



140
141
142
# File 'lib/sgs/bearing.rb', line 140

def back_angle
  Bearing.absolute(@angle - Math::PI)
end

#to_sObject

Convert to a string



146
147
148
# File 'lib/sgs/bearing.rb', line 146

def to_s
  "BRNG %03dd,%.3fnm" % [angle_d, @distance]
end