Class: SGS::Bearing
- Inherits:
-
Object
- Object
- SGS::Bearing
- 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
-
#distance ⇒ Object
Returns the value of attribute distance.
Class Method Summary collapse
-
.absolute(angle) ⇒ Object
Handy function to re-adjust an angle away from negative.
-
.absolute_d(angle) ⇒ Object
Another handy function to re-adjust an angle (in degrees) away from negative.
-
.compute(loc1, loc2) ⇒ Object
Haversine formula for calculating distance and angle, given two locations.
-
.degrees(angle, distance) ⇒ Object
Create a bearing from an angle in degrees.
-
.dtor(deg) ⇒ Object
Handy function to translate degrees to radians.
-
.rtod(rad) ⇒ Object
Handy function to translate radians to degrees.
-
.rtox(rad) ⇒ Object
Convert radians to hex-degrees.
-
.xtor(val) ⇒ Object
Convert boat angle (0->255) to radians.
Instance Method Summary collapse
-
#angle ⇒ Object
Get the angle.
-
#angle=(angle) ⇒ Object
Set the angle.
-
#angle_d ⇒ Object
Return the angle (in degrees).
-
#back_angle ⇒ Object
Get the back-angle (the angle viewed from the opposite end of the line).
-
#distance_m ⇒ Object
Return the distance in metres.
-
#initialize(angle = 0.0, distance = 0.0) ⇒ Bearing
constructor
Create the Bearing instance.
-
#to_s ⇒ Object
Convert to a string.
Constructor Details
#initialize(angle = 0.0, distance = 0.0) ⇒ Bearing
Create the Bearing instance. Angle is in radians, distance in nautical miles.
54 55 56 57 |
# File 'lib/sgs/bearing.rb', line 54 def initialize(angle = 0.0, distance = 0.0) self.angle = angle.to_f self.distance = distance.to_f end |
Instance Attribute Details
#distance ⇒ Object
Returns the value of attribute distance.
49 50 51 |
# File 'lib/sgs/bearing.rb', line 49 def distance @distance end |
Class Method Details
.absolute(angle) ⇒ Object
Handy function to re-adjust an angle away from negative
96 97 98 |
# File 'lib/sgs/bearing.rb', line 96 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.
103 104 105 |
# File 'lib/sgs/bearing.rb', line 103 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();
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/sgs/bearing.rb', line 123 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) * 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.
61 62 63 |
# File 'lib/sgs/bearing.rb', line 61 def self.degrees(angle, distance) new(Bearing.dtor(angle), distance) end |
.dtor(deg) ⇒ Object
Handy function to translate degrees to radians
67 68 69 |
# File 'lib/sgs/bearing.rb', line 67 def self.dtor(deg) deg.to_f * Math::PI / 180.0 end |
.rtod(rad) ⇒ Object
Handy function to translate radians to degrees
73 74 75 |
# File 'lib/sgs/bearing.rb', line 73 def self.rtod(rad) rad.to_f * 180.0 / Math::PI end |
.rtox(rad) ⇒ Object
Convert radians to hex-degrees.
90 91 92 |
# File 'lib/sgs/bearing.rb', line 90 def self.rtox(rad) (rad.to_f * 128.0 / Math::PI).round.to_i & 0xff end |
.xtor(val) ⇒ Object
Convert boat angle (0->255) to radians. The boat uses an 8bit quantity to represent an angle, where 256 maps to 360 degrees. This makes angle arithmetic quite simple on an 8 bit processor, but useless for something which has a proper FPU. These two helper functions convert to and from radians.
83 84 85 86 |
# File 'lib/sgs/bearing.rb', line 83 def self.xtor(val) val &= 0xff val.to_f * Math::PI / 128.0 end |
Instance Method Details
#angle ⇒ Object
Get the angle
147 148 149 |
# File 'lib/sgs/bearing.rb', line 147 def angle @angle end |
#angle=(angle) ⇒ Object
Set the angle
141 142 143 |
# File 'lib/sgs/bearing.rb', line 141 def angle=(angle) @angle = Bearing.absolute(angle) end |
#angle_d ⇒ Object
Return the angle (in degrees)
153 154 155 |
# File 'lib/sgs/bearing.rb', line 153 def angle_d Bearing.rtod(@angle).to_i end |
#back_angle ⇒ Object
Get the back-angle (the angle viewed from the opposite end of the line)
159 160 161 |
# File 'lib/sgs/bearing.rb', line 159 def back_angle Bearing.absolute(@angle - Math::PI) end |
#distance_m ⇒ Object
Return the distance in metres
165 166 167 |
# File 'lib/sgs/bearing.rb', line 165 def distance_m @distance * 1852.0 end |
#to_s ⇒ Object
Convert to a string
171 172 173 174 175 176 177 |
# File 'lib/sgs/bearing.rb', line 171 def to_s if @distance > 0.9 "BRNG %03dd,%.3fNM" % [angle_d, @distance] else "BRNG %03dd,%.1fm" % [angle_d, distance_m] end end |