]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / strategies / cartesian / distance_pythagoras_box_box.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
4// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
5// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
6
7// This file was modified by Oracle on 2014.
8// Modifications copyright (c) 2014, Oracle and/or its affiliates.
9
10// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11
12// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14
15// Use, modification and distribution is subject to the Boost Software License,
16// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17// http://www.boost.org/LICENSE_1_0.txt)
18
19#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP
20#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP
21
22
23#include <boost/geometry/core/access.hpp>
24
25#include <boost/geometry/strategies/distance.hpp>
26
27#include <boost/geometry/util/math.hpp>
28#include <boost/geometry/util/calculation_type.hpp>
29
30
31
32
33namespace boost { namespace geometry
34{
35
36namespace strategy { namespace distance
37{
38
39#ifndef DOXYGEN_NO_DETAIL
40namespace detail
41{
42
43template <std::size_t I>
44struct compute_pythagoras_box_box
45{
46 template <typename Box1, typename Box2, typename T>
47 static inline void apply(Box1 const& box1, Box2 const& box2, T& result)
48 {
49 T const b1_min_coord =
50 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box1));
51 T const b1_max_coord =
52 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box1));
53
54 T const b2_min_coord =
55 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box2));
56 T const b2_max_coord =
57 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box2));
58
59 if ( b1_max_coord < b2_min_coord )
60 {
61 T diff = b2_min_coord - b1_max_coord;
62 result += diff * diff;
63 }
64 if ( b1_min_coord > b2_max_coord )
65 {
66 T diff = b1_min_coord - b2_max_coord;
67 result += diff * diff;
68 }
69
70 compute_pythagoras_box_box<I-1>::apply(box1, box2, result);
71 }
72};
73
74template <>
75struct compute_pythagoras_box_box<0>
76{
77 template <typename Box1, typename Box2, typename T>
78 static inline void apply(Box1 const&, Box2 const&, T&)
79 {
80 }
81};
82
83}
84#endif // DOXYGEN_NO_DETAIL
85
86
87namespace comparable
88{
89
90/*!
91\brief Strategy to calculate comparable distance between two boxes
92\ingroup strategies
93\tparam Box1 \tparam_first_box
94\tparam Box2 \tparam_second_box
95\tparam CalculationType \tparam_calculation
96*/
97template <typename CalculationType = void>
98class pythagoras_box_box
99{
100public :
101
102 template <typename Box1, typename Box2>
103 struct calculation_type
104 {
105 typedef typename util::calculation_type::geometric::binary
106 <
107 Box1,
108 Box2,
109 CalculationType
110 >::type type;
111 };
112
113 template <typename Box1, typename Box2>
114 static inline typename calculation_type<Box1, Box2>::type
115 apply(Box1 const& box1, Box2 const& box2)
116 {
117 BOOST_CONCEPT_ASSERT
118 ( (concepts::ConstPoint<typename point_type<Box1>::type>) );
119 BOOST_CONCEPT_ASSERT
120 ( (concepts::ConstPoint<typename point_type<Box2>::type>) );
121
122 // Calculate distance using Pythagoras
123 // (Leave comment above for Doxygen)
124
125 assert_dimension_equal<Box1, Box2>();
126
127 typename calculation_type<Box1, Box2>::type result(0);
128
129 detail::compute_pythagoras_box_box
130 <
131 dimension<Box1>::value
132 >::apply(box1, box2, result);
133
134 return result;
135 }
136};
137
138} // namespace comparable
139
140
141/*!
142\brief Strategy to calculate the distance between two boxes
143\ingroup strategies
144\tparam CalculationType \tparam_calculation
145
146\qbk{
147[heading Notes]
148[note Can be used for boxes with two\, three or more dimensions]
149[heading See also]
150[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
151}
152
153*/
154template
155<
156 typename CalculationType = void
157>
158class pythagoras_box_box
159{
160public :
161
162 template <typename Box1, typename Box2>
163 struct calculation_type
164 : util::calculation_type::geometric::binary
165 <
166 Box1,
167 Box2,
168 CalculationType,
169 double,
170 double // promote integer to double
171 >
172 {};
173
174 /*!
175 \brief applies the distance calculation using pythagoras_box_box
176 \return the calculated distance (including taking the square root)
177 \param box1 first box
178 \param box2 second box
179 */
180 template <typename Box1, typename Box2>
181 static inline typename calculation_type<Box1, Box2>::type
182 apply(Box1 const& box1, Box2 const& box2)
183 {
184 // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
185 return math::sqrt
186 (
187 boost::numeric_cast<typename calculation_type
188 <
189 Box1, Box2
190 >::type>
191 (
192 comparable::pythagoras_box_box
193 <
194 CalculationType
195 >::apply(box1, box2)
196 )
197 );
198 }
199};
200
201
202#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
203namespace services
204{
205
206template <typename CalculationType>
207struct tag<pythagoras_box_box<CalculationType> >
208{
209 typedef strategy_tag_distance_box_box type;
210};
211
212
213template <typename CalculationType, typename Box1, typename Box2>
214struct return_type<distance::pythagoras_box_box<CalculationType>, Box1, Box2>
215 : pythagoras_box_box<CalculationType>::template calculation_type<Box1, Box2>
216{};
217
218
219template <typename CalculationType>
220struct comparable_type<pythagoras_box_box<CalculationType> >
221{
222 typedef comparable::pythagoras_box_box<CalculationType> type;
223};
224
225
226template <typename CalculationType>
227struct get_comparable<pythagoras_box_box<CalculationType> >
228{
229 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
230public :
231 static inline comparable_type
232 apply(pythagoras_box_box<CalculationType> const& )
233 {
234 return comparable_type();
235 }
236};
237
238
239template <typename CalculationType, typename Box1, typename Box2>
240struct result_from_distance<pythagoras_box_box<CalculationType>, Box1, Box2>
241{
242private:
243 typedef typename return_type
244 <
245 pythagoras_box_box<CalculationType>, Box1, Box2
246 >::type return_type;
247public:
248 template <typename T>
249 static inline return_type
250 apply(pythagoras_box_box<CalculationType> const& , T const& value)
251 {
252 return return_type(value);
253 }
254};
255
256
257// Specializations for comparable::pythagoras_box_box
258template <typename CalculationType>
259struct tag<comparable::pythagoras_box_box<CalculationType> >
260{
261 typedef strategy_tag_distance_box_box type;
262};
263
264
265template <typename CalculationType, typename Box1, typename Box2>
266struct return_type<comparable::pythagoras_box_box<CalculationType>, Box1, Box2>
267 : comparable::pythagoras_box_box
268 <
269 CalculationType
270 >::template calculation_type<Box1, Box2>
271{};
272
273
274
275
276template <typename CalculationType>
277struct comparable_type<comparable::pythagoras_box_box<CalculationType> >
278{
279 typedef comparable::pythagoras_box_box<CalculationType> type;
280};
281
282
283template <typename CalculationType>
284struct get_comparable<comparable::pythagoras_box_box<CalculationType> >
285{
286 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
287public :
288 static inline comparable_type apply(comparable_type const& )
289 {
290 return comparable_type();
291 }
292};
293
294
295template <typename CalculationType, typename Box1, typename Box2>
296struct result_from_distance
297 <
298 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
299 >
300{
301private :
302 typedef typename return_type
303 <
304 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
305 >::type return_type;
306public :
307 template <typename T>
308 static inline return_type
309 apply(comparable::pythagoras_box_box<CalculationType> const&,
310 T const& value)
311 {
312 return_type const v = value;
313 return v * v;
314 }
315};
316
317
318template <typename BoxPoint1, typename BoxPoint2>
319struct default_strategy
320 <
321 box_tag, box_tag, BoxPoint1, BoxPoint2, cartesian_tag, cartesian_tag
322 >
323{
324 typedef pythagoras_box_box<> type;
325};
326
327
328} // namespace services
329#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
330
331
332}} // namespace strategy::distance
333
334
335}} // namespace boost::geometry
336
337
338#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP