From bc7846b697d3ece9c7ab93d24cb9ce739ea36524 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Tue, 5 Jan 2021 13:38:55 -0800 Subject: [PATCH] Clarify for myself how the line-point intersection check works --- src/engine/collision.cpp | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/engine/collision.cpp b/src/engine/collision.cpp index ea620c1..316a235 100644 --- a/src/engine/collision.cpp +++ b/src/engine/collision.cpp @@ -116,19 +116,44 @@ namespace egn{ return false; } bool check_collision(const line& l, const point& r, float epsilon){ + /* + C (the point) + . + /| + / | + / | + / | + .-----------------. + A b B + (line start) (line end) + + L(t) = A + t*(B - A) + ab = (B - A) + ac = (C - A) + solve for b + L(b) = A + b*(ab) + b = (ac * ab) / (ab * ab) + u = ab / |ab| + dist = |C - L(b)| + */ math::vec3 ab = (l.point2 - l.point1); math::vec3 ac = (r - l.point1); //check if point is within the line segment - float c1 = ac * ab; - if(c1 < (0 - epsilon)) - return false; - float c2 = ab * ab; - if(c2 < (c1 - epsilon)) + //don't need to divide b by (ab * ab) to check if it's less than 0 + float b = ac * ab; + if(b < (0 - epsilon)) return false; - //check if the point is zero distance from the line - float b = c1 / c2; + //don't need to divide b by (ab * ab) to check if it's greater than (ab * ab) + float ab2 = ab * ab; + if(b > (ab2 + epsilon)) + return false; + + //now divide once we know that the point is within this line segment + b = b / ab2; + + //check if the point is zero(ish) distance from the line math::vec3 pb = l.point1 + (ab * b); return math::fuzzy_eq(r - pb, math::vec3(math::zero_initialize), epsilon); }