Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:34:22

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0004 // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 
0007 // This file was modified by Oracle on 2018.
0008 // Modifications copyright (c) 2018, Oracle and/or its affiliates.
0009 
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 
0012 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0013 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0014 
0015 // Use, modification and distribution is subject to the Boost Software License,
0016 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0017 // http://www.boost.org/LICENSE_1_0.txt)
0018 
0019 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
0020 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
0021 
0022 
0023 #include <boost/geometry/core/access.hpp>
0024 
0025 #include <boost/geometry/geometries/concepts/point_concept.hpp>
0026 
0027 #include <boost/geometry/strategies/distance.hpp>
0028 
0029 #include <boost/geometry/util/calculation_type.hpp>
0030 #include <boost/geometry/util/math.hpp>
0031 #include <boost/geometry/util/numeric_cast.hpp>
0032 
0033 
0034 namespace boost { namespace geometry
0035 {
0036 
0037 namespace strategy { namespace distance
0038 {
0039 
0040 #ifndef DOXYGEN_NO_DETAIL
0041 namespace detail
0042 {
0043 
0044 template <size_t I, typename T>
0045 struct compute_pythagoras
0046 {
0047     template <typename Point1, typename Point2>
0048     static inline T apply(Point1 const& p1, Point2 const& p2)
0049     {
0050         T const c1 = util::numeric_cast<T>(get<I-1>(p1));
0051         T const c2 = util::numeric_cast<T>(get<I-1>(p2));
0052         T const d = c1 - c2;
0053         return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
0054     }
0055 };
0056 
0057 template <typename T>
0058 struct compute_pythagoras<0, T>
0059 {
0060     template <typename Point1, typename Point2>
0061     static inline T apply(Point1 const&, Point2 const&)
0062     {
0063         return util::numeric_cast<T>(0);
0064     }
0065 };
0066 
0067 }
0068 #endif // DOXYGEN_NO_DETAIL
0069 
0070 
0071 namespace comparable
0072 {
0073 
0074 /*!
0075 \brief Strategy to calculate comparable distance between two points
0076 \ingroup strategies
0077 \tparam Point1 \tparam_first_point
0078 \tparam Point2 \tparam_second_point
0079 \tparam CalculationType \tparam_calculation
0080 */
0081 template <typename CalculationType = void>
0082 class pythagoras
0083 {
0084 public :
0085 
0086     template <typename Point1, typename Point2>
0087     struct calculation_type
0088         : util::calculation_type::geometric::binary
0089           <
0090               Point1,
0091               Point2,
0092               CalculationType,
0093               double,
0094               double
0095           >
0096     {};
0097 
0098     template <typename Point1, typename Point2>
0099     static inline typename calculation_type<Point1, Point2>::type
0100     apply(Point1 const& p1, Point2 const& p2)
0101     {
0102         BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point1>) );
0103         BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
0104 
0105         // Calculate distance using Pythagoras
0106         // (Leave comment above for Doxygen)
0107 
0108         assert_dimension_equal<Point1, Point2>();
0109 
0110         return detail::compute_pythagoras
0111             <
0112                 dimension<Point1>::value,
0113                 typename calculation_type<Point1, Point2>::type
0114             >::apply(p1, p2);
0115     }
0116 };
0117 
0118 } // namespace comparable
0119 
0120 
0121 /*!
0122 \brief Strategy to calculate the distance between two points
0123 \ingroup strategies
0124 \tparam CalculationType \tparam_calculation
0125 
0126 \qbk{
0127 [heading Notes]
0128 [note Can be used for points with two\, three or more dimensions]
0129 [heading See also]
0130 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
0131 }
0132 
0133 */
0134 template
0135 <
0136     typename CalculationType = void
0137 >
0138 class pythagoras
0139 {
0140 public :
0141 
0142     template <typename P1, typename P2>
0143     struct calculation_type
0144         : util::calculation_type::geometric::binary
0145           <
0146               P1,
0147               P2,
0148               CalculationType,
0149               double,
0150               double // promote integer to double
0151           >
0152     {};
0153 
0154     /*!
0155     \brief applies the distance calculation using pythagoras
0156     \return the calculated distance (including taking the square root)
0157     \param p1 first point
0158     \param p2 second point
0159     */
0160     template <typename P1, typename P2>
0161     static inline typename calculation_type<P1, P2>::type
0162     apply(P1 const& p1, P2 const& p2)
0163     {
0164         // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
0165         return math::sqrt
0166             (
0167                  util::numeric_cast<typename calculation_type<P1, P2>::type>
0168                     (
0169                         comparable::pythagoras<CalculationType>::apply(p1, p2)
0170                     )
0171             );
0172     }
0173 };
0174 
0175 
0176 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0177 namespace services
0178 {
0179 
0180 template <typename CalculationType>
0181 struct tag<pythagoras<CalculationType> >
0182 {
0183     typedef strategy_tag_distance_point_point type;
0184 };
0185 
0186 
0187 template <typename CalculationType, typename P1, typename P2>
0188 struct return_type<distance::pythagoras<CalculationType>, P1, P2>
0189     : pythagoras<CalculationType>::template calculation_type<P1, P2>
0190 {};
0191 
0192 
0193 template <typename CalculationType>
0194 struct comparable_type<pythagoras<CalculationType> >
0195 {
0196     typedef comparable::pythagoras<CalculationType> type;
0197 };
0198 
0199 
0200 template <typename CalculationType>
0201 struct get_comparable<pythagoras<CalculationType> >
0202 {
0203     typedef comparable::pythagoras<CalculationType> comparable_type;
0204 public :
0205     static inline comparable_type apply(pythagoras<CalculationType> const& )
0206     {
0207         return comparable_type();
0208     }
0209 };
0210 
0211 
0212 template <typename CalculationType, typename Point1, typename Point2>
0213 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
0214 {
0215 private :
0216     typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
0217 public :
0218     template <typename T>
0219     static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
0220     {
0221         return return_type(value);
0222     }
0223 };
0224 
0225 
0226 // Specializations for comparable::pythagoras
0227 template <typename CalculationType>
0228 struct tag<comparable::pythagoras<CalculationType> >
0229 {
0230     typedef strategy_tag_distance_point_point type;
0231 };
0232 
0233 
0234 template <typename CalculationType, typename P1, typename P2>
0235 struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
0236     : comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
0237 {};
0238 
0239 
0240 
0241 
0242 template <typename CalculationType>
0243 struct comparable_type<comparable::pythagoras<CalculationType> >
0244 {
0245     typedef comparable::pythagoras<CalculationType> type;
0246 };
0247 
0248 
0249 template <typename CalculationType>
0250 struct get_comparable<comparable::pythagoras<CalculationType> >
0251 {
0252     typedef comparable::pythagoras<CalculationType> comparable_type;
0253 public :
0254     static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
0255     {
0256         return comparable_type();
0257     }
0258 };
0259 
0260 
0261 template <typename CalculationType, typename Point1, typename Point2>
0262 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
0263 {
0264 private :
0265     typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
0266 public :
0267     template <typename T>
0268     static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
0269     {
0270         return_type const v = value;
0271         return v * v;
0272     }
0273 };
0274 
0275 
0276 template <typename Point1, typename Point2>
0277 struct default_strategy
0278     <
0279         point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
0280     >
0281 {
0282     typedef pythagoras<> type;
0283 };
0284 
0285 
0286 } // namespace services
0287 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0288 
0289 
0290 }} // namespace strategy::distance
0291 
0292 
0293 }} // namespace boost::geometry
0294 
0295 
0296 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP