1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
14 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
15 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
18 #include <boost/geometry/core/access.hpp>
20 #include <boost/geometry/strategies/distance.hpp>
22 #include <boost/geometry/util/math.hpp>
23 #include <boost/geometry/util/calculation_type.hpp>
26 namespace boost { namespace geometry
29 namespace strategy { namespace distance
32 #ifndef DOXYGEN_NO_DETAIL
36 template <size_t I, typename T>
37 struct compute_pythagoras
39 template <typename Point1, typename Point2>
40 static inline T apply(Point1 const& p1, Point2 const& p2)
42 T const c1 = boost::numeric_cast<T>(get<I-1>(p1));
43 T const c2 = boost::numeric_cast<T>(get<I-1>(p2));
45 return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
50 struct compute_pythagoras<0, T>
52 template <typename Point1, typename Point2>
53 static inline T apply(Point1 const&, Point2 const&)
55 return boost::numeric_cast<T>(0);
60 #endif // DOXYGEN_NO_DETAIL
67 \brief Strategy to calculate comparable distance between two points
69 \tparam Point1 \tparam_first_point
70 \tparam Point2 \tparam_second_point
71 \tparam CalculationType \tparam_calculation
73 template <typename CalculationType = void>
78 template <typename Point1, typename Point2>
79 struct calculation_type
80 : util::calculation_type::geometric::binary
90 template <typename Point1, typename Point2>
91 static inline typename calculation_type<Point1, Point2>::type
92 apply(Point1 const& p1, Point2 const& p2)
94 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point1>) );
95 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
97 // Calculate distance using Pythagoras
98 // (Leave comment above for Doxygen)
100 assert_dimension_equal<Point1, Point2>();
102 return detail::compute_pythagoras
104 dimension<Point1>::value,
105 typename calculation_type<Point1, Point2>::type
110 } // namespace comparable
114 \brief Strategy to calculate the distance between two points
116 \tparam CalculationType \tparam_calculation
120 [note Can be used for points with two\, three or more dimensions]
122 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
128 typename CalculationType = void
134 template <typename P1, typename P2>
135 struct calculation_type
136 : util::calculation_type::geometric::binary
142 double // promote integer to double
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
152 template <typename P1, typename P2>
153 static inline typename calculation_type<P1, P2>::type
154 apply(P1 const& p1, P2 const& p2)
156 // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
159 boost::numeric_cast<typename calculation_type<P1, P2>::type>
161 comparable::pythagoras<CalculationType>::apply(p1, p2)
168 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
172 template <typename CalculationType>
173 struct tag<pythagoras<CalculationType> >
175 typedef strategy_tag_distance_point_point type;
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>
185 template <typename CalculationType>
186 struct comparable_type<pythagoras<CalculationType> >
188 typedef comparable::pythagoras<CalculationType> type;
192 template <typename CalculationType>
193 struct get_comparable<pythagoras<CalculationType> >
195 typedef comparable::pythagoras<CalculationType> comparable_type;
197 static inline comparable_type apply(pythagoras<CalculationType> const& )
199 return comparable_type();
204 template <typename CalculationType, typename Point1, typename Point2>
205 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
208 typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
210 template <typename T>
211 static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
213 return return_type(value);
218 // Specializations for comparable::pythagoras
219 template <typename CalculationType>
220 struct tag<comparable::pythagoras<CalculationType> >
222 typedef strategy_tag_distance_point_point type;
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>
234 template <typename CalculationType>
235 struct comparable_type<comparable::pythagoras<CalculationType> >
237 typedef comparable::pythagoras<CalculationType> type;
241 template <typename CalculationType>
242 struct get_comparable<comparable::pythagoras<CalculationType> >
244 typedef comparable::pythagoras<CalculationType> comparable_type;
246 static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
248 return comparable_type();
253 template <typename CalculationType, typename Point1, typename Point2>
254 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
257 typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
259 template <typename T>
260 static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
262 return_type const v = value;
268 template <typename Point1, typename Point2>
269 struct default_strategy
271 point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
274 typedef pythagoras<> type;
278 } // namespace services
279 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
282 }} // namespace strategy::distance
285 }} // namespace boost::geometry
288 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP