DistPointSegment.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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/Segment.h>
  10. namespace WwiseGTE
  11. {
  12. template <int N, typename Real>
  13. class DCPQuery<Real, Vector<N, Real>, Segment<N, Real>>
  14. {
  15. public:
  16. struct Result
  17. {
  18. Real distance, sqrDistance;
  19. Real segmentParameter; // t in [0,1]
  20. Vector<N, Real> segmentClosest; // (1-t)*p[0] + t*p[1]
  21. };
  22. Result operator()(Vector<N, Real> const& point, Segment<N, Real> const& segment)
  23. {
  24. Result result;
  25. // The direction vector is not unit length. The normalization is
  26. // deferred until it is needed.
  27. Vector<N, Real> direction = segment.p[1] - segment.p[0];
  28. Vector<N, Real> diff = point - segment.p[1];
  29. Real t = Dot(direction, diff);
  30. if (t >= (Real)0)
  31. {
  32. result.segmentParameter = (Real)1;
  33. result.segmentClosest = segment.p[1];
  34. }
  35. else
  36. {
  37. diff = point - segment.p[0];
  38. t = Dot(direction, diff);
  39. if (t <= (Real)0)
  40. {
  41. result.segmentParameter = (Real)0;
  42. result.segmentClosest = segment.p[0];
  43. }
  44. else
  45. {
  46. Real sqrLength = Dot(direction, direction);
  47. if (sqrLength > (Real)0)
  48. {
  49. t /= sqrLength;
  50. result.segmentParameter = t;
  51. result.segmentClosest = segment.p[0] + t * direction;
  52. }
  53. else
  54. {
  55. result.segmentParameter = (Real)0;
  56. result.segmentClosest = segment.p[0];
  57. }
  58. }
  59. }
  60. diff = point - result.segmentClosest;
  61. result.sqrDistance = Dot(diff, diff);
  62. result.distance = std::sqrt(result.sqrDistance);
  63. return result;
  64. }
  65. };
  66. // Template aliases for convenience.
  67. template <int N, typename Real>
  68. using DCPPointSegment = DCPQuery<Real, Vector<N, Real>, Segment<N, Real>>;
  69. template <typename Real>
  70. using DCPPoint2Segment2 = DCPPointSegment<2, Real>;
  71. template <typename Real>
  72. using DCPPoint3Segment3 = DCPPointSegment<3, Real>;
  73. }