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 // This file was modified by Oracle on 2018.
8 // Modifications copyright (c) 2018, Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
19 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
20 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
23 #include <boost/geometry/core/access.hpp>
25 #include <boost/geometry/geometries/concepts/point_concept.hpp>
27 #include <boost/geometry/strategies/distance.hpp>
29 #include <boost/geometry/util/math.hpp>
30 #include <boost/geometry/util/calculation_type.hpp>
33 namespace boost { namespace geometry
36 namespace strategy { namespace distance
39 #ifndef DOXYGEN_NO_DETAIL
43 template <size_t I, typename T>
44 struct compute_pythagoras
46 template <typename Point1, typename Point2>
47 static inline T apply(Point1 const& p1, Point2 const& p2)
49 T const c1 = boost::numeric_cast<T>(get<I-1>(p1));
50 T const c2 = boost::numeric_cast<T>(get<I-1>(p2));
52 return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
57 struct compute_pythagoras<0, T>
59 template <typename Point1, typename Point2>
60 static inline T apply(Point1 const&, Point2 const&)
62 return boost::numeric_cast<T>(0);
67 #endif // DOXYGEN_NO_DETAIL
74 \brief Strategy to calculate comparable distance between two points
76 \tparam Point1 \tparam_first_point
77 \tparam Point2 \tparam_second_point
78 \tparam CalculationType \tparam_calculation
80 template <typename CalculationType = void>
85 template <typename Point1, typename Point2>
86 struct calculation_type
87 : util::calculation_type::geometric::binary
97 template <typename Point1, typename Point2>
98 static inline typename calculation_type<Point1, Point2>::type
99 apply(Point1 const& p1, Point2 const& p2)
101 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point1>) );
102 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
104 // Calculate distance using Pythagoras
105 // (Leave comment above for Doxygen)
107 assert_dimension_equal<Point1, Point2>();
109 return detail::compute_pythagoras
111 dimension<Point1>::value,
112 typename calculation_type<Point1, Point2>::type
117 } // namespace comparable
121 \brief Strategy to calculate the distance between two points
123 \tparam CalculationType \tparam_calculation
127 [note Can be used for points with two\, three or more dimensions]
129 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
135 typename CalculationType = void
141 template <typename P1, typename P2>
142 struct calculation_type
143 : util::calculation_type::geometric::binary
149 double // promote integer to double
154 \brief applies the distance calculation using pythagoras
155 \return the calculated distance (including taking the square root)
156 \param p1 first point
157 \param p2 second point
159 template <typename P1, typename P2>
160 static inline typename calculation_type<P1, P2>::type
161 apply(P1 const& p1, P2 const& p2)
163 // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
166 boost::numeric_cast<typename calculation_type<P1, P2>::type>
168 comparable::pythagoras<CalculationType>::apply(p1, p2)
175 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
179 template <typename CalculationType>
180 struct tag<pythagoras<CalculationType> >
182 typedef strategy_tag_distance_point_point type;
186 template <typename CalculationType, typename P1, typename P2>
187 struct return_type<distance::pythagoras<CalculationType>, P1, P2>
188 : pythagoras<CalculationType>::template calculation_type<P1, P2>
192 template <typename CalculationType>
193 struct comparable_type<pythagoras<CalculationType> >
195 typedef comparable::pythagoras<CalculationType> type;
199 template <typename CalculationType>
200 struct get_comparable<pythagoras<CalculationType> >
202 typedef comparable::pythagoras<CalculationType> comparable_type;
204 static inline comparable_type apply(pythagoras<CalculationType> const& )
206 return comparable_type();
211 template <typename CalculationType, typename Point1, typename Point2>
212 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
215 typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
217 template <typename T>
218 static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
220 return return_type(value);
225 // Specializations for comparable::pythagoras
226 template <typename CalculationType>
227 struct tag<comparable::pythagoras<CalculationType> >
229 typedef strategy_tag_distance_point_point type;
233 template <typename CalculationType, typename P1, typename P2>
234 struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
235 : comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
241 template <typename CalculationType>
242 struct comparable_type<comparable::pythagoras<CalculationType> >
244 typedef comparable::pythagoras<CalculationType> type;
248 template <typename CalculationType>
249 struct get_comparable<comparable::pythagoras<CalculationType> >
251 typedef comparable::pythagoras<CalculationType> comparable_type;
253 static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
255 return comparable_type();
260 template <typename CalculationType, typename Point1, typename Point2>
261 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
264 typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
266 template <typename T>
267 static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
269 return_type const v = value;
275 template <typename Point1, typename Point2>
276 struct default_strategy
278 point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
281 typedef pythagoras<> type;
285 } // namespace services
286 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
289 }} // namespace strategy::distance
292 }} // namespace boost::geometry
295 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP