Skip to content

Commit 3b33cb5

Browse files
swipesenseswipesense
authored andcommitted
use previous method of edge checking
1 parent 265f35b commit 3b33cb5

File tree

2 files changed

+18
-40
lines changed

2 files changed

+18
-40
lines changed
Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Geometry
22
class PointInPolygon < Struct.new(:point, :polygon)
33
extend Memoist
4-
4+
55
def inside?
66
point_location == :inside
77
end
@@ -18,7 +18,7 @@ def point_location
1818
return :outside unless bounding_box.contains?(point)
1919
return :on_the_boundary if point_is_vertex? || point_on_edge?
2020

21-
intersection_count(choose_good_ray).odd? ? :inside : :outside
21+
point_inside_polygon? ? :inside : :outside
2222
end
2323

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

37-
def choose_good_ray
38-
ray = random_ray
39-
while ! good_ray?(ray) do
40-
ray = random_ray
41-
end
42-
ray
43-
end
37+
def point_inside_polygon?
38+
# Algorithm source:
39+
# https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html
4440

45-
def good_ray?(ray)
46-
edges.none? { |edge| !edge.length.zero? && edge.parallel_to?(ray) } && vertices.none? { |vertex| ray.contains_point?(vertex) }
47-
end
48-
49-
def intersection_count(ray)
50-
edges.select { |edge| edge.intersects_with?(ray) }.size
51-
end
52-
53-
def random_ray
54-
random_direction = rand * (2 * Math::PI)
55-
56-
ray_endpoint = Point sufficient_ray_radius * Math.cos(random_direction), sufficient_ray_radius * Math.sin(random_direction)
57-
Segment point, ray_endpoint
58-
end
41+
result = false
42+
43+
vertices.each_with_index do |vertex, i|
44+
previous_vertex = vertices[i - 1] || vertex.last
45+
if ((vertex.y > point.y) != (previous_vertex.y > point.y)) &&
46+
(point.x < (previous_vertex.x - vertex.x) * (point.y - vertex.y) / (previous_vertex.y - vertex.y) + vertex.x)
47+
result = !result
48+
end
49+
end
5950

60-
def sufficient_ray_radius
61-
@sufficient_ray_radius ||= bounding_box.diagonal.length * 2
51+
result
6252
end
6353
end
6454
end

lib/geometry/polygon.rb

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,13 @@ 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-
# 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
21+
point_in_polygon = PointInPolygon.new(point, self)
22+
point_in_polygon.inside? || point_in_polygon.on_the_boundary?
3523
end
3624

3725
def area

0 commit comments

Comments
 (0)