class Quadtree::Point

Simple coordinate object to represent points in some space.

Attributes

data[RW]

Optional payload attached to this instance. @return [Object] payload attached to this instance.

x[RW]

The X coordinate of this instance. @return [Float, Integer] X coordinate.

y[RW]

The Y coordinate of this instance. @return [Float, Integer] Y coordinate.

Public Class Methods

from_json(json_data) click to toggle source

Construct a {Quadtree::Point} from a JSON String.

@param [String] json_data input JSON String.

@return [Quadtree::Point] the {Quadtree::Point} contained in the JSON String.

# File lib/quadtree/point.rb, line 79
def self.from_json(json_data)
  new(json_data['x'], json_data['y'], json_data['data'])
end
new(x, y, data = nil) click to toggle source

@param x [Float, Integer] X coordinate. @param y [Float, Integer] Y coordinate. @param data [Object] payload payload attached to this instance

(optional).

@raise [UnknownTypeError] if one or more input parameters (x and y)

has the wrong type.
# File lib/quadtree/point.rb, line 24
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

Public Instance Methods

distance_to(other) click to toggle source

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

@param other [Point] the other {Point}. @return [Float] the distance to the other {Point}.

# File lib/quadtree/point.rb, line 88
def distance_to(other)
  Math.sqrt((other.x - x)**2 + (other.y - y)**2)
end
haversine_distance_to(other) click to toggle source

This will calculate distance to another {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!

@param other [Point] the other {Point}. @return [Float] the distance, in meters, to the other {Point}.

# File lib/quadtree/point.rb, line 108
def haversine_distance_to(other)
  lat1 = y * (Math::PI / 180.0)
  lat2 = other.y * (Math::PI / 180.0)
  dlat = (other.y - y) * (Math::PI / 180.0)
  dlon = (other.x - x) * (Math::PI / 180.0)

  # a = sin²(Δφ/2) + cos φ_1 ⋅ cos φ_2 ⋅ sin²(Δλ/2)
  a = calculate_haversine_a(lat1, lat2, dlat, dlon)
  # c = 2 ⋅ atan2( √a, √(1−a) )
  c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
  # d = R ⋅ c
  6371 * 1000.0 * c
end
to_h() click to toggle source

Create a Hash for this {Point}.

@return [Hash] Hash representation of this {Point}.

# File lib/quadtree/point.rb, line 36
def to_h
  {
    'x': x,
    'y': y,
    'data': process_data(data)
  }
end
to_hash() click to toggle source

Create a Hash for this {Point}.

@return [Hash] Hash representation of this {Point}.

# File lib/quadtree/point.rb, line 49
def to_hash
  to_h
end
to_json(*_args) click to toggle source

Create a JSON String representation of this {Point}.

@return [String] JSON String of this {Point}.

# File lib/quadtree/point.rb, line 58
def to_json(*_args)
  require 'json'
  to_h.to_json
end
to_s() click to toggle source

Create a String for this {Point}.

@return [String] String representation of this {Point}.

# File lib/quadtree/point.rb, line 68
def to_s
  to_h.to_s
end

Private Instance Methods

calculate_haversine_a(lat1, lat2, dlat, dlon) click to toggle source
# File lib/quadtree/point.rb, line 124
def calculate_haversine_a(lat1, lat2, dlat, dlon)
  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)
end
get_float(any_input) click to toggle source
# File lib/quadtree/point.rb, line 152
def get_float(any_input)
  return Float(any_input) if any_input.is_a? String
  return any_input if any_input.is_a? Float

  nil
rescue StandardError
  nil
end
get_integer(any_input) click to toggle source
# File lib/quadtree/point.rb, line 143
def get_integer(any_input)
  return Integer(any_input) if any_input.is_a? String
  return any_input if any_input.is_a? Integer

  nil
rescue StandardError
  nil
end
get_typed_numeric(any_input) click to toggle source
# File lib/quadtree/point.rb, line 134
def get_typed_numeric(any_input)
  # Try integer first since float will parse integers too
  return get_integer(any_input) unless get_integer(any_input).nil?
  # Try Float next
  return get_float(any_input) unless get_float(any_input).nil?

  raise UnknownTypeError, "Unknown type for parameter: #{any_input.class}"
end
process_data(data) click to toggle source
# File lib/quadtree/point.rb, line 130
def process_data(data)
  data.nil? || data.is_a?(Array) || data.is_a?(String) || data.is_a?(Numeric) ? data : data.to_h
end