]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/test/strategies/pythagoras_point_box.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / geometry / test / strategies / pythagoras_point_box.cpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2// Unit Test
3
4// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
5// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
6// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
7
20effc67
TL
8// This file was modified by Oracle on 2014-2020.
9// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
7c673cae
FG
10
11// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
20effc67 12// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7c673cae
FG
13
14// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16
17// Use, modification and distribution is subject to the Boost Software License,
18// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
19// http://www.boost.org/LICENSE_1_0.txt)
20
21#ifndef BOOST_TEST_MODULE
22#define BOOST_TEST_MODULE test_pythagoras_point_box
23#endif
24
25#include <boost/test/included/unit_test.hpp>
26
27#if defined(_MSC_VER)
28# pragma warning( disable : 4101 )
29#endif
30
31#include <boost/core/ignore_unused.hpp>
32#include <boost/timer.hpp>
33
34#include <boost/concept/requires.hpp>
35#include <boost/concept_check.hpp>
36
37#include <boost/geometry/algorithms/assign.hpp>
38#include <boost/geometry/algorithms/expand.hpp>
39#include <boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp>
40#include <boost/geometry/strategies/concepts/distance_concept.hpp>
41
42
43#include <boost/geometry/geometries/point.hpp>
44#include <boost/geometry/geometries/box.hpp>
45#include <boost/geometry/geometries/adapted/c_array.hpp>
46#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
47
48#include <test_common/test_point.hpp>
49
20effc67
TL
50// TEST
51#include <boost/geometry/strategies/cartesian.hpp>
52#include <boost/geometry/strategies/geographic.hpp>
53#include <boost/geometry/strategies/spherical.hpp>
7c673cae
FG
54
55
56namespace bg = boost::geometry;
57
58
59BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
60BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
61
62
63template <typename Box, typename Coordinate>
64inline void assign_values(Box& box,
65 Coordinate const& x1,
66 Coordinate const& y1,
67 Coordinate const& z1,
68 Coordinate const& x2,
69 Coordinate const& y2,
70 Coordinate const& z2)
71{
72 typename bg::point_type<Box>::type p1, p2;
73 bg::assign_values(p1, x1, y1, z1);
74 bg::assign_values(p2, x2, y2, z2);
75 bg::assign(box, p1);
76 bg::expand(box, p2);
77}
78
79template <typename Point, typename Box>
80inline void test_null_distance_3d()
81{
82 Point p;
83 bg::assign_values(p, 1, 2, 4);
84 Box b;
85 assign_values(b, 1, 2, 3, 4, 5, 6);
86
87 typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_pb_type;
88 typedef typename bg::strategy::distance::services::return_type
89 <
90 pythagoras_pb_type, Point, Box
91 >::type return_type;
92
93 pythagoras_pb_type pythagoras_pb;
94 return_type result = pythagoras_pb.apply(p, b);
95
96 BOOST_CHECK_EQUAL(result, return_type(0));
97
98 bg::assign_values(p, 1, 3, 4);
99 result = pythagoras_pb.apply(p, b);
100 BOOST_CHECK_EQUAL(result, return_type(0));
101
102 bg::assign_values(p, 2, 3, 4);
103 result = pythagoras_pb.apply(p, b);
104 BOOST_CHECK_EQUAL(result, return_type(0));
105}
106
107template <typename Point, typename Box>
108inline void test_axis_3d()
109{
110 Box b;
111 assign_values(b, 0, 0, 0, 1, 1, 1);
112 Point p;
113 bg::assign_values(p, 2, 0, 0);
114
115 typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_pb_type;
116 typedef typename bg::strategy::distance::services::return_type
117 <
118 pythagoras_pb_type, Point, Box
119 >::type return_type;
120
121 pythagoras_pb_type pythagoras_pb;
122
123 return_type result = pythagoras_pb.apply(p, b);
124 BOOST_CHECK_EQUAL(result, return_type(1));
125
126 bg::assign_values(p, 0, 2, 0);
127 result = pythagoras_pb.apply(p, b);
128 BOOST_CHECK_EQUAL(result, return_type(1));
129
130 bg::assign_values(p, 0, 0, 2);
131 result = pythagoras_pb.apply(p, b);
132 BOOST_CHECK_CLOSE(result, return_type(1), 0.001);
133}
134
135template <typename Point, typename Box>
136inline void test_arbitrary_3d()
137{
138 Box b;
139 assign_values(b, 0, 0, 0, 1, 2, 3);
140 Point p;
141 bg::assign_values(p, 9, 8, 7);
142
143 {
144 typedef bg::strategy::distance::pythagoras_point_box<> strategy_type;
145 typedef typename bg::strategy::distance::services::return_type
146 <
147 strategy_type, Point, Box
148 >::type return_type;
149
150 strategy_type strategy;
151 return_type result = strategy.apply(p, b);
152 BOOST_CHECK_CLOSE(result, return_type(10.77032961427), 0.001);
153 }
154
155 {
156 // Check comparable distance
157 typedef bg::strategy::distance::comparable::pythagoras_point_box<>
158 strategy_type;
159
160 typedef typename bg::strategy::distance::services::return_type
161 <
162 strategy_type, Point, Box
163 >::type return_type;
164
165 strategy_type strategy;
166 return_type result = strategy.apply(p, b);
167 BOOST_CHECK_EQUAL(result, return_type(116));
168 }
169}
170
171template <typename Point, typename Box, typename CalculationType>
172inline void test_services()
173{
174 namespace bgsd = bg::strategy::distance;
175 namespace services = bg::strategy::distance::services;
176
177 {
178 // Compile-check if there is a strategy for this type
179 typedef typename services::default_strategy
180 <
181 bg::point_tag, bg::box_tag, Point, Box
182 >::type pythagoras_pb_strategy_type;
183
184 // reverse geometry tags
185 typedef typename services::default_strategy
186 <
187 bg::box_tag, bg::point_tag, Box, Point
188 >::type reversed_pythagoras_pb_strategy_type;
189
190 boost::ignore_unused
191 <
192 pythagoras_pb_strategy_type,
193 reversed_pythagoras_pb_strategy_type
194 >();
195 }
196
197 Point p;
198 bg::assign_values(p, 1, 2, 3);
199
200 Box b;
201 assign_values(b, 4, 5, 6, 14, 15, 16);
202
203 double const sqr_expected = 3*3 + 3*3 + 3*3; // 27
204 double const expected = sqrt(sqr_expected); // sqrt(27)=5.1961524227
205
206 // 1: normal, calculate distance:
207
208 typedef bgsd::pythagoras_point_box<CalculationType> strategy_type;
209
210 BOOST_CONCEPT_ASSERT
211 ( (bg::concepts::PointDistanceStrategy<strategy_type, Point, Box>) );
212
213 typedef typename bgsd::services::return_type
214 <
215 strategy_type, Point, Box
216 >::type return_type;
217
218 strategy_type strategy;
219 return_type result = strategy.apply(p, b);
220 BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
221
222 // 2: the strategy should return the same result if we reverse parameters
223 // result = strategy.apply(p2, p1);
224 // BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
225
226
227 // 3: "comparable" to construct a "comparable strategy" for Point/Box
228 // a "comparable strategy" is a strategy which does not calculate the exact distance, but
229 // which returns results which can be mutually compared (e.g. avoid sqrt)
230
231 // 3a: "comparable_type"
232 typedef typename services::comparable_type
233 <
234 strategy_type
235 >::type comparable_type;
236
237 // 3b: "get_comparable"
238 comparable_type comparable = bgsd::services::get_comparable
239 <
240 strategy_type
241 >::apply(strategy);
242
243 typedef typename bgsd::services::return_type
244 <
245 comparable_type, Point, Box
246 >::type comparable_return_type;
247
248 comparable_return_type c_result = comparable.apply(p, b);
249 BOOST_CHECK_CLOSE(c_result, return_type(sqr_expected), 0.001);
250
251 // 4: the comparable_type should have a distance_strategy_constructor as well,
252 // knowing how to compare something with a fixed distance
253 comparable_return_type c_dist5 = services::result_from_distance
254 <
255 comparable_type, Point, Box
256 >::apply(comparable, 5.0);
257
258 comparable_return_type c_dist6 = services::result_from_distance
259 <
260 comparable_type, Point, Box
261 >::apply(comparable, 6.0);
262
263 // If this is the case:
264 BOOST_CHECK(c_dist5 < c_result && c_result < c_dist6);
265
266 // This should also be the case
267 return_type dist5 = services::result_from_distance
268 <
269 strategy_type, Point, Box
270 >::apply(strategy, 5.0);
271 return_type dist6 = services::result_from_distance
272 <
273 strategy_type, Point, Box
274 >::apply(strategy, 6.0);
275 BOOST_CHECK(dist5 < result && result < dist6);
276}
277
278template
279<
280 typename CoordinateType,
281 typename CalculationType,
282 typename AssignType
283>
284inline void test_big_2d_with(AssignType const& x1, AssignType const& y1,
285 AssignType const& x2, AssignType const& y2,
286 AssignType const& zero)
287{
288 typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
289 typedef bg::model::box<point_type> box_type;
290 typedef bg::strategy::distance::pythagoras_point_box
291 <
292 CalculationType
293 > pythagoras_pb_type;
294
295 pythagoras_pb_type pythagoras_pb;
296 typedef typename bg::strategy::distance::services::return_type
297 <
298 pythagoras_pb_type, point_type, box_type
299 >::type return_type;
300
301
302 point_type p;
303 box_type b;
304 bg::assign_values(b, zero, zero, x1, y1);
305 bg::assign_values(p, x2, y2);
306 return_type d = pythagoras_pb.apply(p, b);
307
308 BOOST_CHECK_CLOSE(d, return_type(1076554.5485833955678294387789057), 0.001);
309}
310
311template <typename CoordinateType, typename CalculationType>
312inline void test_big_2d()
313{
314 test_big_2d_with<CoordinateType, CalculationType>
315 (123456.78900001, 234567.89100001,
316 987654.32100001, 876543.21900001,
317 0.0);
318}
319
320template <typename CoordinateType, typename CalculationType>
321inline void test_big_2d_string()
322{
323 test_big_2d_with<CoordinateType, CalculationType>
324 ("123456.78900001", "234567.89100001",
325 "987654.32100001", "876543.21900001",
326 "0.0000000000000");
327}
328
329template <typename CoordinateType>
330inline void test_integer(bool check_types)
331{
332 typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
333 typedef bg::model::box<point_type> box_type;
334
335 point_type p;
336 box_type b;
337 bg::assign_values(b, 0, 0, 12345678, 23456789);
338 bg::assign_values(p, 98765432, 87654321);
339
340 typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_type;
341 typedef typename bg::strategy::distance::services::comparable_type
342 <
343 pythagoras_type
344 >::type comparable_type;
345
346 typedef typename bg::strategy::distance::services::return_type
347 <
348 pythagoras_type, point_type, box_type
349 >::type distance_type;
350 typedef typename bg::strategy::distance::services::return_type
351 <
352 comparable_type, point_type, box_type
353 >::type cdistance_type;
354
355 pythagoras_type pythagoras;
356 distance_type distance = pythagoras.apply(p, b);
357 BOOST_CHECK_CLOSE(distance, 107655455.02347542, 0.001);
358
359 comparable_type comparable;
360 cdistance_type cdistance = comparable.apply(p, b);
b32b8144 361 BOOST_CHECK_EQUAL(cdistance, 11589696996311540.0);
7c673cae
FG
362
363 distance_type distance2 = sqrt(distance_type(cdistance));
364 BOOST_CHECK_CLOSE(distance, distance2, 0.001);
365
366 if (check_types)
367 {
368 BOOST_CHECK((boost::is_same<distance_type, double>::type::value));
369 BOOST_CHECK((boost::is_same<cdistance_type, boost::long_long_type>::type::value));
370 }
371}
372
373template <typename P1, typename P2>
374void test_all_3d()
375{
376 test_null_distance_3d<P1, bg::model::box<P2> >();
377 test_axis_3d<P1, bg::model::box<P2> >();
378 test_arbitrary_3d<P1, bg::model::box<P2> >();
379
380 test_null_distance_3d<P2, bg::model::box<P1> >();
381 test_axis_3d<P2, bg::model::box<P1> >();
382 test_arbitrary_3d<P2, bg::model::box<P1> >();
383}
384
385template <typename P>
386void test_all_3d()
387{
388 test_all_3d<P, int[3]>();
389 test_all_3d<P, float[3]>();
390 test_all_3d<P, double[3]>();
391 test_all_3d<P, test::test_point>();
392 test_all_3d<P, bg::model::point<int, 3, bg::cs::cartesian> >();
393 test_all_3d<P, bg::model::point<float, 3, bg::cs::cartesian> >();
394 test_all_3d<P, bg::model::point<double, 3, bg::cs::cartesian> >();
395}
396
397template <typename P, typename Strategy>
398void time_compare_s(int const n)
399{
400 typedef bg::model::box<P> box_type;
401
402 boost::timer t;
403 P p;
404 box_type b;
405 bg::assign_values(b, 0, 0, 1, 1);
406 bg::assign_values(p, 2, 2);
407 Strategy strategy;
408 typename bg::strategy::distance::services::return_type
409 <
410 Strategy, P, box_type
411 >::type s = 0;
412 for (int i = 0; i < n; i++)
413 {
414 for (int j = 0; j < n; j++)
415 {
416 bg::set<0>(p, bg::get<0>(p) + 0.001);
417 s += strategy.apply(p, b);
418 }
419 }
420 std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
421}
422
423template <typename P>
424inline void time_compare(int const n)
425{
426 time_compare_s<P, bg::strategy::distance::pythagoras_point_box<> >(n);
427 time_compare_s
428 <
429 P, bg::strategy::distance::comparable::pythagoras_point_box<>
430 >(n);
431}
432
433
434
435
436BOOST_AUTO_TEST_CASE( test_integer_all )
437{
438 test_integer<int>(true);
439 test_integer<boost::long_long_type>(true);
440 test_integer<double>(false);
441}
442
443
444BOOST_AUTO_TEST_CASE( test_3d_all )
445{
446 test_all_3d<int[3]>();
447 test_all_3d<float[3]>();
448 test_all_3d<double[3]>();
449
450 test_all_3d<test::test_point>();
451
452 test_all_3d<bg::model::point<int, 3, bg::cs::cartesian> >();
453 test_all_3d<bg::model::point<float, 3, bg::cs::cartesian> >();
454 test_all_3d<bg::model::point<double, 3, bg::cs::cartesian> >();
455}
456
457
458BOOST_AUTO_TEST_CASE( test_big_2d_all )
459{
460 test_big_2d<float, float>();
461 test_big_2d<double, double>();
462 test_big_2d<long double, long double>();
463 test_big_2d<float, long double>();
464}
465
466
467BOOST_AUTO_TEST_CASE( test_services_all )
468{
469 test_services
470 <
471 bg::model::point<float, 3, bg::cs::cartesian>,
472 bg::model::box<double[3]>,
473 long double
474 >();
475 test_services<double[3], bg::model::box<test::test_point>, float>();
476
477 // reverse the point and box types
478 test_services
479 <
480 double[3],
481 bg::model::box<bg::model::point<float, 3, bg::cs::cartesian> >,
482 long double
483 >();
484 test_services<test::test_point, bg::model::box<double[3]>, float>();
485}
486
487
488BOOST_AUTO_TEST_CASE( test_time_compare )
489{
490 // TODO move this to another non-unit test
491 // time_compare<bg::model::point<double, 2, bg::cs::cartesian> >(10000);
492}
493