DisjointIntervals.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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 <vector>
  9. namespace WwiseGTE
  10. {
  11. // Compute Boolean operations of disjoint sets of half-open intervals of
  12. // the form [xmin,xmax) with xmin < xmax.
  13. template <typename Scalar>
  14. class DisjointIntervals
  15. {
  16. public:
  17. // Construction and destruction. The non-default constructor requires
  18. // that xmin < xmax.
  19. DisjointIntervals()
  20. {
  21. }
  22. DisjointIntervals(Scalar const& xmin, Scalar const& xmax)
  23. {
  24. if (xmin < xmax)
  25. {
  26. mEndpoints = { xmin, xmax };
  27. mEndpoints[0] = xmin;
  28. mEndpoints[1] = xmax;
  29. }
  30. }
  31. ~DisjointIntervals()
  32. {
  33. }
  34. // Copy operations.
  35. DisjointIntervals(DisjointIntervals const& other)
  36. :
  37. mEndpoints(other.mEndpoints)
  38. {
  39. }
  40. DisjointIntervals& operator=(DisjointIntervals const& other)
  41. {
  42. mEndpoints = other.mEndpoints;
  43. return *this;
  44. }
  45. // Move operations.
  46. DisjointIntervals(DisjointIntervals&& other)
  47. :
  48. mEndpoints(std::move(other.mEndpoints))
  49. {
  50. }
  51. DisjointIntervals& operator=(DisjointIntervals&& other)
  52. {
  53. mEndpoints = std::move(other.mEndpoints);
  54. return *this;
  55. }
  56. // The number of intervals in the set.
  57. inline int GetNumIntervals() const
  58. {
  59. return static_cast<int>(mEndpoints.size() / 2);
  60. }
  61. // The i-th interval is [xmin,xmax). The values xmin and xmax are
  62. // valid only when 0 <= i < GetNumIntervals().
  63. bool GetInterval(int i, Scalar& xmin, Scalar& xmax) const
  64. {
  65. int index = 2 * i;
  66. if (0 <= index && index < static_cast<int>(mEndpoints.size()))
  67. {
  68. xmin = mEndpoints[index];
  69. xmax = mEndpoints[++index];
  70. return true;
  71. }
  72. xmin = (Scalar)0;
  73. xmax = (Scalar)0;
  74. return false;
  75. }
  76. // Make this set empty.
  77. inline void Clear()
  78. {
  79. mEndpoints.clear();
  80. }
  81. // Insert [xmin,xmax) into the set. This is a Boolean 'union'
  82. // operation. The operation is successful only when xmin < xmax.
  83. bool Insert(Scalar const& xmin, Scalar const& xmax)
  84. {
  85. if (xmin < xmax)
  86. {
  87. DisjointIntervals input(xmin, xmax);
  88. DisjointIntervals output = *this | input;
  89. mEndpoints = std::move(output.mEndpoints);
  90. return true;
  91. }
  92. return false;
  93. }
  94. // Remove [xmin,xmax) from the set. This is a Boolean 'difference'
  95. // operation. The operation is successful only when xmin < xmax.
  96. bool Remove(Scalar const& xmin, Scalar const& xmax)
  97. {
  98. if (xmin < xmax)
  99. {
  100. DisjointIntervals input(xmin, xmax);
  101. DisjointIntervals output = std::move(*this - input);
  102. mEndpoints = std::move(output.mEndpoints);
  103. return true;
  104. }
  105. return false;
  106. }
  107. // Get the union of the interval sets, input0 union input1.
  108. friend DisjointIntervals operator|(DisjointIntervals const& input0, DisjointIntervals const& input1)
  109. {
  110. DisjointIntervals output;
  111. size_t const numEndpoints0 = input0.mEndpoints.size();
  112. size_t const numEndpoints1 = input1.mEndpoints.size();
  113. size_t i0 = 0, i1 = 0;
  114. int parity0 = 0, parity1 = 0;
  115. while (i0 < numEndpoints0 && i1 < numEndpoints1)
  116. {
  117. Scalar const& value0 = input0.mEndpoints[i0];
  118. Scalar const& value1 = input1.mEndpoints[i1];
  119. if (value0 < value1)
  120. {
  121. if (parity0 == 0)
  122. {
  123. parity0 = 1;
  124. if (parity1 == 0)
  125. {
  126. output.mEndpoints.push_back(value0);
  127. }
  128. }
  129. else
  130. {
  131. if (parity1 == 0)
  132. {
  133. output.mEndpoints.push_back(value0);
  134. }
  135. parity0 = 0;
  136. }
  137. ++i0;
  138. }
  139. else if (value1 < value0)
  140. {
  141. if (parity1 == 0)
  142. {
  143. parity1 = 1;
  144. if (parity0 == 0)
  145. {
  146. output.mEndpoints.push_back(value1);
  147. }
  148. }
  149. else
  150. {
  151. if (parity0 == 0)
  152. {
  153. output.mEndpoints.push_back(value1);
  154. }
  155. parity1 = 0;
  156. }
  157. ++i1;
  158. }
  159. else // value0 == value1
  160. {
  161. if (parity0 == parity1)
  162. {
  163. output.mEndpoints.push_back(value0);
  164. }
  165. parity0 ^= 1;
  166. parity1 ^= 1;
  167. ++i0;
  168. ++i1;
  169. }
  170. }
  171. while (i0 < numEndpoints0)
  172. {
  173. output.mEndpoints.push_back(input0.mEndpoints[i0]);
  174. ++i0;
  175. }
  176. while (i1 < numEndpoints1)
  177. {
  178. output.mEndpoints.push_back(input1.mEndpoints[i1]);
  179. ++i1;
  180. }
  181. return output;
  182. }
  183. // Get the intersection of the interval sets, input0 intersect is1.
  184. friend DisjointIntervals operator&(DisjointIntervals const& input0, DisjointIntervals const& input1)
  185. {
  186. DisjointIntervals output;
  187. size_t const numEndpoints0 = input0.mEndpoints.size();
  188. size_t const numEndpoints1 = input1.mEndpoints.size();
  189. size_t i0 = 0, i1 = 0;
  190. int parity0 = 0, parity1 = 0;
  191. while (i0 < numEndpoints0 && i1 < numEndpoints1)
  192. {
  193. Scalar const& value0 = input0.mEndpoints[i0];
  194. Scalar const& value1 = input1.mEndpoints[i1];
  195. if (value0 < value1)
  196. {
  197. if (parity0 == 0)
  198. {
  199. parity0 = 1;
  200. if (parity1 == 1)
  201. {
  202. output.mEndpoints.push_back(value0);
  203. }
  204. }
  205. else
  206. {
  207. if (parity1 == 1)
  208. {
  209. output.mEndpoints.push_back(value0);
  210. }
  211. parity0 = 0;
  212. }
  213. ++i0;
  214. }
  215. else if (value1 < value0)
  216. {
  217. if (parity1 == 0)
  218. {
  219. parity1 = 1;
  220. if (parity0 == 1)
  221. {
  222. output.mEndpoints.push_back(value1);
  223. }
  224. }
  225. else
  226. {
  227. if (parity0 == 1)
  228. {
  229. output.mEndpoints.push_back(value1);
  230. }
  231. parity1 = 0;
  232. }
  233. ++i1;
  234. }
  235. else // value0 == value1
  236. {
  237. if (parity0 == parity1)
  238. {
  239. output.mEndpoints.push_back(value0);
  240. }
  241. parity0 ^= 1;
  242. parity1 ^= 1;
  243. ++i0;
  244. ++i1;
  245. }
  246. }
  247. return output;
  248. }
  249. // Get the differences of the interval sets, input0 minus input1.
  250. friend DisjointIntervals operator-(DisjointIntervals const& input0, DisjointIntervals const& input1)
  251. {
  252. DisjointIntervals output;
  253. size_t const numEndpoints0 = input0.mEndpoints.size();
  254. size_t const numEndpoints1 = input1.mEndpoints.size();
  255. size_t i0 = 0, i1 = 0;
  256. int parity0 = 0, parity1 = 1;
  257. while (i0 < numEndpoints0 && i1 < numEndpoints1)
  258. {
  259. Scalar const& value0 = input0.mEndpoints[i0];
  260. Scalar const& value1 = input1.mEndpoints[i1];
  261. if (value0 < value1)
  262. {
  263. if (parity0 == 0)
  264. {
  265. parity0 = 1;
  266. if (parity1 == 1)
  267. {
  268. output.mEndpoints.push_back(value0);
  269. }
  270. }
  271. else
  272. {
  273. if (parity1 == 1)
  274. {
  275. output.mEndpoints.push_back(value0);
  276. }
  277. parity0 = 0;
  278. }
  279. ++i0;
  280. }
  281. else if (value1 < value0)
  282. {
  283. if (parity1 == 0)
  284. {
  285. parity1 = 1;
  286. if (parity0 == 1)
  287. {
  288. output.mEndpoints.push_back(value1);
  289. }
  290. }
  291. else
  292. {
  293. if (parity0 == 1)
  294. {
  295. output.mEndpoints.push_back(value1);
  296. }
  297. parity1 = 0;
  298. }
  299. ++i1;
  300. }
  301. else // value0 == value1
  302. {
  303. if (parity0 == parity1)
  304. {
  305. output.mEndpoints.push_back(value0);
  306. }
  307. parity0 ^= 1;
  308. parity1 ^= 1;
  309. ++i0;
  310. ++i1;
  311. }
  312. }
  313. while (i0 < numEndpoints0)
  314. {
  315. output.mEndpoints.push_back(input0.mEndpoints[i0]);
  316. ++i0;
  317. }
  318. return output;
  319. }
  320. // Get the exclusive or of the interval sets, input0 xor input1 =
  321. // (input0 minus input1) or (input1 minus input0).
  322. friend DisjointIntervals operator^(DisjointIntervals const& input0, DisjointIntervals const& input1)
  323. {
  324. DisjointIntervals output;
  325. size_t const numEndpoints0 = input0.mEndpoints.size();
  326. size_t const numEndpoints1 = input1.mEndpoints.size();
  327. size_t i0 = 0, i1 = 0;
  328. while (i0 < numEndpoints0 && i1 < numEndpoints1)
  329. {
  330. Scalar const& value0 = input0.mEndpoints[i0];
  331. Scalar const& value1 = input1.mEndpoints[i1];
  332. if (value0 < value1)
  333. {
  334. output.mEndpoints.push_back(value0);
  335. ++i0;
  336. }
  337. else if (value1 < value0)
  338. {
  339. output.mEndpoints.push_back(value1);
  340. ++i1;
  341. }
  342. else // value0 == value1
  343. {
  344. ++i0;
  345. ++i1;
  346. }
  347. }
  348. while (i0 < numEndpoints0)
  349. {
  350. output.mEndpoints.push_back(input0.mEndpoints[i0]);
  351. ++i0;
  352. }
  353. while (i1 < numEndpoints1)
  354. {
  355. output.mEndpoints.push_back(input1.mEndpoints[i1]);
  356. ++i1;
  357. }
  358. return output;
  359. }
  360. private:
  361. // The array of endpoints has an even number of elements. The i-th
  362. // interval is [mEndPoints[2*i],mEndPoints[2*i+1]).
  363. std::vector<Scalar> mEndpoints;
  364. };
  365. }