DistPoint3Circle3.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/DCPQuery.h>
  9. #include <Mathematics/Circle3.h>
  10. // The 3D point-circle distance algorithm is described in
  11. // https://www.geometrictools.com/Documentation/DistanceToCircle3.pdf
  12. // The notation used in the code matches that of the document.
  13. namespace WwiseGTE
  14. {
  15. template <typename Real>
  16. class DCPQuery<Real, Vector3<Real>, Circle3<Real>>
  17. {
  18. public:
  19. // Either a single point on the circle is closest to 'point', in
  20. // which case 'equidistant' is false, or the entire circle is
  21. // closest to 'point', in which case 'equidistant' is true. In the
  22. // latter case, the query returns the circle point C+r*U, where C is
  23. // the circle center, r is the circle radius, and U is a vector
  24. // perpendicular to the normal N for the plane of the circle.
  25. struct Result
  26. {
  27. Real distance, sqrDistance;
  28. Vector3<Real> circleClosest;
  29. bool equidistant;
  30. };
  31. Result operator()(Vector3<Real> const& point, Circle3<Real> const& circle)
  32. {
  33. Result result;
  34. // Projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N.
  35. Vector3<Real> PmC = point - circle.center;
  36. Vector3<Real> QmC = PmC - Dot(circle.normal, PmC) * circle.normal;
  37. Real lengthQmC = Length(QmC);
  38. if (lengthQmC > (Real)0)
  39. {
  40. result.circleClosest = circle.center + (circle.radius / lengthQmC) * QmC;
  41. result.equidistant = false;
  42. }
  43. else
  44. {
  45. // All circle points are equidistant from P. Return one of
  46. // them.
  47. Vector3<Real> basis[3];
  48. basis[0] = circle.normal;
  49. ComputeOrthogonalComplement(1, basis);
  50. result.circleClosest = circle.center + circle.radius * basis[1];
  51. result.equidistant = true;
  52. }
  53. Vector3<Real> diff = point - result.circleClosest;
  54. result.sqrDistance = Dot(diff, diff);
  55. result.distance = std::sqrt(result.sqrDistance);
  56. return result;
  57. }
  58. };
  59. }