diff --git a/src/libslic3r/Line.hpp b/src/libslic3r/Line.hpp index 1edd1f5e9..d90757bed 100644 --- a/src/libslic3r/Line.hpp +++ b/src/libslic3r/Line.hpp @@ -40,11 +40,12 @@ template auto get_b(L &&l) { return Traits>::get_b(l) // Distance to the closest point of line. template -double distance_to_squared(const L &line, const Vec, Scalar> &point, Vec, Scalar> *nearest_point) +inline double distance_to_squared(const L &line, const Vec, Scalar> &point, Vec, Scalar> *nearest_point) { - const Vec, double> v = (get_b(line) - get_a(line)).template cast(); - const Vec, double> va = (point - get_a(line)).template cast(); - const double l2 = v.squaredNorm(); // avoid a sqrt + using VecType = Vec, double>; + const VecType v = (get_b(line) - get_a(line)).template cast(); + const VecType va = (point - get_a(line)).template cast(); + const double l2 = v.squaredNorm(); if (l2 == 0.0) { // a == b case *nearest_point = get_a(line); @@ -53,19 +54,20 @@ double distance_to_squared(const L &line, const Vec, Scalar> &point, V // Consider the line extending the segment, parameterized as a + t (b - a). // We find projection of this point onto the line. // It falls where t = [(this-a) . (b-a)] / |b-a|^2 - const double t = va.dot(v) / l2; + const double t = va.dot(v); if (t <= 0.0) { // beyond the 'a' end of the segment *nearest_point = get_a(line); return va.squaredNorm(); - } else if (t >= 1.0) { + } else if (t >= l2) { // beyond the 'b' end of the segment *nearest_point = get_b(line); return (point - get_b(line)).template cast().squaredNorm(); } - *nearest_point = (get_a(line).template cast() + t * v).template cast>(); - return (t * v - va).squaredNorm(); + const VecType w = ((t / l2) * v).eval(); + *nearest_point = (get_a(line).template cast() + w).template cast>(); + return (w - va).squaredNorm(); } // Distance to the closest point of line.