diff --git a/modules/intersect.lua b/modules/intersect.lua index c8d7086..0d185ae 100644 --- a/modules/intersect.lua +++ b/modules/intersect.lua @@ -13,6 +13,25 @@ local min = math.min local max = math.max local intersect = {} +-- Checks if a point belongs to the segment +-- p is a vec3 +-- seg[1] is a vec3 +-- seg[2] is a vec3 +-- Returns a boolean +function intersect.point_segment(p, seg) + local min, max = vec3.component_sort(seg[1], seg[2]) + if min.x <= p.x and + min.y <= p.y and + min.z <= p.z and + p.x <= max.x and + p.y <= max.y and + p.z <= max.z + then + return true + end + return false +end + -- https://blogs.msdn.microsoft.com/rezanour/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests/ -- point is a vec3 -- triangle[1] is a vec3 @@ -305,39 +324,13 @@ end -- e is a number function intersect.segment_segment(a, b, e) local c, d = intersect.line_line(a, b, e) - - if c and (( - a[1].x <= c[1].x and - a[1].y <= c[1].y and - a[1].z <= c[1].z and - c[1].x <= a[2].x and - c[1].y <= a[2].y and - c[1].z <= a[2].z - ) or ( - a[1].x >= c[1].x and - a[1].y >= c[1].y and - a[1].z >= c[1].z and - c[1].x >= a[2].x and - c[1].y >= a[2].y and - c[1].z >= a[2].z - )) and (( - b[1].x <= c[2].x and - b[1].y <= c[2].y and - b[1].z <= c[2].z and - c[2].x <= b[2].x and - c[2].y <= b[2].y and - c[2].z <= b[2].z - ) or ( - b[1].x >= c[2].x and - b[1].y >= c[2].y and - b[1].z >= c[2].z and - c[2].x >= b[2].x and - c[2].y >= b[2].y and - c[2].z >= b[2].z - )) then + if c and + intersect.point_segment(c[1], a) and + intersect.point_segment(c[2], a) and + intersect.point_segment(c[1], b) and + intersect.point_segment(c[2], b) then return c, d end - -- segments do not intersect return false end diff --git a/modules/vec3.lua b/modules/vec3.lua index b653506..d03e43f 100644 --- a/modules/vec3.lua +++ b/modules/vec3.lua @@ -309,6 +309,14 @@ function vec3.component_max(a, b) return new(math.max(a.x, b.x), math.max(a.y, b.y), math.max(a.z, b.z)) end +--- Return the component-wise minimum and maximum of two vectors. +-- @tparam vec3 a Left hand operand +-- @tparam vec3 b Right hand operand +-- @treturn vec3, vec3 sorted vectors +function vec3.component_sort(a, b) + return vec3.component_min(a, b), vec3.component_max(a, b) +end + -- Negate x axis only of vector. -- @tparam vec3 a Vector to x-flip. -- @treturn vec3 x-flipped vector