1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
4 // Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
7 // This file was modified by Oracle on 2014.
8 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
19 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP
20 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP
23 #include <boost/geometry/core/access.hpp>
25 #include <boost/geometry/strategies/distance.hpp>
27 #include <boost/geometry/util/math.hpp>
28 #include <boost/geometry/util/calculation_type.hpp>
33 namespace boost { namespace geometry
36 namespace strategy { namespace distance
39 #ifndef DOXYGEN_NO_DETAIL
43 template <std::size_t I>
44 struct compute_pythagoras_box_box
46 template <typename Box1, typename Box2, typename T>
47 static inline void apply(Box1 const& box1, Box2 const& box2, T& result)
49 T const b1_min_coord =
50 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box1));
51 T const b1_max_coord =
52 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box1));
54 T const b2_min_coord =
55 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box2));
56 T const b2_max_coord =
57 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box2));
59 if ( b1_max_coord < b2_min_coord )
61 T diff = b2_min_coord - b1_max_coord;
62 result += diff * diff;
64 if ( b1_min_coord > b2_max_coord )
66 T diff = b1_min_coord - b2_max_coord;
67 result += diff * diff;
70 compute_pythagoras_box_box<I-1>::apply(box1, box2, result);
75 struct compute_pythagoras_box_box<0>
77 template <typename Box1, typename Box2, typename T>
78 static inline void apply(Box1 const&, Box2 const&, T&)
84 #endif // DOXYGEN_NO_DETAIL
91 \brief Strategy to calculate comparable distance between two boxes
93 \tparam Box1 \tparam_first_box
94 \tparam Box2 \tparam_second_box
95 \tparam CalculationType \tparam_calculation
97 template <typename CalculationType = void>
98 class pythagoras_box_box
102 template <typename Box1, typename Box2>
103 struct calculation_type
105 typedef typename util::calculation_type::geometric::binary
113 template <typename Box1, typename Box2>
114 static inline typename calculation_type<Box1, Box2>::type
115 apply(Box1 const& box1, Box2 const& box2)
118 ( (concepts::ConstPoint<typename point_type<Box1>::type>) );
120 ( (concepts::ConstPoint<typename point_type<Box2>::type>) );
122 // Calculate distance using Pythagoras
123 // (Leave comment above for Doxygen)
125 assert_dimension_equal<Box1, Box2>();
127 typename calculation_type<Box1, Box2>::type result(0);
129 detail::compute_pythagoras_box_box
131 dimension<Box1>::value
132 >::apply(box1, box2, result);
138 } // namespace comparable
142 \brief Strategy to calculate the distance between two boxes
144 \tparam CalculationType \tparam_calculation
148 [note Can be used for boxes with two\, three or more dimensions]
150 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
156 typename CalculationType = void
158 class pythagoras_box_box
162 template <typename Box1, typename Box2>
163 struct calculation_type
164 : util::calculation_type::geometric::binary
170 double // promote integer to double
175 \brief applies the distance calculation using pythagoras_box_box
176 \return the calculated distance (including taking the square root)
177 \param box1 first box
178 \param box2 second box
180 template <typename Box1, typename Box2>
181 static inline typename calculation_type<Box1, Box2>::type
182 apply(Box1 const& box1, Box2 const& box2)
184 // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
187 boost::numeric_cast<typename calculation_type
192 comparable::pythagoras_box_box
202 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
206 template <typename CalculationType>
207 struct tag<pythagoras_box_box<CalculationType> >
209 typedef strategy_tag_distance_box_box type;
213 template <typename CalculationType, typename Box1, typename Box2>
214 struct return_type<distance::pythagoras_box_box<CalculationType>, Box1, Box2>
215 : pythagoras_box_box<CalculationType>::template calculation_type<Box1, Box2>
219 template <typename CalculationType>
220 struct comparable_type<pythagoras_box_box<CalculationType> >
222 typedef comparable::pythagoras_box_box<CalculationType> type;
226 template <typename CalculationType>
227 struct get_comparable<pythagoras_box_box<CalculationType> >
229 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
231 static inline comparable_type
232 apply(pythagoras_box_box<CalculationType> const& )
234 return comparable_type();
239 template <typename CalculationType, typename Box1, typename Box2>
240 struct result_from_distance<pythagoras_box_box<CalculationType>, Box1, Box2>
243 typedef typename return_type
245 pythagoras_box_box<CalculationType>, Box1, Box2
248 template <typename T>
249 static inline return_type
250 apply(pythagoras_box_box<CalculationType> const& , T const& value)
252 return return_type(value);
257 // Specializations for comparable::pythagoras_box_box
258 template <typename CalculationType>
259 struct tag<comparable::pythagoras_box_box<CalculationType> >
261 typedef strategy_tag_distance_box_box type;
265 template <typename CalculationType, typename Box1, typename Box2>
266 struct return_type<comparable::pythagoras_box_box<CalculationType>, Box1, Box2>
267 : comparable::pythagoras_box_box
270 >::template calculation_type<Box1, Box2>
276 template <typename CalculationType>
277 struct comparable_type<comparable::pythagoras_box_box<CalculationType> >
279 typedef comparable::pythagoras_box_box<CalculationType> type;
283 template <typename CalculationType>
284 struct get_comparable<comparable::pythagoras_box_box<CalculationType> >
286 typedef comparable::pythagoras_box_box<CalculationType> comparable_type;
288 static inline comparable_type apply(comparable_type const& )
290 return comparable_type();
295 template <typename CalculationType, typename Box1, typename Box2>
296 struct result_from_distance
298 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
302 typedef typename return_type
304 comparable::pythagoras_box_box<CalculationType>, Box1, Box2
307 template <typename T>
308 static inline return_type
309 apply(comparable::pythagoras_box_box<CalculationType> const&,
312 return_type const v = value;
318 template <typename BoxPoint1, typename BoxPoint2>
319 struct default_strategy
321 box_tag, box_tag, BoxPoint1, BoxPoint2, cartesian_tag, cartesian_tag
324 typedef pythagoras_box_box<> type;
328 } // namespace services
329 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
332 }} // namespace strategy::distance
335 }} // namespace boost::geometry
338 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_BOX_BOX_HPP