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