1 // Boost.Geometry
2 
3 // Copyright (c) 2016-2019 Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7 
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 
12 #include <boost/geometry/geometries/box.hpp>
13 #include <boost/geometry/geometries/point_xy.hpp>
14 #include <boost/geometry/geometries/geometries.hpp>
15 #include <boost/geometry/geometries/adapted/c_array.hpp>
16 #include <boost/geometry/geometries/adapted/boost_tuple.hpp>
17 #include <test_common/test_point.hpp>
18 
19 #include <boost/geometry/formulas/andoyer_inverse.hpp>
20 #include <boost/geometry/formulas/thomas_inverse.hpp>
21 #include <boost/geometry/formulas/vincenty_inverse.hpp>
22 
23 #include <boost/geometry/strategies/strategies.hpp>
24 
25 #include <boost/geometry/algorithms/disjoint.hpp>
26 
27 #include <geometry_test_common.hpp>
28 
29 #include "test_disjoint_seg_box.hpp"
30 
31 
32 namespace bg = boost::geometry;
33 
34 //Tests for disjoint(point, box), disjoint(box, box) and disjoint(segment, box)
35 
36 template <typename P>
disjoint_tests_1()37 void disjoint_tests_1()
38 {
39     test_disjoint<bg::model::box<P>, P>("BOX(1 1,3 3)", "POINT(4 4)", true);
40     test_disjoint<bg::model::box<P>, P>("BOX(1 1,3 3)", "POINT(2 2)", false);
41     test_disjoint<bg::model::box<P>, P>("BOX(1 1,3 3)", "POINT(3 3)", false);
42     test_disjoint<bg::model::box<P>, P>("BOX(1 1,3 3)", "POINT(2 3)", false);
43 
44     test_disjoint<bg::model::box<P>, bg::model::box<P> >("BOX(1 1,3 3)",
45                                                          "BOX(1 4,5 5)",
46                                                          true);
47     test_disjoint<bg::model::box<P>, bg::model::box<P> >("BOX(1 1,3 3)",
48                                                          "BOX(2 2,4 4)",
49                                                          false);
50     test_disjoint<bg::model::box<P>, bg::model::box<P> >("BOX(1 1,3 3)",
51                                                          "BOX(3 3,4 4)",
52                                                          false);
53     test_disjoint<bg::model::box<P>, bg::model::box<P> >("BOX(1 1,3 3)",
54                                                          "BOX(2 3,4 4)",
55                                                          false);
56 
57     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
58                                                              "SEGMENT(1 4, 5 5)",
59                                                              true);
60     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
61                                                              "SEGMENT(3 3, 5 5)",
62                                                              false);
63     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
64                                                              "SEGMENT(1 1, 4 1)",
65                                                              false);
66     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
67                                                              "SEGMENT(1 2, 5 5)",
68                                                              false);
69     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
70                                                              "SEGMENT(1 2, 3 2)",
71                                                              false);
72     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
73                                                              "SEGMENT(0 0, 4 0)",
74                                                              true);
75     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
76                                                              "SEGMENT(2 2, 4 4)",
77                                                              false);
78     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
79                                                              "SEGMENT(4 4, 2 2)",
80                                                              false);
81     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
82                                                              "SEGMENT(1.5 1.5, 2 2)",
83                                                              false);
84 }
85 
86 template <typename P>
disjoint_tests_2(bool expected_result)87 void disjoint_tests_2(bool expected_result)
88 {
89     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
90                                                              "SEGMENT(1 0.999, 10 0.999)",
91                                                              expected_result);
92     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
93                                                              "SEGMENT(10 0.999, 1 0.999)",
94                                                              expected_result);
95 }
96 
97 template <typename P>
disjoint_tests_3(bool expected_result)98 void disjoint_tests_3(bool expected_result)
99 {
100     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(3 4.42, 100 5)",
101                                                              "SEGMENT(2 2.9, 100 2.9)",
102                                                              expected_result);
103     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(3 4.42, 100 5)",
104                                                              "SEGMENT(100 2.9, 2 2.9)",
105                                                              expected_result);
106 }
107 
108 template <typename P>
disjoint_tests_4(bool expected_result)109 void disjoint_tests_4(bool expected_result)
110 {
111     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
112                                                              "SEGMENT(0 0.99999999, 2 0.99999999)",
113                                                              expected_result);
114     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(1 1,3 3)",
115                                                              "SEGMENT(2 0.99999999, 0 0.99999999)",
116                                                              expected_result);
117 }
118 
119 template <typename P, typename CT>
disjoint_tests_with_strategy(bool expected_result)120 void disjoint_tests_with_strategy(bool expected_result)
121 {
122     bg::strategy::disjoint::segment_box_geographic
123     <
124         bg::strategy::andoyer,
125         bg::srs::spheroid<CT>,
126         CT
127     > geographic_andoyer;
128 
129     bg::strategy::disjoint::segment_box_geographic
130     <
131         bg::strategy::thomas,
132         bg::srs::spheroid<CT>,
133         CT
134     > geographic_thomas;
135 
136     bg::strategy::disjoint::segment_box_geographic
137     <
138         bg::strategy::vincenty,
139         bg::srs::spheroid<CT>,
140         CT
141     > geographic_vincenty;
142 
143     test_disjoint_strategy<bg::model::box<P>, bg::model::segment<P> >
144             ("BOX(1 1,3 3)", "SEGMENT(1 0.999, 10 0.999)",
145              expected_result, geographic_andoyer);
146     test_disjoint_strategy<bg::model::box<P>, bg::model::segment<P> >
147             ("BOX(1 1,3 3)", "SEGMENT(1 0.999, 10 0.999)",
148              expected_result, geographic_thomas);
149     test_disjoint_strategy<bg::model::box<P>, bg::model::segment<P> >
150             ("BOX(1 1,3 3)", "SEGMENT(1 0.999, 10 0.999)",
151              expected_result, geographic_vincenty);
152 }
153 
154 template <typename P>
disjoint_tests_sph_geo()155 void disjoint_tests_sph_geo()
156 {
157     //Case A: box intersects without containing the vertex
158     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 6, 120 7)",
159                                                              "SEGMENT(0 5, 120 5)",
160                                                              false);
161     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 -6, 120 -7)",
162                                                              "SEGMENT(0 -5, 120 -5)",
163                                                              false);
164 
165     //Case B: box intersects and contains the vertex
166     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 9, 120 10)",
167                                                              "SEGMENT(0 5, 120 5)",
168                                                              false);
169     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 -10, 120 -9)",
170                                                              "SEGMENT(0 -5, 120 -5)",
171                                                              false);
172 
173     //Case C: bounding boxes disjoint
174     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 10, 10 20)",
175                                                              "SEGMENT(0 5, 120 5)",
176                                                              true);
177     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 -20, 10 -10)",
178                                                              "SEGMENT(0 -5, 120 -5)",
179                                                              true);
180 
181     //Case D: bounding boxes intersect but box segment are disjoint
182     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 9, 0.1 20)",
183                                                              "SEGMENT(0 5, 120 5)",
184                                                              true);
185     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 -20, 0.1 -9)",
186                                                              "SEGMENT(0 -5, 120 -5)",
187                                                              true);
188 
189     //Case E: geodesic intersects box but box segment are disjoint
190     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(121 0, 122 10)",
191                                                              "SEGMENT(0 5, 120 5)",
192                                                              true);
193     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(121 -10, 122 0)",
194                                                              "SEGMENT(0 -5, 120 -5)",
195                                                              true);
196 
197     //Case F: segment crosses box
198     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(100 0, 110 20)",
199                                                              "SEGMENT(0 5, 120 5)",
200                                                              false);
201     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(100 -20, 110 0)",
202                                                              "SEGMENT(0 -5, 120 -5)",
203                                                              false);
204 
205     //Case G: box contains one segment endpoint
206     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(110 0, 130 10)",
207                                                              "SEGMENT(0 5, 120 5)",
208                                                              false);
209     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(110 -10, 130 0)",
210                                                              "SEGMENT(0 -5, 120 -5)",
211                                                              false);
212 
213     //Case H: box below segment
214     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(50 0, 70 6)",
215                                                              "SEGMENT(0 5, 120 5)",
216                                                              true);
217     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(50 -6, 70 0)",
218                                                              "SEGMENT(0 -5, 120 -5)",
219                                                              true);
220 
221     //Case I: box contains segment
222     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(-10 0, 130 10)",
223                                                              "SEGMENT(0 5, 120 5)",
224                                                              false);
225     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(-10 -10, 130 0)",
226                                                              "SEGMENT(0 -5, 120 -5)",
227                                                              false);
228 
229     //ascending segment
230     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 10, 120 10.1)",
231                                                              "SEGMENT(0 5, 120 5.1)",
232                                                              false);
233 
234     //descending segment
235     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 9.8, 120 10)",
236                                                              "SEGMENT(0 5, 120 4.9)",
237                                                              false);
238 
239     //ascending segment both hemispheres
240     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(100 5, 120 6)",
241                                                              "SEGMENT(0 -1, 120 4.9)",
242                                                              false);
243 
244     //descending segment both hemispheres
245     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(0 5, 20 6)",
246                                                              "SEGMENT(0 4.9, 120 -1)",
247                                                              false);
248 
249     //https://github.com/boostorg/geometry/issues/579
250     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(10 10,20 20)",
251                                                              "SEGMENT(12 2,12 1)",
252                                                              true);
253     test_disjoint<bg::model::box<P>, bg::model::segment<P> >("BOX(10 10,20 20)",
254                                                              "SEGMENT(12 1,12 2)",
255                                                              true);
256 }
257 
258 template <typename CT>
test_all()259 void test_all()
260 {
261     typedef bg::model::d2::point_xy<CT> point;
262     typedef bg::model::point<CT, 2,
263             bg::cs::spherical_equatorial<bg::degree> > sph_point;
264     typedef bg::model::point<CT, 2,
265             bg::cs::geographic<bg::degree> > geo_point;
266 
267     disjoint_tests_1<point>();
268     disjoint_tests_1<sph_point>();
269     disjoint_tests_1<geo_point>();
270 
271     disjoint_tests_2<point>(true);
272     disjoint_tests_2<sph_point>(false);
273     disjoint_tests_2<geo_point>(false);
274 
275     //illustrate difference between spherical and geographic computation on same data
276     disjoint_tests_3<point>(true);
277     disjoint_tests_3<sph_point>(true);
278     disjoint_tests_3<geo_point>(false);
279 
280     disjoint_tests_4<sph_point>(false);
281     disjoint_tests_4<geo_point>(false);
282 
283     disjoint_tests_with_strategy<geo_point, CT>(false);
284 
285     disjoint_tests_sph_geo<sph_point>();
286     disjoint_tests_sph_geo<geo_point>();
287 }
288 
289 
test_main(int,char * [])290 int test_main( int , char* [] )
291 {
292     test_all<float>();
293     test_all<double>();
294 
295     return 0;
296 }
297