Class: Quadtree::Point

Inherits:
Object
  • Object
show all
Defined in:
lib/quadtree/point.rb

Overview

Simple coordinate object to represent points in some space.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x, y, data = nil) ⇒ Point

Returns a new instance of Point.

Raises:

  • (UnknownTypeError)

    if one or more input parameters (x and y) has the wrong type.



23
24
25
26
27
28
29
# File 'lib/quadtree/point.rb', line 23

def initialize(x, y, data=nil)

  self.x = get_typed_numeric(x)
  self.y = get_typed_numeric(y)

  self.data = data unless data.nil?
end

Instance Attribute Details

#dataObject

Optional payload attached to this instance.



15
16
17
# File 'lib/quadtree/point.rb', line 15

def data
  @data
end

#xFloat, Integer

The X coordinate of this instance.



7
8
9
# File 'lib/quadtree/point.rb', line 7

def x
  @x
end

#yFloat, Integer

The Y coordinate of this instance.



11
12
13
# File 'lib/quadtree/point.rb', line 11

def y
  @y
end

Instance Method Details

#distance_to(other) ⇒ Float

This will calculate distance to another Quadtree::Point, given that they are both in the same 2D space.



36
37
38
# File 'lib/quadtree/point.rb', line 36

def distance_to(other)
  Math.sqrt((other.x - self.x) ** 2 + (other.y - self.y) ** 2)
end

#haversine_distance_to(other) ⇒ Float

This will calculate distance to another Quadtree::Point using the Haversine formula. This means that it will treat #x as longitude and #y as latitude!

a = sin²(Δφ/2) + cos φ_1 ⋅ cos φ_2 ⋅ sin²(Δλ/2)

c = 2 ⋅ atan2( √a, √(1−a) )

d = R ⋅ c

where φ is latitude, λ is longitude, R is earth’s radius (mean radius = 6 371 km); note that angles need to be in radians to pass to trig functions!



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/quadtree/point.rb', line 56

def haversine_distance_to(other)
  # earth's radius

  r = 6371 * 1000.0
  # coverting degrees to radians

  lat1 = self.y * (Math::PI / 180.0)
  lat2 = other.y * (Math::PI / 180.0)
  dlat = (other.y - self.y) * (Math::PI / 180.0)
  dlon = (other.x - self.x) * (Math::PI / 180.0)

  # a = sin²(Δφ/2) + cos φ_1 ⋅ cos φ_2 ⋅ sin²(Δλ/2)

  a = Math.sin(dlat / 2.0) * Math.sin(dlat / 2.0) +
      Math.cos(lat1) * Math.cos(lat2) *
      Math.sin(dlon / 2.0) * Math.sin(dlon / 2.0)
  # c = 2 ⋅ atan2( √a, √(1−a) )

  c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
  # d = R ⋅ c

  return r * c
end