DistPointTriangleExact.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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/Triangle.h>
  10. namespace WwiseGTE
  11. {
  12. template <int N, typename Rational>
  13. class DistancePointTriangleExact
  14. {
  15. public:
  16. struct Result
  17. {
  18. Rational sqrDistance;
  19. // barycentric coordinates for triangle.v[3]
  20. Rational parameter[3];
  21. Vector<N, Rational> closest;
  22. };
  23. Result operator()(Vector<N, Rational> const& point, Triangle<N, Rational> const& triangle)
  24. {
  25. Vector<N, Rational> diff = point - triangle.v[0];
  26. Vector<N, Rational> edge0 = triangle.v[1] - triangle.v[0];
  27. Vector<N, Rational> edge1 = triangle.v[2] - triangle.v[0];
  28. Rational a00 = Dot(edge0, edge0);
  29. Rational a01 = Dot(edge0, edge1);
  30. Rational a11 = Dot(edge1, edge1);
  31. Rational b0 = -Dot(diff, edge0);
  32. Rational b1 = -Dot(diff, edge1);
  33. Rational const zero = (Rational)0;
  34. Rational const one = (Rational)1;
  35. Rational det = a00 * a11 - a01 * a01;
  36. Rational t0 = a01 * b1 - a11 * b0;
  37. Rational t1 = a01 * b0 - a00 * b1;
  38. if (t0 + t1 <= det)
  39. {
  40. if (t0 < zero)
  41. {
  42. if (t1 < zero) // region 4
  43. {
  44. if (b0 < zero)
  45. {
  46. t1 = zero;
  47. if (-b0 >= a00) // V1
  48. {
  49. t0 = one;
  50. }
  51. else // E01
  52. {
  53. t0 = -b0 / a00;
  54. }
  55. }
  56. else
  57. {
  58. t0 = zero;
  59. if (b1 >= zero) // V0
  60. {
  61. t1 = zero;
  62. }
  63. else if (-b1 >= a11) // V2
  64. {
  65. t1 = one;
  66. }
  67. else // E20
  68. {
  69. t1 = -b1 / a11;
  70. }
  71. }
  72. }
  73. else // region 3
  74. {
  75. t0 = zero;
  76. if (b1 >= zero) // V0
  77. {
  78. t1 = zero;
  79. }
  80. else if (-b1 >= a11) // V2
  81. {
  82. t1 = one;
  83. }
  84. else // E20
  85. {
  86. t1 = -b1 / a11;
  87. }
  88. }
  89. }
  90. else if (t1 < zero) // region 5
  91. {
  92. t1 = zero;
  93. if (b0 >= zero) // V0
  94. {
  95. t0 = zero;
  96. }
  97. else if (-b0 >= a00) // V1
  98. {
  99. t0 = one;
  100. }
  101. else // E01
  102. {
  103. t0 = -b0 / a00;
  104. }
  105. }
  106. else // region 0, interior
  107. {
  108. Rational invDet = one / det;
  109. t0 *= invDet;
  110. t1 *= invDet;
  111. }
  112. }
  113. else
  114. {
  115. Rational tmp0, tmp1, numer, denom;
  116. if (t0 < zero) // region 2
  117. {
  118. tmp0 = a01 + b0;
  119. tmp1 = a11 + b1;
  120. if (tmp1 > tmp0)
  121. {
  122. numer = tmp1 - tmp0;
  123. denom = a00 - (Rational)2 * a01 + a11;
  124. if (numer >= denom) // V1
  125. {
  126. t0 = one;
  127. t1 = zero;
  128. }
  129. else // E12
  130. {
  131. t0 = numer / denom;
  132. t1 = one - t0;
  133. }
  134. }
  135. else
  136. {
  137. t0 = zero;
  138. if (tmp1 <= zero) // V2
  139. {
  140. t1 = one;
  141. }
  142. else if (b1 >= zero) // V0
  143. {
  144. t1 = zero;
  145. }
  146. else // E20
  147. {
  148. t1 = -b1 / a11;
  149. }
  150. }
  151. }
  152. else if (t1 < zero) // region 6
  153. {
  154. tmp0 = a01 + b1;
  155. tmp1 = a00 + b0;
  156. if (tmp1 > tmp0)
  157. {
  158. numer = tmp1 - tmp0;
  159. denom = a00 - (Rational)2 * a01 + a11;
  160. if (numer >= denom) // V2
  161. {
  162. t1 = one;
  163. t0 = zero;
  164. }
  165. else // E12
  166. {
  167. t1 = numer / denom;
  168. t0 = one - t1;
  169. }
  170. }
  171. else
  172. {
  173. t1 = zero;
  174. if (tmp1 <= zero) // V1
  175. {
  176. t0 = one;
  177. }
  178. else if (b0 >= zero) // V0
  179. {
  180. t0 = zero;
  181. }
  182. else // E01
  183. {
  184. t0 = -b0 / a00;
  185. }
  186. }
  187. }
  188. else // region 1
  189. {
  190. numer = a11 + b1 - a01 - b0;
  191. if (numer <= zero) // V2
  192. {
  193. t0 = zero;
  194. t1 = one;
  195. }
  196. else
  197. {
  198. denom = a00 - (Rational)2 * a01 + a11;
  199. if (numer >= denom) // V1
  200. {
  201. t0 = one;
  202. t1 = zero;
  203. }
  204. else // 12
  205. {
  206. t0 = numer / denom;
  207. t1 = one - t0;
  208. }
  209. }
  210. }
  211. }
  212. Result result;
  213. result.parameter[0] = one - t0 - t1;
  214. result.parameter[1] = t0;
  215. result.parameter[2] = t1;
  216. result.closest = triangle.v[0] + t0 * edge0 + t1 * edge1;
  217. diff = point - result.closest;
  218. result.sqrDistance = Dot(diff, diff);
  219. return result;
  220. }
  221. };
  222. }