]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / strategies / cartesian / distance_pythagoras_point_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
92f5a8d4
TL
7// This file was modified by Oracle on 2014, 2018.
8// Modifications copyright (c) 2014, 2018, Oracle and/or its affiliates.
7c673cae
FG
9
10// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
92f5a8d4 11// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7c673cae
FG
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>
92f5a8d4
TL
25#include <boost/geometry/core/point_type.hpp>
26
27#include <boost/geometry/geometries/concepts/point_concept.hpp>
7c673cae
FG
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
36namespace boost { namespace geometry
37{
38
39namespace strategy { namespace distance
40{
41
42#ifndef DOXYGEN_NO_DETAIL
43namespace detail
44{
45
46template <size_t I>
47struct 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
73template <>
74struct 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
87namespace 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*/
98template <typename CalculationType = void>
99class pythagoras_point_box
100{
101public :
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*/
152template
153<
154 typename CalculationType = void
155>
156class pythagoras_point_box
157{
158public :
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
201namespace services
202{
203
204template <typename CalculationType>
205struct tag<pythagoras_point_box<CalculationType> >
206{
207 typedef strategy_tag_distance_point_box type;
208};
209
210
211template <typename CalculationType, typename Point, typename Box>
212struct 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
220template <typename CalculationType>
221struct comparable_type<pythagoras_point_box<CalculationType> >
222{
223 typedef comparable::pythagoras_point_box<CalculationType> type;
224};
225
226
227template <typename CalculationType>
228struct get_comparable<pythagoras_point_box<CalculationType> >
229{
230 typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
231public :
232 static inline comparable_type
233 apply(pythagoras_point_box<CalculationType> const& )
234 {
235 return comparable_type();
236 }
237};
238
239
240template <typename CalculationType, typename Point, typename Box>
241struct result_from_distance<pythagoras_point_box<CalculationType>, Point, Box>
242{
243private :
244 typedef typename return_type
245 <
246 pythagoras_point_box<CalculationType>, Point, Box
247 >::type return_type;
248public :
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
259template <typename CalculationType>
260struct tag<comparable::pythagoras_point_box<CalculationType> >
261{
262 typedef strategy_tag_distance_point_box type;
263};
264
265
266template <typename CalculationType, typename Point, typename Box>
267struct 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
279template <typename CalculationType>
280struct comparable_type<comparable::pythagoras_point_box<CalculationType> >
281{
282 typedef comparable::pythagoras_point_box<CalculationType> type;
283};
284
285
286template <typename CalculationType>
287struct get_comparable<comparable::pythagoras_point_box<CalculationType> >
288{
289 typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
290public :
291 static inline comparable_type apply(comparable_type const& )
292 {
293 return comparable_type();
294 }
295};
296
297
298template <typename CalculationType, typename Point, typename Box>
299struct result_from_distance
300 <
301 comparable::pythagoras_point_box<CalculationType>, Point, Box
302 >
303{
304private :
305 typedef typename return_type
306 <
307 comparable::pythagoras_point_box<CalculationType>, Point, Box
308 >::type return_type;
309public :
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
321template <typename Point, typename BoxPoint>
322struct default_strategy
323 <
324 point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
325 >
326{
327 typedef pythagoras_point_box<> type;
328};
329
330template <typename BoxPoint, typename Point>
331struct 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