class Polygon

Public Class Methods

new(p) click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 4
def initialize(p)
  @sides = p.length
  @vertices = sort(p)
end

Public Instance Methods

isConvex() click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 9
def isConvex
  vectors = []
  for i in 1..@sides
    vectors << @vertices[i % @sides] - @vertices[i-1]
  end
  cross_product = each_cross_product(vectors)
  return isSameDir(cross_product) ? true : false
end
isInside(target) click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 18
def isInside(target)
  if isConvex
    target_vector = target_vector(target)
    cross_product = each_cross_product(target_vector)
    return isSameDir(cross_product) ? 1 : 0
  end

  return -1
end

Protected Instance Methods

each_cross_product(vectors) click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 55
def each_cross_product(vectors)

  cross_product = []
  len = vectors.length

  for i in 1..len
    cross_product << vectors[i-1].cross_product(vectors[i % @sides])
  end

  return cross_product
end
isSameDir(cross_product) click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 67
def isSameDir(cross_product)
  len = cross_product.length
  for i in 1..len
    if cross_product[i-1][2] * cross_product[i % len][2] < 0
      return false
    end
  end
  return true
end
sort(p) click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 29
def sort(p)

  x = y = 0
  for v in p
    x += v[0]
    y += v[1]
  end
  avg_dot = [x/@sides, y/@sides]

  arctan = []
  for v in p
    arctan << Math.atan2(v[0] - avg_dot[0], v[1] - avg_dot[1])
  end
  ind = arctan.map{|e| arctan.sort.index(e)}
  p = p.sort_by{|x| ind[p.index(x)]}
  return p
end
target_vector(target) click to toggle source
# File lib/point-in-polygon/Polygon.rb, line 47
def target_vector(target)
  target_vector = []
  for v in @vertices
    target_vector << v - target
  end
  return target_vector
end