From b2c16e223e41ebad6c3963b9b08be3f3c92bde6e Mon Sep 17 00:00:00 2001 From: Gianmarco Cherchi <gianmarcher@gmail.com> Date: Thu, 26 Oct 2023 17:08:02 +0200 Subject: [PATCH] point_segment_sqrd_dist added to segment_utils --- include/cinolib/geometry/segment_utils.cpp | 29 ++++++++++++++++++++++ include/cinolib/geometry/segment_utils.h | 13 ++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/cinolib/geometry/segment_utils.cpp b/include/cinolib/geometry/segment_utils.cpp index 026adac4..7e85e0d5 100644 --- a/include/cinolib/geometry/segment_utils.cpp +++ b/include/cinolib/geometry/segment_utils.cpp @@ -137,4 +137,33 @@ mat<3,1,T> segment_intersection(const mat<3,1,T> & s00, return p; } +//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +/* Given a segments S(s00,s01) and a point p, returns the squared distance between point p and segment S + * Ref: Real Time Collision Detection, Section 5.1.2.1 + */ + +template<class T> +CINO_INLINE +T point_segment_sqrd_dist(const mat<3,1,T> & s00, //a + const mat<3,1,T> & s01, //b + const mat<3,1,T> & p) +{ + mat<3,1,T> ab = s01 - s00; + mat<3,1,T> ac = p - s00; + mat<3,1,T> bc = p - s01; + T e = ac.dot(ab); + + // Handle cases where p projects outside S + if (e <= 0.0f) + return ac.dot(ac); + + T f = ab.dot(ab); + if (e >= f) + return bc.dot(bc); + + // Handle cases where p projects onto S + return ac.dot(ac) - (e * e) / f; +} + } diff --git a/include/cinolib/geometry/segment_utils.h b/include/cinolib/geometry/segment_utils.h index 76024dfb..4ad5b324 100644 --- a/include/cinolib/geometry/segment_utils.h +++ b/include/cinolib/geometry/segment_utils.h @@ -73,8 +73,21 @@ mat<3,1,T> segment_intersection(const mat<3,1,T> & s00, const mat<3,1,T> & s01, const mat<3,1,T> & s10, const mat<3,1,T> & s11); + +//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +/* Given a segments S(s00,s01) and a point p, returns the squared distance between point p and segment S + * Ref: Real Time Collision Detection, Section 5.1.2.1 + */ + + template<class T> + CINO_INLINE + T point_segment_sqrd_dist(const mat<3,1,T> & s00, + const mat<3,1,T> & s01, + const mat<3,1,T> & p); } + #ifndef CINO_STATIC_LIB #include "segment_utils.cpp" #endif