class SGS::Bearing
Class for dealing with the angle/distance vector.
Note that for convenience, we retain the angle in Radians. The
distance is in nautical miles.
Attributes
Public Class Methods
Handy function to re-adjust an angle away from negative
# File lib/sgs/location.rb, line 262 def self.absolute(angle) (angle + 2.0 * Math::PI) % (2.0 * Math::PI) end
Another handy function to re-adjust an angle (in degrees) away from negative.
# File lib/sgs/location.rb, line 269 def self.absolute_d(angle) (angle + 360) % 360 end
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();
# File lib/sgs/location.rb, line 289 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
Create a bearing from an angle in degrees.
# File lib/sgs/location.rb, line 244 def self.degrees(angle, distance) new(Bearing.dtor(angle), distance) end
Handy function to translate degrees to radians
# File lib/sgs/location.rb, line 250 def self.dtor(deg) deg.to_f * Math::PI / 180.0 end
Create the Bearing
instance.
# File lib/sgs/location.rb, line 237 def initialize(angle = 0.0, distance = 0.0) self.angle = angle.to_f self.distance = distance.to_f end
Handy function to translate radians to degrees
# File lib/sgs/location.rb, line 256 def self.rtod(rad) rad.to_f * 180.0 / Math::PI end
Public Instance Methods
Get the angle
# File lib/sgs/location.rb, line 313 def angle @angle end
Set the angle
# File lib/sgs/location.rb, line 307 def angle=(angle) @angle = Bearing.absolute(angle) end
Return the angle (in degrees)
# File lib/sgs/location.rb, line 319 def angle_d Bearing.rtod(@angle).to_i end
Get the back-angle (the angle viewed from the opposite end of the line)
# File lib/sgs/location.rb, line 325 def back_angle Bearing.absolute(@angle - Math::PI) end
Convert to a string
# File lib/sgs/location.rb, line 331 def to_s "BRNG %03dd,%.3fnm" % [angle_d, @distance] end