Class: PerfectShape::Polygon
- Includes:
- MultiPoint
- Defined in:
- lib/perfect_shape/polygon.rb
Instance Attribute Summary
Attributes included from MultiPoint
Instance Method Summary collapse
-
#contain?(x_or_point, y = nil, outline: false, distance_tolerance: 0) ⇒ Boolean
Checks if polygon contains point (two-number Array or x, y args) using the Ray Casting Algorithm (aka Even-Odd Rule): en.wikipedia.org/wiki/Point_in_polygon.
- #edges ⇒ Object
Methods included from MultiPoint
#initialize, #max_x, #max_y, #min_x, #min_y, normalize_point_array
Methods inherited from Shape
#==, #bounding_box, #center_point, #center_x, #center_y, #height, #max_x, #max_y, #min_x, #min_y, #width
Instance Method Details
#contain?(x_or_point, y = nil, outline: false, distance_tolerance: 0) ⇒ Boolean
Checks if polygon contains point (two-number Array or x, y args) using the Ray Casting Algorithm (aka Even-Odd Rule): en.wikipedia.org/wiki/Point_in_polygon
the polygon, false if the point lies outside of the polygon’s bounds.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/perfect_shape/polygon.rb', line 40 def contain?(x_or_point, y = nil, outline: false, distance_tolerance: 0) x, y = Point.normalize_point(x_or_point, y) return unless x && y if outline edges.any? { |edge| edge.contain?(x, y, distance_tolerance: distance_tolerance) } else npoints = points.count xpoints = points.map(&:first) ypoints = points.map(&:last) return false if npoints <= 2 || !bounding_box.contain?(x, y) hits = 0 lastx = xpoints[npoints - 1] lasty = ypoints[npoints - 1] # Walk the edges of the polygon npoints.times do |i| curx = xpoints[i] cury = ypoints[i] if cury == lasty lastx = curx lasty = cury next end if curx < lastx if x >= lastx lastx = curx lasty = cury next end leftx = curx else if x >= curx lastx = curx lasty = cury next end leftx = lastx end if cury < lasty if y < cury || y >= lasty lastx = curx lasty = cury next end if x < leftx hits += 1 lastx = curx lasty = cury next end test1 = x - curx test2 = y - cury else if y < lasty || y >= cury lastx = curx lasty = cury next end if x < leftx hits += 1 lastx = curx lasty = cury next end test1 = x - lastx test2 = y - lasty end hits += 1 if (test1 < (test2 / (lasty - cury) * (lastx - curx))) end (hits & 1) != 0 end end |