Class: SGS::Bearing

Inherits:
Object
  • Object
show all
Defined in:
lib/sgs/location.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.



237
238
239
240
# 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

Instance Attribute Details

#distanceObject

Returns the value of attribute distance.



233
234
235
# File 'lib/sgs/location.rb', line 233

def distance
  @distance
end

Class Method Details

.absolute(angle) ⇒ Object

Handy function to re-adjust an angle away from negative



262
263
264
# File 'lib/sgs/location.rb', line 262

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.



269
270
271
# File 'lib/sgs/location.rb', line 269

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();



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# 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

.degrees(angle, distance) ⇒ Object

Create a bearing from an angle in degrees.



244
245
246
# File 'lib/sgs/location.rb', line 244

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

.dtor(deg) ⇒ Object

Handy function to translate degrees to radians



250
251
252
# File 'lib/sgs/location.rb', line 250

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

.rtod(rad) ⇒ Object

Handy function to translate radians to degrees



256
257
258
# File 'lib/sgs/location.rb', line 256

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

Instance Method Details

#angleObject

Get the angle



313
314
315
# File 'lib/sgs/location.rb', line 313

def angle
  @angle
end

#angle=(angle) ⇒ Object

Set the angle



307
308
309
# File 'lib/sgs/location.rb', line 307

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

#angle_dObject

Return the angle (in degrees)



319
320
321
# File 'lib/sgs/location.rb', line 319

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)



325
326
327
# File 'lib/sgs/location.rb', line 325

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

#to_sObject

Convert to a string



331
332
333
# File 'lib/sgs/location.rb', line 331

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