diff --git a/intersect.lua b/intersect.lua index bb8f687..c5da48a 100644 --- a/intersect.lua +++ b/intersect.lua @@ -397,4 +397,25 @@ function intersect.aabb_aabb_collide_continuous( return false end +--check if a point is in a polygon +--point is the point to test +--poly is a list of points in order +--based on winding number, so re-intersecting areas are counted as solid rather than inverting +function intersect.point_in_poly(point, poly) + local wn = 0 + for i, a in ipairs(poly) do + local b = poly[i + 1] or poly[1] + if a.y <= point.y then + if b.y > point.y and vec2.winding_side(a, b, point) > 0 then + wn = wn + 1 + end + else + if b.y <= point.y and vec2.winding_side(a, b, point) < 0 then + wn = wn - 1 + end + end + end + return wn ~= 0 +end + return intersect diff --git a/vec2.lua b/vec2.lua index 2bfa6ba..02efe4e 100644 --- a/vec2.lua +++ b/vec2.lua @@ -532,6 +532,17 @@ function vec2.vrej(a, b) return a:copy():vreji(b) end +--get the winding side of p, relative to the line a-b +-- (this is based on the signed area of the triangle a-b-p) +-- return value: +-- >0 when p left of line +-- =0 when p on line +-- <0 when p right of line +function vec2.winding_side(a, b, p) + return (b.x - a.x) * (p.y - a.y) + - (p.x - a.x) * (b.y - a.y) +end + ----------------------------------------------------------- -- vector extension methods for special purposes -- (any common vector ops worth naming)