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