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