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