Skip to content

Commit 265f35b

Browse files
swipesenseswipesense
authored andcommitted
deterministic algorithm to determine whether a point is in a polygon
1 parent 5ee2eb0 commit 265f35b

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

lib/geometry/polygon.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,25 @@ def edges
1313
def bounding_box
1414
leftbottom = Point vertices.map(&:x).min, vertices.map(&:y).min
1515
righttop = Point vertices.map(&:x).max, vertices.map(&:y).max
16-
16+
1717
BoundingBox.new leftbottom, righttop
1818
end
1919

2020
def contains?(point)
21-
point_in_polygon = PointInPolygon.new(point, self)
22-
point_in_polygon.inside? || point_in_polygon.on_the_boundary?
21+
# Algorithm source:
22+
# https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html
23+
24+
result = false
25+
26+
vertices.each_with_index do |vertex, i|
27+
previous_vertex = vertices[i - 1] || vertex.last
28+
if ((vertex.y > point.y) != (previous_vertex.y > point.y)) &&
29+
(point.x < (previous_vertex.x - vertex.x) * (point.y - vertex.y) / (previous_vertex.y - vertex.y) + vertex.x)
30+
result = !result
31+
end
32+
end
33+
34+
result
2335
end
2436

2537
def area

0 commit comments

Comments
 (0)