Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:43

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/math.hpp>
0030 #include <boost/geometry/util/calculation_type.hpp>
0031 
0032 
0033 namespace boost { namespace geometry
0034 {
0035 
0036 namespace strategy { namespace distance
0037 {
0038 
0039 #ifndef DOXYGEN_NO_DETAIL
0040 namespace detail
0041 {
0042 
0043 template <size_t I, typename T>
0044 struct compute_pythagoras
0045 {
0046     template <typename Point1, typename Point2>
0047     static inline T apply(Point1 const& p1, Point2 const& p2)
0048     {
0049         T const c1 = boost::numeric_cast<T>(get<I-1>(p1));
0050         T const c2 = boost::numeric_cast<T>(get<I-1>(p2));
0051         T const d = c1 - c2;
0052         return d * d + compute_pythagoras<I-1, T>::apply(p1, p2);
0053     }
0054 };
0055 
0056 template <typename T>
0057 struct compute_pythagoras<0, T>
0058 {
0059     template <typename Point1, typename Point2>
0060     static inline T apply(Point1 const&, Point2 const&)
0061     {
0062         return boost::numeric_cast<T>(0);
0063     }
0064 };
0065 
0066 }
0067 #endif // DOXYGEN_NO_DETAIL
0068 
0069 
0070 namespace comparable
0071 {
0072 
0073 /*!
0074 \brief Strategy to calculate comparable distance between two points
0075 \ingroup strategies
0076 \tparam Point1 \tparam_first_point
0077 \tparam Point2 \tparam_second_point
0078 \tparam CalculationType \tparam_calculation
0079 */
0080 template <typename CalculationType = void>
0081 class pythagoras
0082 {
0083 public :
0084 
0085     template <typename Point1, typename Point2>
0086     struct calculation_type
0087         : util::calculation_type::geometric::binary
0088           <
0089               Point1,
0090               Point2,
0091               CalculationType,
0092               double,
0093               double
0094           >
0095     {};
0096 
0097     template <typename Point1, typename Point2>
0098     static inline typename calculation_type<Point1, Point2>::type
0099     apply(Point1 const& p1, Point2 const& p2)
0100     {
0101         BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point1>) );
0102         BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point2>) );
0103 
0104         // Calculate distance using Pythagoras
0105         // (Leave comment above for Doxygen)
0106 
0107         assert_dimension_equal<Point1, Point2>();
0108 
0109         return detail::compute_pythagoras
0110             <
0111                 dimension<Point1>::value,
0112                 typename calculation_type<Point1, Point2>::type
0113             >::apply(p1, p2);
0114     }
0115 };
0116 
0117 } // namespace comparable
0118 
0119 
0120 /*!
0121 \brief Strategy to calculate the distance between two points
0122 \ingroup strategies
0123 \tparam CalculationType \tparam_calculation
0124 
0125 \qbk{
0126 [heading Notes]
0127 [note Can be used for points with two\, three or more dimensions]
0128 [heading See also]
0129 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
0130 }
0131 
0132 */
0133 template
0134 <
0135     typename CalculationType = void
0136 >
0137 class pythagoras
0138 {
0139 public :
0140 
0141     template <typename P1, typename P2>
0142     struct calculation_type
0143         : util::calculation_type::geometric::binary
0144           <
0145               P1,
0146               P2,
0147               CalculationType,
0148               double,
0149               double // promote integer to double
0150           >
0151     {};
0152 
0153     /*!
0154     \brief applies the distance calculation using pythagoras
0155     \return the calculated distance (including taking the square root)
0156     \param p1 first point
0157     \param p2 second point
0158     */
0159     template <typename P1, typename P2>
0160     static inline typename calculation_type<P1, P2>::type
0161     apply(P1 const& p1, P2 const& p2)
0162     {
0163         // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
0164         return math::sqrt
0165             (
0166                  boost::numeric_cast<typename calculation_type<P1, P2>::type>
0167                     (
0168                         comparable::pythagoras<CalculationType>::apply(p1, p2)
0169                     )
0170             );
0171     }
0172 };
0173 
0174 
0175 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0176 namespace services
0177 {
0178 
0179 template <typename CalculationType>
0180 struct tag<pythagoras<CalculationType> >
0181 {
0182     typedef strategy_tag_distance_point_point type;
0183 };
0184 
0185 
0186 template <typename CalculationType, typename P1, typename P2>
0187 struct return_type<distance::pythagoras<CalculationType>, P1, P2>
0188     : pythagoras<CalculationType>::template calculation_type<P1, P2>
0189 {};
0190 
0191 
0192 template <typename CalculationType>
0193 struct comparable_type<pythagoras<CalculationType> >
0194 {
0195     typedef comparable::pythagoras<CalculationType> type;
0196 };
0197 
0198 
0199 template <typename CalculationType>
0200 struct get_comparable<pythagoras<CalculationType> >
0201 {
0202     typedef comparable::pythagoras<CalculationType> comparable_type;
0203 public :
0204     static inline comparable_type apply(pythagoras<CalculationType> const& )
0205     {
0206         return comparable_type();
0207     }
0208 };
0209 
0210 
0211 template <typename CalculationType, typename Point1, typename Point2>
0212 struct result_from_distance<pythagoras<CalculationType>, Point1, Point2>
0213 {
0214 private :
0215     typedef typename return_type<pythagoras<CalculationType>, Point1, Point2>::type return_type;
0216 public :
0217     template <typename T>
0218     static inline return_type apply(pythagoras<CalculationType> const& , T const& value)
0219     {
0220         return return_type(value);
0221     }
0222 };
0223 
0224 
0225 // Specializations for comparable::pythagoras
0226 template <typename CalculationType>
0227 struct tag<comparable::pythagoras<CalculationType> >
0228 {
0229     typedef strategy_tag_distance_point_point type;
0230 };
0231 
0232 
0233 template <typename CalculationType, typename P1, typename P2>
0234 struct return_type<comparable::pythagoras<CalculationType>, P1, P2>
0235     : comparable::pythagoras<CalculationType>::template calculation_type<P1, P2>
0236 {};
0237 
0238 
0239 
0240 
0241 template <typename CalculationType>
0242 struct comparable_type<comparable::pythagoras<CalculationType> >
0243 {
0244     typedef comparable::pythagoras<CalculationType> type;
0245 };
0246 
0247 
0248 template <typename CalculationType>
0249 struct get_comparable<comparable::pythagoras<CalculationType> >
0250 {
0251     typedef comparable::pythagoras<CalculationType> comparable_type;
0252 public :
0253     static inline comparable_type apply(comparable::pythagoras<CalculationType> const& )
0254     {
0255         return comparable_type();
0256     }
0257 };
0258 
0259 
0260 template <typename CalculationType, typename Point1, typename Point2>
0261 struct result_from_distance<comparable::pythagoras<CalculationType>, Point1, Point2>
0262 {
0263 private :
0264     typedef typename return_type<comparable::pythagoras<CalculationType>, Point1, Point2>::type return_type;
0265 public :
0266     template <typename T>
0267     static inline return_type apply(comparable::pythagoras<CalculationType> const& , T const& value)
0268     {
0269         return_type const v = value;
0270         return v * v;
0271     }
0272 };
0273 
0274 
0275 template <typename Point1, typename Point2>
0276 struct default_strategy
0277     <
0278         point_tag, point_tag, Point1, Point2, cartesian_tag, cartesian_tag
0279     >
0280 {
0281     typedef pythagoras<> type;
0282 };
0283 
0284 
0285 } // namespace services
0286 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0287 
0288 
0289 }} // namespace strategy::distance
0290 
0291 
0292 }} // namespace boost::geometry
0293 
0294 
0295 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP