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_POINT_BOX_HPP
0021 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_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 <size_t I>
0047 struct compute_pythagoras_point_box
0048 {
0049     template <typename Point, typename Box, typename T>
0050     static inline void apply(Point const& point, Box const& box, T& result)
0051     {
0052         T const p_coord = boost::numeric_cast<T>(geometry::get<I-1>(point));
0053         T const b_min_coord =
0054             boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box));
0055         T const b_max_coord =
0056             boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box));
0057 
0058         if ( p_coord < b_min_coord )
0059         {
0060             T diff = b_min_coord - p_coord;
0061             result += diff * diff;
0062         }
0063         if ( p_coord > b_max_coord )
0064         {
0065             T diff = p_coord - b_max_coord;
0066             result += diff * diff;
0067         }
0068 
0069         compute_pythagoras_point_box<I-1>::apply(point, box, result);
0070     }
0071 };
0072 
0073 template <>
0074 struct compute_pythagoras_point_box<0>
0075 {
0076     template <typename Point, typename Box, typename T>
0077     static inline void apply(Point const&, Box const&, T&)
0078     {
0079     }
0080 };
0081 
0082 
0083 } // namespace detail
0084 #endif // DOXYGEN_NO_DETAIL
0085 
0086 
0087 namespace comparable
0088 {
0089 
0090 /*!
0091     \brief Strategy to calculate comparable distance between a point
0092     and a box
0093     \ingroup strategies
0094     \tparam Point \tparam_first_point
0095     \tparam Box \tparam_second_box
0096     \tparam CalculationType \tparam_calculation
0097 */
0098 template <typename CalculationType = void>
0099 class pythagoras_point_box
0100 {
0101 public :
0102 
0103     template <typename Point, typename Box>
0104     struct calculation_type
0105     {
0106         typedef typename util::calculation_type::geometric::binary
0107             <
0108                 Point, Box, CalculationType
0109             >::type type;
0110     };
0111 
0112     template <typename Point, typename Box>
0113     static inline typename calculation_type<Point, Box>::type
0114     apply(Point const& point, Box const& box)
0115     {
0116         BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point>) );
0117         BOOST_CONCEPT_ASSERT
0118             ( (concepts::ConstPoint<typename point_type<Box>::type>) );
0119 
0120         // Calculate distance using Pythagoras
0121         // (Leave comment above for Doxygen)
0122 
0123         assert_dimension_equal<Point, Box>();
0124 
0125         typename calculation_type<Point, Box>::type result(0);
0126 
0127         detail::compute_pythagoras_point_box
0128             <
0129                 dimension<Point>::value
0130             >::apply(point, box, result);
0131 
0132         return result;
0133     }
0134 };
0135 
0136 } // namespace comparable
0137 
0138 
0139 /*!
0140 \brief Strategy to calculate the distance between a point and a box
0141 \ingroup strategies
0142 \tparam CalculationType \tparam_calculation
0143 
0144 \qbk{
0145 [heading Notes]
0146 [note Can be used for points and boxes with two\, three or more dimensions]
0147 [heading See also]
0148 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
0149 }
0150 
0151 */
0152 template
0153 <
0154     typename CalculationType = void
0155 >
0156 class pythagoras_point_box
0157 {
0158 public :
0159 
0160     template <typename Point, typename Box>
0161     struct calculation_type
0162         : util::calculation_type::geometric::binary
0163           <
0164               Point,
0165               Box,
0166               CalculationType,
0167               double,
0168               double // promote integer to double
0169           >
0170     {};
0171 
0172     /*!
0173     \brief applies the distance calculation using pythagoras
0174     \return the calculated distance (including taking the square root)
0175     \param point point
0176     \param box box
0177     */
0178     template <typename Point, typename Box>
0179     static inline typename calculation_type<Point, Box>::type
0180     apply(Point const& point, Box const& box)
0181     {
0182         // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
0183         return math::sqrt
0184             (
0185                  boost::numeric_cast<typename calculation_type
0186                      <
0187                          Point, Box
0188                      >::type>
0189                     (
0190                         comparable::pythagoras_point_box
0191                             <
0192                                 CalculationType
0193                             >::apply(point, box)
0194                     )
0195             );
0196     }
0197 };
0198 
0199 
0200 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0201 namespace services
0202 {
0203 
0204 template <typename CalculationType>
0205 struct tag<pythagoras_point_box<CalculationType> >
0206 {
0207     typedef strategy_tag_distance_point_box type;
0208 };
0209 
0210 
0211 template <typename CalculationType, typename Point, typename Box>
0212 struct return_type<distance::pythagoras_point_box<CalculationType>, Point, Box>
0213     : pythagoras_point_box
0214         <
0215             CalculationType
0216         >::template calculation_type<Point, Box>
0217 {};
0218 
0219 
0220 template <typename CalculationType>
0221 struct comparable_type<pythagoras_point_box<CalculationType> >
0222 {
0223     typedef comparable::pythagoras_point_box<CalculationType> type;
0224 };
0225 
0226 
0227 template <typename CalculationType>
0228 struct get_comparable<pythagoras_point_box<CalculationType> >
0229 {
0230     typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
0231 public :
0232     static inline comparable_type
0233     apply(pythagoras_point_box<CalculationType> const& )
0234     {
0235         return comparable_type();
0236     }
0237 };
0238 
0239 
0240 template <typename CalculationType, typename Point, typename Box>
0241 struct result_from_distance<pythagoras_point_box<CalculationType>, Point, Box>
0242 {
0243 private :
0244     typedef typename return_type
0245         <
0246             pythagoras_point_box<CalculationType>, Point, Box
0247         >::type return_type;
0248 public :
0249     template <typename T>
0250     static inline return_type
0251     apply(pythagoras_point_box<CalculationType> const& , T const& value)
0252     {
0253         return return_type(value);
0254     }
0255 };
0256 
0257 
0258 // Specializations for comparable::pythagoras_point_box
0259 template <typename CalculationType>
0260 struct tag<comparable::pythagoras_point_box<CalculationType> >
0261 {
0262     typedef strategy_tag_distance_point_box type;
0263 };
0264 
0265 
0266 template <typename CalculationType, typename Point, typename Box>
0267 struct return_type
0268     <
0269         comparable::pythagoras_point_box<CalculationType>, Point, Box
0270     > : comparable::pythagoras_point_box
0271         <
0272             CalculationType
0273         >::template calculation_type<Point, Box>
0274 {};
0275 
0276 
0277 
0278 
0279 template <typename CalculationType>
0280 struct comparable_type<comparable::pythagoras_point_box<CalculationType> >
0281 {
0282     typedef comparable::pythagoras_point_box<CalculationType> type;
0283 };
0284 
0285 
0286 template <typename CalculationType>
0287 struct get_comparable<comparable::pythagoras_point_box<CalculationType> >
0288 {
0289     typedef comparable::pythagoras_point_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 Point, typename Box>
0299 struct result_from_distance
0300     <
0301         comparable::pythagoras_point_box<CalculationType>, Point, Box
0302     >
0303 {
0304 private :
0305     typedef typename return_type
0306         <
0307             comparable::pythagoras_point_box<CalculationType>, Point, Box
0308         >::type return_type;
0309 public :
0310     template <typename T>
0311     static inline return_type
0312     apply(comparable::pythagoras_point_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 Point, typename BoxPoint>
0322 struct default_strategy
0323     <
0324         point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
0325     >
0326 {
0327     typedef pythagoras_point_box<> type;
0328 };
0329 
0330 template <typename BoxPoint, typename Point>
0331 struct default_strategy
0332     <
0333         box_tag, point_tag, BoxPoint, Point, cartesian_tag, cartesian_tag
0334     >
0335 {
0336     typedef typename default_strategy
0337         <
0338             point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
0339         >::type type;
0340 };
0341 
0342 
0343 } // namespace services
0344 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0345 
0346 
0347 }} // namespace strategy::distance
0348 
0349 
0350 }} // namespace boost::geometry
0351 
0352 
0353 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_BOX_HPP