]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/include/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / strategies / cartesian / distance_pythagoras_box_box.hpp
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
33 namespace boost { namespace geometry
34 {
35
36 namespace strategy { namespace distance
37 {
38
39 #ifndef DOXYGEN_NO_DETAIL
40 namespace detail
41 {
42
43 template <std::size_t I>
44 struct 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
74 template <>
75 struct 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
87 namespace 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 */
97 template <typename CalculationType = void>
98 class pythagoras_box_box
99 {
100 public :
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 */
154 template
155 <
156 typename CalculationType = void
157 >
158 class pythagoras_box_box
159 {
160 public :
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
203 namespace services
204 {
205
206 template <typename CalculationType>
207 struct tag<pythagoras_box_box<CalculationType> >
208 {
209 typedef strategy_tag_distance_box_box type;
210 };
211
212
213 template <typename CalculationType, typename Box1, typename Box2>
214 struct return_type<distance::pythagoras_box_box<CalculationType>, Box1, Box2>
215 : pythagoras_box_box<CalculationType>::template calculation_type<Box1, Box2>
216 {};
217
218
219 template <typename CalculationType>
220 struct comparable_type<pythagoras_box_box<CalculationType> >
221 {
222 typedef comparable::pythagoras_box_box<CalculationType> type;
223 };
224
225
226 template <typename CalculationType>
227 struct get_comparable<pythagoras_box_box<CalculationType> >
228 {
229 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
230 public :
231 static inline comparable_type
232 apply(pythagoras_box_box<CalculationType> const& )
233 {
234 return comparable_type();
235 }
236 };
237
238
239 template <typename CalculationType, typename Box1, typename Box2>
240 struct result_from_distance<pythagoras_box_box<CalculationType>, Box1, Box2>
241 {
242 private:
243 typedef typename return_type
244 <
245 pythagoras_box_box<CalculationType>, Box1, Box2
246 >::type return_type;
247 public:
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
258 template <typename CalculationType>
259 struct tag<comparable::pythagoras_box_box<CalculationType> >
260 {
261 typedef strategy_tag_distance_box_box type;
262 };
263
264
265 template <typename CalculationType, typename Box1, typename Box2>
266 struct 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
276 template <typename CalculationType>
277 struct comparable_type<comparable::pythagoras_box_box<CalculationType> >
278 {
279 typedef comparable::pythagoras_box_box<CalculationType> type;
280 };
281
282
283 template <typename CalculationType>
284 struct get_comparable<comparable::pythagoras_box_box<CalculationType> >
285 {
286 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
287 public :
288 static inline comparable_type apply(comparable_type const& )
289 {
290 return comparable_type();
291 }
292 };
293
294
295 template <typename CalculationType, typename Box1, typename Box2>
296 struct result_from_distance
297 <
298 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
299 >
300 {
301 private :
302 typedef typename return_type
303 <
304 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
305 >::type return_type;
306 public :
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
318 template <typename BoxPoint1, typename BoxPoint2>
319 struct 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