Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. Chris@16: // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Chris@16: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP Chris@16: #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP Chris@16: Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@101: #include Chris@16: #include Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: namespace boost { namespace geometry Chris@16: { Chris@16: Chris@16: namespace strategy { namespace distance Chris@16: { Chris@16: Chris@16: #ifndef DOXYGEN_NO_DETAIL Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: template Chris@16: struct compute_pythagoras Chris@16: { Chris@16: template Chris@16: static inline T apply(Point1 const& p1, Point2 const& p2) Chris@16: { Chris@16: T const c1 = boost::numeric_cast(get(p1)); Chris@16: T const c2 = boost::numeric_cast(get(p2)); Chris@16: T const d = c1 - c2; Chris@16: return d * d + compute_pythagoras::apply(p1, p2); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct compute_pythagoras<0, T> Chris@16: { Chris@16: template Chris@16: static inline T apply(Point1 const&, Point2 const&) Chris@16: { Chris@16: return boost::numeric_cast(0); Chris@16: } Chris@16: }; Chris@16: Chris@16: } Chris@16: #endif // DOXYGEN_NO_DETAIL Chris@16: Chris@16: Chris@16: namespace comparable Chris@16: { Chris@16: Chris@16: /*! Chris@16: \brief Strategy to calculate comparable distance between two points Chris@16: \ingroup strategies Chris@16: \tparam Point1 \tparam_first_point Chris@16: \tparam Point2 \tparam_second_point Chris@16: \tparam CalculationType \tparam_calculation Chris@16: */ Chris@16: template Chris@16: class pythagoras Chris@16: { Chris@16: public : Chris@16: Chris@16: template Chris@16: struct calculation_type Chris@16: : util::calculation_type::geometric::binary Chris@16: < Chris@16: Point1, Chris@16: Point2, Chris@101: CalculationType, Chris@101: double, Chris@101: double Chris@16: > Chris@16: {}; Chris@16: Chris@16: template Chris@16: static inline typename calculation_type::type Chris@16: apply(Point1 const& p1, Point2 const& p2) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT( (concept::ConstPoint) ); Chris@16: BOOST_CONCEPT_ASSERT( (concept::ConstPoint) ); Chris@16: Chris@16: // Calculate distance using Pythagoras Chris@16: // (Leave comment above for Doxygen) Chris@16: Chris@16: assert_dimension_equal(); Chris@16: Chris@16: return detail::compute_pythagoras Chris@16: < Chris@16: dimension::value, Chris@16: typename calculation_type::type Chris@16: >::apply(p1, p2); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace comparable Chris@16: Chris@16: Chris@16: /*! Chris@16: \brief Strategy to calculate the distance between two points Chris@16: \ingroup strategies Chris@16: \tparam CalculationType \tparam_calculation Chris@16: Chris@16: \qbk{ Chris@16: [heading Notes] Chris@16: [note Can be used for points with two\, three or more dimensions] Chris@16: [heading See also] Chris@16: [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)] Chris@16: } Chris@16: Chris@16: */ Chris@16: template Chris@16: < Chris@16: typename CalculationType = void Chris@16: > Chris@16: class pythagoras Chris@16: { Chris@16: public : Chris@16: Chris@16: template Chris@16: struct calculation_type Chris@16: : util::calculation_type::geometric::binary Chris@16: < Chris@16: P1, Chris@16: P2, Chris@16: CalculationType, Chris@16: double, Chris@16: double // promote integer to double Chris@16: > Chris@16: {}; Chris@16: Chris@16: /*! Chris@16: \brief applies the distance calculation using pythagoras Chris@16: \return the calculated distance (including taking the square root) Chris@16: \param p1 first point Chris@16: \param p2 second point Chris@16: */ Chris@16: template Chris@16: static inline typename calculation_type::type Chris@16: apply(P1 const& p1, P2 const& p2) Chris@16: { Chris@16: // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call Chris@101: return math::sqrt Chris@16: ( Chris@16: boost::numeric_cast::type> Chris@16: ( Chris@16: comparable::pythagoras::apply(p1, p2) Chris@16: ) Chris@16: ); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS Chris@16: namespace services Chris@16: { Chris@16: Chris@16: template Chris@16: struct tag > Chris@16: { Chris@16: typedef strategy_tag_distance_point_point type; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct return_type, P1, P2> Chris@16: : pythagoras::template calculation_type Chris@16: {}; Chris@16: Chris@16: Chris@16: template Chris@16: struct comparable_type > Chris@16: { Chris@16: typedef comparable::pythagoras type; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct get_comparable > Chris@16: { Chris@16: typedef comparable::pythagoras comparable_type; Chris@16: public : Chris@16: static inline comparable_type apply(pythagoras const& ) Chris@16: { Chris@16: return comparable_type(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct result_from_distance, Point1, Point2> Chris@16: { Chris@16: private : Chris@16: typedef typename return_type, Point1, Point2>::type return_type; Chris@16: public : Chris@16: template Chris@16: static inline return_type apply(pythagoras const& , T const& value) Chris@16: { Chris@16: return return_type(value); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: // Specializations for comparable::pythagoras Chris@16: template Chris@16: struct tag > Chris@16: { Chris@16: typedef strategy_tag_distance_point_point type; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct return_type, P1, P2> Chris@16: : comparable::pythagoras::template calculation_type Chris@16: {}; Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: template Chris@16: struct comparable_type > Chris@16: { Chris@16: typedef comparable::pythagoras type; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct get_comparable > Chris@16: { Chris@16: typedef comparable::pythagoras comparable_type; Chris@16: public : Chris@16: static inline comparable_type apply(comparable::pythagoras const& ) Chris@16: { Chris@16: return comparable_type(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: struct result_from_distance, Point1, Point2> Chris@16: { Chris@16: private : Chris@16: typedef typename return_type, Point1, Point2>::type return_type; Chris@16: public : Chris@16: template Chris@16: static inline return_type apply(comparable::pythagoras const& , T const& value) Chris@16: { Chris@16: return_type const v = value; Chris@16: return v * v; Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@101: struct default_strategy Chris@101: < Chris@101: point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag Chris@101: > Chris@16: { Chris@16: typedef pythagoras<> type; Chris@16: }; Chris@16: Chris@16: Chris@16: } // namespace services Chris@16: #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS Chris@16: Chris@16: Chris@16: }} // namespace strategy::distance Chris@16: Chris@16: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: Chris@16: #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP