From 4b78e17b1587611e3e6cfdb6074f85ffbfc933f8 Mon Sep 17 00:00:00 2001 From: Simon Puchert Date: Sat, 6 Jul 2019 17:41:13 +0200 Subject: Optimize get_closest_point_to_segment*. By combining all scalar factors we can get rid of a scalar * vector multiplication and a square root operation, since the resulting formula only uses the squared length. --- core/math/geometry.h | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/core/math/geometry.h b/core/math/geometry.h index 0e144e491f..e4f3ff799e 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -455,16 +455,15 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; if (d <= 0.0) return p_segment[0]; // before first point - else if (d >= l) + else if (d >= 1.0) return p_segment[1]; // after first point else return p_segment[0] + n * d; // inside @@ -474,12 +473,11 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; return p_segment[0] + n * d; // inside } @@ -488,16 +486,15 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; if (d <= 0.0) return p_segment[0]; // before first point - else if (d >= l) + else if (d >= 1.0) return p_segment[1]; // after first point else return p_segment[0] + n * d; // inside @@ -521,12 +518,11 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; return p_segment[0] + n * d; // inside } -- cgit v1.2.3