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