polygon_segment_test.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. // Boost.Polygon library polygon_segment_test.cpp file
  2. // Copyright Andrii Sydorchuk 2012.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org for updates, documentation, and revision history.
  7. #include <boost/core/lightweight_test.hpp>
  8. #include <boost/polygon/segment_concept.hpp>
  9. #include <boost/polygon/segment_data.hpp>
  10. #include <boost/polygon/segment_traits.hpp>
  11. using namespace boost::polygon;
  12. void segment_data_test()
  13. {
  14. typedef point_data<int> point_type;
  15. typedef segment_data<int> segment_type;
  16. point_type point1(1, 2);
  17. point_type point2(3, 4);
  18. segment_type segment1(point1, point2);
  19. segment_type segment2;
  20. segment2 = segment1;
  21. BOOST_TEST(segment1.low() == point1);
  22. BOOST_TEST(segment1.high() == point2);
  23. BOOST_TEST(segment1.get(LOW) == point1);
  24. BOOST_TEST(segment1.get(HIGH) == point2);
  25. BOOST_TEST(segment1 == segment2);
  26. BOOST_TEST(!(segment1 != segment2));
  27. BOOST_TEST(!(segment1 < segment2));
  28. BOOST_TEST(!(segment1 > segment1));
  29. BOOST_TEST(segment1 <= segment2);
  30. BOOST_TEST(segment1 >= segment2);
  31. segment1.low(point2);
  32. segment1.high(point1);
  33. BOOST_TEST(segment1.low() == point2);
  34. BOOST_TEST(segment1.high() == point1);
  35. BOOST_TEST(!(segment1 == segment2));
  36. BOOST_TEST(segment1 != segment2);
  37. segment2.set(LOW, point2);
  38. segment2.set(HIGH, point1);
  39. BOOST_TEST(segment1 == segment2);
  40. }
  41. void segment_traits_test()
  42. {
  43. typedef point_data<int> point_type;
  44. typedef segment_data<int> segment_type;
  45. point_type point1(1, 2);
  46. point_type point2(3, 4);
  47. segment_type segment =
  48. segment_mutable_traits<segment_type>::construct(point1, point2);
  49. BOOST_TEST(segment_traits<segment_type>::get(segment, LOW) == point1);
  50. BOOST_TEST(segment_traits<segment_type>::get(segment, HIGH) == point2);
  51. segment_mutable_traits<segment_type>::set(segment, LOW, point2);
  52. segment_mutable_traits<segment_type>::set(segment, HIGH, point1);
  53. BOOST_TEST(segment_traits<segment_type>::get(segment, LOW) == point2);
  54. BOOST_TEST(segment_traits<segment_type>::get(segment, HIGH) == point1);
  55. }
  56. template <typename T>
  57. struct Segment {
  58. typedef T coordinate_type;
  59. typedef point_data<int> point_type;
  60. point_type p0;
  61. point_type p1;
  62. };
  63. namespace boost {
  64. namespace polygon {
  65. template <typename T>
  66. struct geometry_concept< Segment<T> > {
  67. typedef segment_concept type;
  68. };
  69. template <typename T>
  70. struct segment_traits< Segment<T> > {
  71. typedef T coordinate_type;
  72. typedef point_data<int> point_type;
  73. static point_type get(const Segment<T>& segment, direction_1d dir) {
  74. return dir.to_int() ? segment.p1 : segment.p0;
  75. }
  76. };
  77. template <typename T>
  78. struct segment_mutable_traits< Segment<T> > {
  79. typedef T coordinate_type;
  80. typedef point_data<int> point_type;
  81. static void set(
  82. Segment<T>& segment, direction_1d dir, const point_type& point) {
  83. dir.to_int() ? segment.p1 = point : segment.p0 = point;;
  84. }
  85. static Segment<T> construct(
  86. const point_type& point1, const point_type& point2) {
  87. Segment<T> segment;
  88. segment.p0 = point1;
  89. segment.p1 = point2;
  90. return segment;
  91. }
  92. };
  93. }
  94. }
  95. void segment_concept_test1()
  96. {
  97. typedef point_data<int> point_type;
  98. typedef Segment<int> segment_type;
  99. point_type point1(1, 2);
  100. point_type point2(3, 4);
  101. point_type point3(2, 3);
  102. segment_type segment1 = construct<segment_type>(point1, point2);
  103. BOOST_TEST(segment1.p0 == point1);
  104. BOOST_TEST(segment1.p1 == point2);
  105. BOOST_TEST(get(segment1, LOW) == point1);
  106. BOOST_TEST(low(segment1) == point1);
  107. BOOST_TEST(get(segment1, HIGH) == point2);
  108. BOOST_TEST(high(segment1) == point2);
  109. BOOST_TEST(center(segment1) == point3);
  110. set(segment1, LOW, point2);
  111. set(segment1, HIGH, point1);
  112. BOOST_TEST(segment1.p0 == point2);
  113. BOOST_TEST(segment1.p1 == point1);
  114. BOOST_TEST(get(segment1, LOW) == point2);
  115. BOOST_TEST(get(segment1, HIGH) == point1);
  116. low(segment1, point1);
  117. high(segment1, point2);
  118. BOOST_TEST(segment1.p0 == point1);
  119. BOOST_TEST(segment1.p1 == point2);
  120. segment_data<int> segment2 = copy_construct< segment_data<int> >(segment1);
  121. BOOST_TEST(segment1.p0 == segment2.low());
  122. BOOST_TEST(segment1.p1 == segment2.high());
  123. BOOST_TEST(equivalence(segment1, segment2));
  124. segment_data<int> segment3 = construct< segment_data<int> >(point2, point1);
  125. assign(segment1, segment3);
  126. BOOST_TEST(segment1.p0 == point2);
  127. BOOST_TEST(segment1.p1 == point1);
  128. BOOST_TEST(!equivalence(segment1, segment2));
  129. }
  130. void segment_concept_test2()
  131. {
  132. typedef point_data<int> point_type;
  133. typedef Segment<int> segment_type;
  134. point_type point1(1, 2);
  135. point_type point2(2, 4);
  136. point_type point3(0, 0);
  137. point_type point4(5, 10);
  138. point_type point5(1, 3);
  139. point_type point6(2, 3);
  140. point_type point7(100, 201);
  141. point_type point8(100, 200);
  142. point_type point9(100, 199);
  143. segment_type segment1 = construct<segment_type>(point1, point2);
  144. segment_type segment2 = construct<segment_type>(point2, point1);
  145. segment_type segment3 = construct<segment_type>(point1, point5);
  146. BOOST_TEST(orientation(segment1, point1) == 0);
  147. BOOST_TEST(orientation(segment1, point2) == 0);
  148. BOOST_TEST(orientation(segment1, point3) == 0);
  149. BOOST_TEST(orientation(segment1, point4) == 0);
  150. BOOST_TEST(orientation(segment1, point5) == 1);
  151. BOOST_TEST(orientation(segment2, point5) == -1);
  152. BOOST_TEST(orientation(segment1, point6) == -1);
  153. BOOST_TEST(orientation(segment2, point6) == 1);
  154. BOOST_TEST(orientation(segment1, point7) == 1);
  155. BOOST_TEST(orientation(segment2, point7) == -1);
  156. BOOST_TEST(orientation(segment1, point8) == 0);
  157. BOOST_TEST(orientation(segment1, point9) == -1);
  158. BOOST_TEST(orientation(segment2, point9) == 1);
  159. BOOST_TEST(orientation(segment3, point6) == -1);
  160. BOOST_TEST(orientation(segment3, point3) == 1);
  161. }
  162. void segment_concept_test3()
  163. {
  164. typedef point_data<int> point_type;
  165. typedef Segment<int> segment_type;
  166. segment_type segment1 = construct<segment_type>(
  167. point_type(0, 0), point_type(1, 2));
  168. segment_type segment2 = construct<segment_type>(
  169. point_type(0, 0), point_type(2, 4));
  170. segment_type segment3 = construct<segment_type>(
  171. point_type(0, 0), point_type(2, 3));
  172. segment_type segment4 = construct<segment_type>(
  173. point_type(0, 0), point_type(2, 5));
  174. segment_type segment5 = construct<segment_type>(
  175. point_type(0, 2), point_type(2, 0));
  176. BOOST_TEST(orientation(segment1, segment2) == 0);
  177. BOOST_TEST(orientation(segment1, segment3) == -1);
  178. BOOST_TEST(orientation(segment3, segment1) == 1);
  179. BOOST_TEST(orientation(segment1, segment4) == 1);
  180. BOOST_TEST(orientation(segment4, segment1) == -1);
  181. BOOST_TEST(orientation(segment1, segment5) == -1);
  182. BOOST_TEST(orientation(segment5, segment1) == 1);
  183. }
  184. void segment_concept_test4()
  185. {
  186. typedef point_data<int> point_type;
  187. typedef Segment<int> segment_type;
  188. point_type point1(1, 2);
  189. point_type point2(3, 6);
  190. point_type point3(2, 4);
  191. point_type point4(4, 8);
  192. point_type point5(0, 0);
  193. segment_type segment = construct<segment_type>(point1, point2);
  194. BOOST_TEST(contains(segment, point1, true));
  195. BOOST_TEST(contains(segment, point2, true));
  196. BOOST_TEST(!contains(segment, point1, false));
  197. BOOST_TEST(!contains(segment, point2, false));
  198. BOOST_TEST(contains(segment, point3, false));
  199. BOOST_TEST(!contains(segment, point4, true));
  200. BOOST_TEST(!contains(segment, point5, true));
  201. }
  202. void segment_concept_test5()
  203. {
  204. typedef point_data<int> point_type;
  205. typedef Segment<int> segment_type;
  206. point_type point1(0, 0);
  207. point_type point2(10, 0);
  208. point_type point3(5, 0);
  209. point_type point4(-1, 0);
  210. point_type point5(11, 0);
  211. segment_type segment = construct<segment_type>(point1, point2);
  212. BOOST_TEST(contains(segment, point1, true));
  213. BOOST_TEST(contains(segment, point2, true));
  214. BOOST_TEST(!contains(segment, point1, false));
  215. BOOST_TEST(!contains(segment, point2, false));
  216. BOOST_TEST(contains(segment, point3, false));
  217. BOOST_TEST(!contains(segment, point4, true));
  218. BOOST_TEST(!contains(segment, point5, true));
  219. }
  220. void segment_concept_test6()
  221. {
  222. typedef point_data<int> point_type;
  223. typedef Segment<int> segment_type;
  224. point_type point1(0, 0);
  225. point_type point2(1, 2);
  226. point_type point3(2, 4);
  227. point_type point4(3, 6);
  228. point_type point5(4, 8);
  229. point_type point6(5, 10);
  230. segment_type segment1 = construct<segment_type>(point2, point5);
  231. segment_type segment2 = construct<segment_type>(point3, point4);
  232. segment_type segment3 = construct<segment_type>(point1, point3);
  233. segment_type segment4 = construct<segment_type>(point4, point6);
  234. BOOST_TEST(contains(segment1, segment2, false));
  235. BOOST_TEST(!contains(segment2, segment1, true));
  236. BOOST_TEST(!contains(segment1, segment3, true));
  237. BOOST_TEST(!contains(segment1, segment4, true));
  238. BOOST_TEST(contains(segment1, segment1, true));
  239. BOOST_TEST(!contains(segment1, segment1, false));
  240. }
  241. template<typename T>
  242. struct Transformer {
  243. void scale(T& x, T& y) const {
  244. x *= 2;
  245. y *= 2;
  246. }
  247. void transform(T& x, T& y) const {
  248. T tmp = x;
  249. x = y;
  250. y = tmp;
  251. }
  252. };
  253. void segment_concept_test7()
  254. {
  255. typedef point_data<int> point_type;
  256. typedef Segment<int> segment_type;
  257. point_type point1(1, 2);
  258. point_type point2(4, 6);
  259. segment_type segment1 = construct<segment_type>(point1, point2);
  260. scale_up(segment1, 3);
  261. BOOST_TEST(low(segment1) == point_type(3, 6));
  262. BOOST_TEST(high(segment1) == point_type(12, 18));
  263. scale_down(segment1, 3);
  264. BOOST_TEST(low(segment1) == point1);
  265. BOOST_TEST(high(segment1) == point2);
  266. BOOST_TEST(length(segment1) == 5);
  267. move(segment1, HORIZONTAL, 1);
  268. move(segment1, VERTICAL, 2);
  269. BOOST_TEST(low(segment1) == point_type(2, 4));
  270. BOOST_TEST(high(segment1) == point_type(5, 8));
  271. BOOST_TEST(length(segment1) == 5);
  272. convolve(segment1, point_type(1, 2));
  273. BOOST_TEST(low(segment1) == point_type(3, 6));
  274. BOOST_TEST(high(segment1) == point_type(6, 10));
  275. deconvolve(segment1, point_type(2, 4));
  276. BOOST_TEST(low(segment1) == point1);
  277. BOOST_TEST(high(segment1) == point2);
  278. scale(segment1, Transformer<int>());
  279. BOOST_TEST(low(segment1) == point_type(2, 4));
  280. BOOST_TEST(high(segment1) == point_type(8, 12));
  281. transform(segment1, Transformer<int>());
  282. BOOST_TEST(low(segment1) == point_type(4, 2));
  283. BOOST_TEST(high(segment1) == point_type(12, 8));
  284. }
  285. void segment_concept_test8()
  286. {
  287. typedef point_data<int> point_type;
  288. typedef Segment<int> segment_type;
  289. segment_type segment1 = construct<segment_type>(
  290. point_type(0, 0), point_type(1, 2));
  291. segment_type segment2 = construct<segment_type>(
  292. point_type(1, 2), point_type(2, 4));
  293. segment_type segment3 = construct<segment_type>(
  294. point_type(2, 4), point_type(0, 4));
  295. segment_type segment4 = construct<segment_type>(
  296. point_type(0, 4), point_type(0, 0));
  297. BOOST_TEST(abuts(segment1, segment2, HIGH));
  298. BOOST_TEST(abuts(segment2, segment3, HIGH));
  299. BOOST_TEST(abuts(segment3, segment4, HIGH));
  300. BOOST_TEST(abuts(segment4, segment1, HIGH));
  301. BOOST_TEST(!abuts(segment1, segment2, LOW));
  302. BOOST_TEST(!abuts(segment2, segment3, LOW));
  303. BOOST_TEST(!abuts(segment3, segment4, LOW));
  304. BOOST_TEST(!abuts(segment4, segment1, LOW));
  305. BOOST_TEST(abuts(segment2, segment1));
  306. BOOST_TEST(abuts(segment3, segment2));
  307. BOOST_TEST(abuts(segment4, segment3));
  308. BOOST_TEST(abuts(segment1, segment4));
  309. BOOST_TEST(!abuts(segment1, segment3));
  310. BOOST_TEST(!abuts(segment2, segment4));
  311. }
  312. void segment_concept_test9()
  313. {
  314. typedef point_data<int> point_type;
  315. typedef Segment<int> segment_type;
  316. segment_type segment1 = construct<segment_type>(
  317. point_type(0, 0), point_type(2, 2));
  318. segment_type segment2 = construct<segment_type>(
  319. point_type(1, 1), point_type(3, 3));
  320. segment_type segment3 = construct<segment_type>(
  321. point_type(2, 2), point_type(-1, -1));
  322. segment_type segment4 = construct<segment_type>(
  323. point_type(1, 3), point_type(3, 1));
  324. segment_type segment5 = construct<segment_type>(
  325. point_type(2, 2), point_type(1, 3));
  326. BOOST_TEST(intersects(segment1, segment2, false));
  327. BOOST_TEST(intersects(segment1, segment2, true));
  328. BOOST_TEST(intersects(segment1, segment3, false));
  329. BOOST_TEST(intersects(segment1, segment3, true));
  330. BOOST_TEST(intersects(segment2, segment3, false));
  331. BOOST_TEST(intersects(segment2, segment3, true));
  332. BOOST_TEST(intersects(segment4, segment3, false));
  333. BOOST_TEST(intersects(segment4, segment3, true));
  334. BOOST_TEST(intersects(segment4, segment2, false));
  335. BOOST_TEST(intersects(segment4, segment2, true));
  336. BOOST_TEST(!intersects(segment3, segment5, false));
  337. BOOST_TEST(intersects(segment3, segment5, true));
  338. }
  339. void segment_concept_test10()
  340. {
  341. typedef point_data<int> point_type;
  342. typedef Segment<int> segment_type;
  343. segment_type segment1 = construct<segment_type>(
  344. point_type(0, 0), point_type(0, 2));
  345. segment_type segment2 = construct<segment_type>(
  346. point_type(0, 1), point_type(0, 3));
  347. segment_type segment3 = construct<segment_type>(
  348. point_type(0, 1), point_type(0, 2));
  349. segment_type segment4 = construct<segment_type>(
  350. point_type(0, 2), point_type(0, 3));
  351. segment_type segment5 = construct<segment_type>(
  352. point_type(0, 2), point_type(2, 2));
  353. segment_type segment6 = construct<segment_type>(
  354. point_type(0, 1), point_type(1, 1));
  355. BOOST_TEST(intersects(segment1, segment1, false));
  356. BOOST_TEST(intersects(segment1, segment1, true));
  357. BOOST_TEST(intersects(segment1, segment2, false));
  358. BOOST_TEST(intersects(segment1, segment2, true));
  359. BOOST_TEST(intersects(segment1, segment3, false));
  360. BOOST_TEST(intersects(segment1, segment3, true));
  361. BOOST_TEST(intersects(segment2, segment3, false));
  362. BOOST_TEST(intersects(segment2, segment3, true));
  363. BOOST_TEST(!intersects(segment1, segment4, false));
  364. BOOST_TEST(intersects(segment1, segment4, true));
  365. BOOST_TEST(!intersects(segment1, segment5, false));
  366. BOOST_TEST(intersects(segment1, segment5, true));
  367. BOOST_TEST(intersects(segment1, segment6, false));
  368. BOOST_TEST(intersects(segment1, segment6, true));
  369. }
  370. void segment_concept_test11()
  371. {
  372. typedef point_data<int> point_type;
  373. typedef Segment<int> segment_type;
  374. point_type point1(1, 2);
  375. point_type point2(7, 10);
  376. segment_type segment1 = construct<segment_type>(point1, point2);
  377. BOOST_TEST(euclidean_distance(segment1, point1) == 0.0);
  378. BOOST_TEST(euclidean_distance(segment1, point2) == 0.0);
  379. BOOST_TEST(euclidean_distance(segment1, point_type(10, 14)) == 5.0);
  380. BOOST_TEST(euclidean_distance(segment1, point_type(-3, -1)) == 5.0);
  381. BOOST_TEST(euclidean_distance(segment1, point_type(0, 9)) == 5.0);
  382. BOOST_TEST(euclidean_distance(segment1, point_type(8, 3)) == 5.0);
  383. }
  384. void segment_concept_test12()
  385. {
  386. typedef point_data<int> point_type;
  387. typedef Segment<int> segment_type;
  388. segment_type segment1 = construct<segment_type>(
  389. point_type(0, 0), point_type(3, 4));
  390. segment_type segment2 = construct<segment_type>(
  391. point_type(2, 0), point_type(0, 2));
  392. segment_type segment3 = construct<segment_type>(
  393. point_type(1, -7), point_type(10, 5));
  394. segment_type segment4 = construct<segment_type>(
  395. point_type(7, 7), point_type(10, 11));
  396. BOOST_TEST(euclidean_distance(segment1, segment2) == 0.0);
  397. BOOST_TEST(euclidean_distance(segment1, segment3) == 5.0);
  398. BOOST_TEST(euclidean_distance(segment1, segment4) == 5.0);
  399. }
  400. int main()
  401. {
  402. segment_data_test();
  403. segment_traits_test();
  404. segment_concept_test1();
  405. segment_concept_test2();
  406. segment_concept_test3();
  407. segment_concept_test4();
  408. segment_concept_test5();
  409. segment_concept_test6();
  410. segment_concept_test7();
  411. segment_concept_test8();
  412. segment_concept_test9();
  413. segment_concept_test10();
  414. segment_concept_test11();
  415. segment_concept_test12();
  416. return boost::report_errors();
  417. }