IntrLine2Segment2.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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/IntrLine2Line2.h>
  9. #include <Mathematics/Segment.h>
  10. namespace WwiseGTE
  11. {
  12. template <typename Real>
  13. class TIQuery<Real, Line2<Real>, Segment2<Real>>
  14. {
  15. public:
  16. struct Result
  17. {
  18. bool intersect;
  19. // The number is 0 (no intersection), 1 (line and segment
  20. // intersect in a single point) or std::numeric_limits<int>::max()
  21. // (line and segment are collinear).
  22. int numIntersections;
  23. };
  24. Result operator()(Line2<Real> const& line, Segment2<Real> const& segment)
  25. {
  26. Result result;
  27. Vector2<Real> segOrigin, segDirection;
  28. Real segExtent;
  29. segment.GetCenteredForm(segOrigin, segDirection, segExtent);
  30. FIQuery<Real, Line2<Real>, Line2<Real>> llQuery;
  31. auto llResult = llQuery(line, Line2<Real>(segOrigin, segDirection));
  32. if (llResult.numIntersections == 1)
  33. {
  34. // Test whether the line-line intersection is on the segment.
  35. if (std::fabs(llResult.line1Parameter[0]) <= segExtent)
  36. {
  37. result.intersect = true;
  38. result.numIntersections = 1;
  39. }
  40. else
  41. {
  42. result.intersect = false;
  43. result.numIntersections = 0;
  44. }
  45. }
  46. else
  47. {
  48. result.intersect = llResult.intersect;
  49. result.numIntersections = llResult.numIntersections;
  50. }
  51. return result;
  52. }
  53. };
  54. template <typename Real>
  55. class FIQuery<Real, Line2<Real>, Segment2<Real>>
  56. {
  57. public:
  58. struct Result
  59. {
  60. bool intersect;
  61. // The number is 0 (no intersection), 1 (line and segment
  62. // intersect in a single point) or std::numeric_limits<int>::max()
  63. // (line and segment are collinear).
  64. int numIntersections;
  65. // If numIntersections is 1, the intersection is
  66. // point = line.origin + lineParameter[0] * line.direction
  67. // = segment.origin +
  68. // segmentParameter[0] * segment.direction
  69. // If numIntersections is maxInt, point is not valid but the
  70. // intervals are
  71. // lineParameter[] = { -maxReal, +maxReal }
  72. // segmentParameter[] = { -segmentExtent, segmentExtent }
  73. Real lineParameter[2], segmentParameter[2];
  74. Vector2<Real> point;
  75. };
  76. Result operator()(Line2<Real> const& line, Segment2<Real> const& segment)
  77. {
  78. Result result;
  79. Vector2<Real> segOrigin, segDirection;
  80. Real segExtent;
  81. segment.GetCenteredForm(segOrigin, segDirection, segExtent);
  82. FIQuery<Real, Line2<Real>, Line2<Real>> llQuery;
  83. auto llResult = llQuery(line, Line2<Real>(segOrigin, segDirection));
  84. if (llResult.numIntersections == 1)
  85. {
  86. // Test whether the line-line intersection is on the ray.
  87. if (std::fabs(llResult.line1Parameter[0]) <= segExtent)
  88. {
  89. result.intersect = true;
  90. result.numIntersections = 1;
  91. result.lineParameter[0] = llResult.line0Parameter[0];
  92. result.segmentParameter[0] = llResult.line1Parameter[0];
  93. result.point = llResult.point;
  94. }
  95. else
  96. {
  97. result.intersect = false;
  98. result.numIntersections = 0;
  99. }
  100. }
  101. else if (llResult.numIntersections == std::numeric_limits<int>::max())
  102. {
  103. result.intersect = true;
  104. result.numIntersections = std::numeric_limits<int>::max();
  105. Real maxReal = std::numeric_limits<Real>::max();
  106. result.lineParameter[0] = -maxReal;
  107. result.lineParameter[1] = +maxReal;
  108. result.segmentParameter[0] = -segExtent;
  109. result.segmentParameter[1] = +segExtent;
  110. }
  111. else
  112. {
  113. result.intersect = false;
  114. result.numIntersections = 0;
  115. }
  116. return result;
  117. }
  118. };
  119. }