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 #ifdef HAVE_TTMATH
296 common_tests<bg::model::d2::point_xy<ttmath_big> >();
297 common_tests<bg::model::point<ttmath_big, 3, bg::cs::cartesian> >();
298 #endif
299
300 return 0;
301 }
302