123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- // 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 <Mathematics/DCPQuery.h>
- #include <Mathematics/Circle3.h>
- // The 3D point-circle distance algorithm is described in
- // https://www.geometrictools.com/Documentation/DistanceToCircle3.pdf
- // The notation used in the code matches that of the document.
- namespace WwiseGTE
- {
- template <typename Real>
- class DCPQuery<Real, Vector3<Real>, Circle3<Real>>
- {
- public:
- // Either a single point on the circle is closest to 'point', in
- // which case 'equidistant' is false, or the entire circle is
- // closest to 'point', in which case 'equidistant' is true. In the
- // latter case, the query returns the circle point C+r*U, where C is
- // the circle center, r is the circle radius, and U is a vector
- // perpendicular to the normal N for the plane of the circle.
- struct Result
- {
- Real distance, sqrDistance;
- Vector3<Real> circleClosest;
- bool equidistant;
- };
- Result operator()(Vector3<Real> const& point, Circle3<Real> const& circle)
- {
- Result result;
- // Projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N.
- Vector3<Real> PmC = point - circle.center;
- Vector3<Real> QmC = PmC - Dot(circle.normal, PmC) * circle.normal;
- Real lengthQmC = Length(QmC);
- if (lengthQmC > (Real)0)
- {
- result.circleClosest = circle.center + (circle.radius / lengthQmC) * QmC;
- result.equidistant = false;
- }
- else
- {
- // All circle points are equidistant from P. Return one of
- // them.
- Vector3<Real> basis[3];
- basis[0] = circle.normal;
- ComputeOrthogonalComplement(1, basis);
- result.circleClosest = circle.center + circle.radius * basis[1];
- result.equidistant = true;
- }
- Vector3<Real> diff = point - result.circleClosest;
- result.sqrDistance = Dot(diff, diff);
- result.distance = std::sqrt(result.sqrDistance);
- return result;
- }
- };
- }
|