class Geometry::PointInPolygon

Public Instance Methods

inside?() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 5
def inside?
  point_location == :inside
end
on_the_boundary?() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 13
def on_the_boundary?
  point_location == :on_the_boundary
end
outside?() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 9
def outside?
  point_location == :outside
end
point_location() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 17
def point_location
  return :outside unless bounding_box.contains?(point)
  return :on_the_boundary if point_is_vertex? || point_on_edge?

  intersection_count(choose_good_ray).odd? ? :inside : :outside
end

Private Instance Methods

choose_good_ray() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 37
def choose_good_ray
  ray = random_ray
  while ! good_ray?(ray) do
    ray = random_ray
  end
  ray
end
good_ray?(ray) click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 45
def good_ray?(ray)
  edges.none? { |edge| !edge.length.zero? && edge.parallel_to?(ray) } && vertices.none? { |vertex| ray.contains_point?(vertex) }
end
intersection_count(ray) click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 49
def intersection_count(ray)
  edges.select { |edge| edge.intersects_with?(ray) }.size
end
point_is_vertex?() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 29
def point_is_vertex?
  vertices.any? { |vertex| vertex == point }
end
point_on_edge?() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 33
def point_on_edge?
  edges.any? { |edge| edge.contains_point?(point) }
end
random_ray() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 53
def random_ray
  random_direction = rand * (2 * Math::PI)
  
  ray_endpoint = Point sufficient_ray_radius * Math.cos(random_direction), sufficient_ray_radius * Math.sin(random_direction)
  Segment point, ray_endpoint
end
sufficient_ray_radius() click to toggle source
# File lib/geometry/algorithms/point_in_polygon.rb, line 60
def sufficient_ray_radius
  @sufficient_ray_radius ||= bounding_box.diagonal.length * 2
end