IntrArc2Arc2.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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/IntrCircle2Circle2.h>
  9. #include <Mathematics/Arc2.h>
  10. namespace WwiseGTE
  11. {
  12. template <typename Real>
  13. class FIQuery<Real, Arc2<Real>, Arc2<Real>>
  14. {
  15. public:
  16. // The possible 'configuration' in Result are listed as an
  17. // enumeration. The valid array elements are listed in the comments.
  18. enum
  19. {
  20. NO_INTERSECTION,
  21. NONCOCIRCULAR_ONE_POINT, // point[0]
  22. NONCOCIRCULAR_TWO_POINTS, // point[0], point[1]
  23. COCIRCULAR_ONE_POINT, // point[0]
  24. COCIRCULAR_TWO_POINTS, // point[0], point[1]
  25. COCIRCULAR_ONE_POINT_ONE_ARC, // point[0], arc[0]
  26. COCIRCULAR_ONE_ARC, // arc[0]
  27. COCIRCULAR_TWO_ARCS // arc[0], arc[1]
  28. };
  29. struct Result
  30. {
  31. // 'true' iff configuration != NO_INTERSECTION
  32. bool intersect;
  33. // one of the enumerations listed previously
  34. int configuration;
  35. Vector2<Real> point[2];
  36. Arc2<Real> arc[2];
  37. };
  38. Result operator()(Arc2<Real> const& arc0, Arc2<Real> const& arc1)
  39. {
  40. // Assume initially there are no intersections. If we find at
  41. // least one intersection, we will set result.intersect to 'true'.
  42. Result result;
  43. result.intersect = false;
  44. result.configuration = NO_INTERSECTION;
  45. result.point[0] = { (Real)0, (Real)0 };
  46. result.point[1] = { (Real)0, (Real)0 };
  47. Circle2<Real> circle0(arc0.center, arc0.radius);
  48. Circle2<Real> circle1(arc1.center, arc1.radius);
  49. FIQuery<Real, Circle2<Real>, Circle2<Real>> ccQuery;
  50. auto ccResult = ccQuery(circle0, circle1);
  51. if (!ccResult.intersect)
  52. {
  53. // The arcs do not intersect.
  54. result.configuration = NO_INTERSECTION;
  55. return result;
  56. }
  57. if (ccResult.numIntersections == std::numeric_limits<int>::max())
  58. {
  59. // The arcs are cocircular. Determine whether they overlap.
  60. // Let arc0 be <A0,A1> and arc1 be <B0,B1>. The points are
  61. // ordered counterclockwise around the circle of the arc.
  62. if (arc1.Contains(arc0.end[0]))
  63. {
  64. result.intersect = true;
  65. if (arc1.Contains(arc0.end[1]))
  66. {
  67. if (arc0.Contains(arc1.end[0]) && arc0.Contains(arc1.end[1]))
  68. {
  69. if (arc0.end[0] == arc1.end[0] && arc0.end[1] == arc1.end[1])
  70. {
  71. // The arcs are the same.
  72. result.configuration = COCIRCULAR_ONE_ARC;
  73. result.arc[0] = arc0;
  74. }
  75. else
  76. {
  77. // arc0 and arc1 overlap in two disjoint
  78. // subsets.
  79. if (arc0.end[0] != arc1.end[1])
  80. {
  81. if (arc1.end[0] != arc0.end[1])
  82. {
  83. // The arcs overlap in two disjoint
  84. // subarcs, each of positive subtended
  85. // angle: <A0,B1>, <A1,B0>
  86. result.configuration = COCIRCULAR_TWO_ARCS;
  87. result.arc[0] = Arc2<Real>(arc0.center, arc0.radius, arc0.end[0], arc1.end[1]);
  88. result.arc[1] = Arc2<Real>(arc0.center, arc0.radius, arc1.end[0], arc0.end[1]);
  89. }
  90. else // B0 = A1
  91. {
  92. // The intersection is a point {A1}
  93. // and an arc <A0,B1>.
  94. result.configuration = COCIRCULAR_ONE_POINT_ONE_ARC;
  95. result.point[0] = arc0.end[1];
  96. result.arc[0] = Arc2<Real>(arc0.center, arc0.radius, arc0.end[0], arc1.end[1]);
  97. }
  98. }
  99. else // A0 = B1
  100. {
  101. if (arc1.end[0] != arc0.end[1])
  102. {
  103. // The intersection is a point {A0}
  104. // and an arc <A1,B0>.
  105. result.configuration = COCIRCULAR_ONE_POINT_ONE_ARC;
  106. result.point[0] = arc0.end[0];
  107. result.arc[0] = Arc2<Real>(arc0.center, arc0.radius, arc1.end[0], arc0.end[1]);
  108. }
  109. else
  110. {
  111. // The arcs shared endpoints, so the
  112. // union is a circle.
  113. result.configuration = COCIRCULAR_TWO_POINTS;
  114. result.point[0] = arc0.end[0];
  115. result.point[1] = arc0.end[1];
  116. }
  117. }
  118. }
  119. }
  120. else
  121. {
  122. // Arc0 inside arc1, <B0,A0,A1,B1>.
  123. result.configuration = COCIRCULAR_ONE_ARC;
  124. result.arc[0] = arc0;
  125. }
  126. }
  127. else
  128. {
  129. if (arc0.end[0] != arc1.end[1])
  130. {
  131. // Arc0 and arc1 overlap, <B0,A0,B1,A1>.
  132. result.configuration = COCIRCULAR_ONE_ARC;
  133. result.arc[0] = Arc2<Real>(arc0.center, arc0.radius, arc0.end[0], arc1.end[1]);
  134. }
  135. else
  136. {
  137. // Arc0 and arc1 share endpoint, <B0,A0,B1,A1>
  138. // with A0 = B1.
  139. result.configuration = COCIRCULAR_ONE_POINT;
  140. result.point[0] = arc0.end[0];
  141. }
  142. }
  143. return result;
  144. }
  145. if (arc1.Contains(arc0.end[1]))
  146. {
  147. result.intersect = true;
  148. if (arc0.end[1] != arc1.end[0])
  149. {
  150. // Arc0 and arc1 overlap in a single arc,
  151. // <A0,B0,A1,B1>.
  152. result.configuration = COCIRCULAR_ONE_ARC;
  153. result.arc[0] = Arc2<Real>(arc0.center, arc0.radius, arc1.end[0], arc0.end[1]);
  154. }
  155. else
  156. {
  157. // Arc0 and arc1 share endpoint, <A0,B0,A1,B1>
  158. // with B0 = A1.
  159. result.configuration = COCIRCULAR_ONE_POINT;
  160. result.point[0] = arc1.end[0];
  161. }
  162. return result;
  163. }
  164. if (arc0.Contains(arc1.end[0]))
  165. {
  166. // Arc1 inside arc0, <A0,B0,B1,A1>.
  167. result.intersect = true;
  168. result.configuration = COCIRCULAR_ONE_ARC;
  169. result.arc[0] = arc1;
  170. }
  171. else
  172. {
  173. // Arcs do not overlap, <A0,A1,B0,B1>.
  174. result.configuration = NO_INTERSECTION;
  175. }
  176. return result;
  177. }
  178. // Test whether circle-circle intersection points are on the arcs.
  179. int numIntersections = 0;
  180. for (int i = 0; i < ccResult.numIntersections; ++i)
  181. {
  182. if (arc0.Contains(ccResult.point[i]) && arc1.Contains(ccResult.point[i]))
  183. {
  184. result.point[numIntersections++] = ccResult.point[i];
  185. result.intersect = true;
  186. }
  187. }
  188. if (numIntersections == 2)
  189. {
  190. result.configuration = NONCOCIRCULAR_TWO_POINTS;
  191. }
  192. else if (numIntersections == 1)
  193. {
  194. result.configuration = NONCOCIRCULAR_ONE_POINT;
  195. }
  196. else
  197. {
  198. result.configuration = NO_INTERSECTION;
  199. }
  200. return result;
  201. }
  202. };
  203. }