// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2020 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include #include namespace WwiseGTE { template class DCPQuery, Segment> { public: struct Result { Real distance, sqrDistance; Real segmentParameter; // t in [0,1] Vector segmentClosest; // (1-t)*p[0] + t*p[1] }; Result operator()(Vector const& point, Segment const& segment) { Result result; // The direction vector is not unit length. The normalization is // deferred until it is needed. Vector direction = segment.p[1] - segment.p[0]; Vector diff = point - segment.p[1]; Real t = Dot(direction, diff); if (t >= (Real)0) { result.segmentParameter = (Real)1; result.segmentClosest = segment.p[1]; } else { diff = point - segment.p[0]; t = Dot(direction, diff); if (t <= (Real)0) { result.segmentParameter = (Real)0; result.segmentClosest = segment.p[0]; } else { Real sqrLength = Dot(direction, direction); if (sqrLength > (Real)0) { t /= sqrLength; result.segmentParameter = t; result.segmentClosest = segment.p[0] + t * direction; } else { result.segmentParameter = (Real)0; result.segmentClosest = segment.p[0]; } } } diff = point - result.segmentClosest; result.sqrDistance = Dot(diff, diff); result.distance = std::sqrt(result.sqrDistance); return result; } }; // Template aliases for convenience. template using DCPPointSegment = DCPQuery, Segment>; template using DCPPoint2Segment2 = DCPPointSegment<2, Real>; template using DCPPoint3Segment3 = DCPPointSegment<3, Real>; }