]> git.proxmox.com Git - ceph.git/blob - 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
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
26 namespace boost { namespace geometry
27 {
28
29 namespace strategy { namespace distance
30 {
31
32 #ifndef DOXYGEN_NO_DETAIL
33 namespace detail
34 {
35
36 template <size_t I, typename T>
37 struct 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
49 template <typename T>
50 struct 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
63 namespace 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 */
73 template <typename CalculationType = void>
74 class pythagoras
75 {
76 public :
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 */
126 template
127 <
128 typename CalculationType = void
129 >
130 class pythagoras
131 {
132 public :
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
169 namespace services
170 {
171
172 template <typename CalculationType>
173 struct tag<pythagoras<CalculationType> >
174 {
175 typedef strategy_tag_distance_point_point type;
176 };
177
178
179 template <typename CalculationType, typename P1, typename P2>
180 struct return_type<distance::pythagoras<CalculationType>, P1, P2>
181 : pythagoras<CalculationType>::template calculation_type<P1, P2>
182 {};
183
184
185 template <typename CalculationType>
186 struct comparable_type<pythagoras<CalculationType> >
187 {
188 typedef comparable::pythagoras<CalculationType> type;
189 };
190
191
192 template <typename CalculationType>
193 struct get_comparable<pythagoras<CalculationType> >
194 {
195 typedef comparable::pythagoras<CalculationType> comparable_type;
196 public :
197 static inline comparable_type apply(pythagoras<CalculationType> const& )
198 {
199 return comparable_type();
200 }
201 };
202
203
204 template <typename CalculationType, typename Point1, typename Point2>
205 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
206 {
207 private :
208 typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
209 public :
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
219 template <typename CalculationType>
220 struct tag<comparable::pythagoras<CalculationType> >
221 {
222 typedef strategy_tag_distance_point_point type;
223 };
224
225
226 template <typename CalculationType, typename P1, typename P2>
227 struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
228 : comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
229 {};
230
231
232
233
234 template <typename CalculationType>
235 struct comparable_type<comparable::pythagoras<CalculationType> >
236 {
237 typedef comparable::pythagoras<CalculationType> type;
238 };
239
240
241 template <typename CalculationType>
242 struct get_comparable<comparable::pythagoras<CalculationType> >
243 {
244 typedef comparable::pythagoras<CalculationType> comparable_type;
245 public :
246 static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
247 {
248 return comparable_type();
249 }
250 };
251
252
253 template <typename CalculationType, typename Point1, typename Point2>
254 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
255 {
256 private :
257 typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
258 public :
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
268 template <typename Point1, typename Point2>
269 struct 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