Skip to content

Commit

Permalink
use previous method of edge checking
Browse files Browse the repository at this point in the history
  • Loading branch information
swipesense authored and swipesense committed May 6, 2017
1 parent 265f35b commit 3b33cb5
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 40 deletions.
40 changes: 15 additions & 25 deletions lib/geometry/algorithms/point_in_polygon.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Geometry
class PointInPolygon < Struct.new(:point, :polygon)
extend Memoist

def inside?
point_location == :inside
end
Expand All @@ -18,7 +18,7 @@ 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
point_inside_polygon? ? :inside : :outside
end

delegate :vertices, :edges, :bounding_box, :to => :polygon
Expand All @@ -34,31 +34,21 @@ def point_on_edge?
edges.any? { |edge| edge.contains_point?(point) }
end

def choose_good_ray
ray = random_ray
while ! good_ray?(ray) do
ray = random_ray
end
ray
end
def point_inside_polygon?
# Algorithm source:
# https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html

def good_ray?(ray)
edges.none? { |edge| !edge.length.zero? && edge.parallel_to?(ray) } && vertices.none? { |vertex| ray.contains_point?(vertex) }
end

def intersection_count(ray)
edges.select { |edge| edge.intersects_with?(ray) }.size
end

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
result = false

vertices.each_with_index do |vertex, i|
previous_vertex = vertices[i - 1] || vertex.last
if ((vertex.y > point.y) != (previous_vertex.y > point.y)) &&
(point.x < (previous_vertex.x - vertex.x) * (point.y - vertex.y) / (previous_vertex.y - vertex.y) + vertex.x)
result = !result
end
end

def sufficient_ray_radius
@sufficient_ray_radius ||= bounding_box.diagonal.length * 2
result
end
end
end
18 changes: 3 additions & 15 deletions lib/geometry/polygon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,13 @@ def edges
def bounding_box
leftbottom = Point vertices.map(&:x).min, vertices.map(&:y).min
righttop = Point vertices.map(&:x).max, vertices.map(&:y).max

BoundingBox.new leftbottom, righttop
end

def contains?(point)
# Algorithm source:
# https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html

result = false

vertices.each_with_index do |vertex, i|
previous_vertex = vertices[i - 1] || vertex.last
if ((vertex.y > point.y) != (previous_vertex.y > point.y)) &&
(point.x < (previous_vertex.x - vertex.x) * (point.y - vertex.y) / (previous_vertex.y - vertex.y) + vertex.x)
result = !result
end
end

result
point_in_polygon = PointInPolygon.new(point, self)
point_in_polygon.inside? || point_in_polygon.on_the_boundary?
end

def area
Expand Down

0 comments on commit 3b33cb5

Please sign in to comment.