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, 2018.
8 // Modifications copyright (c) 2014, 2018, Oracle and/or its affiliates.
10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
20 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_BOX_HPP
21 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_BOX_HPP
24 #include <boost/geometry/core/access.hpp>
25 #include <boost/geometry/core/point_type.hpp>
27 #include <boost/geometry/geometries/concepts/point_concept.hpp>
29 #include <boost/geometry/strategies/distance.hpp>
31 #include <boost/geometry/util/math.hpp>
32 #include <boost/geometry/util/calculation_type.hpp>
36 namespace boost { namespace geometry
39 namespace strategy { namespace distance
42 #ifndef DOXYGEN_NO_DETAIL
47 struct compute_pythagoras_point_box
49 template <typename Point, typename Box, typename T>
50 static inline void apply(Point const& point, Box const& box, T& result)
52 T const p_coord = boost::numeric_cast<T>(geometry::get<I-1>(point));
54 boost::numeric_cast<T>(geometry::get<min_corner, I-1>(box));
56 boost::numeric_cast<T>(geometry::get<max_corner, I-1>(box));
58 if ( p_coord < b_min_coord )
60 T diff = b_min_coord - p_coord;
61 result += diff * diff;
63 if ( p_coord > b_max_coord )
65 T diff = p_coord - b_max_coord;
66 result += diff * diff;
69 compute_pythagoras_point_box<I-1>::apply(point, box, result);
74 struct compute_pythagoras_point_box<0>
76 template <typename Point, typename Box, typename T>
77 static inline void apply(Point const&, Box const&, T&)
84 #endif // DOXYGEN_NO_DETAIL
91 \brief Strategy to calculate comparable distance between a point
94 \tparam Point \tparam_first_point
95 \tparam Box \tparam_second_box
96 \tparam CalculationType \tparam_calculation
98 template <typename CalculationType = void>
99 class pythagoras_point_box
103 template <typename Point, typename Box>
104 struct calculation_type
106 typedef typename util::calculation_type::geometric::binary
108 Point, Box, CalculationType
112 template <typename Point, typename Box>
113 static inline typename calculation_type<Point, Box>::type
114 apply(Point const& point, Box const& box)
116 BOOST_CONCEPT_ASSERT( (concepts::ConstPoint<Point>) );
118 ( (concepts::ConstPoint<typename point_type<Box>::type>) );
120 // Calculate distance using Pythagoras
121 // (Leave comment above for Doxygen)
123 assert_dimension_equal<Point, Box>();
125 typename calculation_type<Point, Box>::type result(0);
127 detail::compute_pythagoras_point_box
129 dimension<Point>::value
130 >::apply(point, box, result);
136 } // namespace comparable
140 \brief Strategy to calculate the distance between a point and a box
142 \tparam CalculationType \tparam_calculation
146 [note Can be used for points and boxes with two\, three or more dimensions]
148 [link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
154 typename CalculationType = void
156 class pythagoras_point_box
160 template <typename Point, typename Box>
161 struct calculation_type
162 : util::calculation_type::geometric::binary
168 double // promote integer to double
173 \brief applies the distance calculation using pythagoras
174 \return the calculated distance (including taking the square root)
178 template <typename Point, typename Box>
179 static inline typename calculation_type<Point, Box>::type
180 apply(Point const& point, Box const& box)
182 // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call
185 boost::numeric_cast<typename calculation_type
190 comparable::pythagoras_point_box
200 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
204 template <typename CalculationType>
205 struct tag<pythagoras_point_box<CalculationType> >
207 typedef strategy_tag_distance_point_box type;
211 template <typename CalculationType, typename Point, typename Box>
212 struct return_type<distance::pythagoras_point_box<CalculationType>, Point, Box>
213 : pythagoras_point_box
216 >::template calculation_type<Point, Box>
220 template <typename CalculationType>
221 struct comparable_type<pythagoras_point_box<CalculationType> >
223 typedef comparable::pythagoras_point_box<CalculationType> type;
227 template <typename CalculationType>
228 struct get_comparable<pythagoras_point_box<CalculationType> >
230 typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
232 static inline comparable_type
233 apply(pythagoras_point_box<CalculationType> const& )
235 return comparable_type();
240 template <typename CalculationType, typename Point, typename Box>
241 struct result_from_distance<pythagoras_point_box<CalculationType>, Point, Box>
244 typedef typename return_type
246 pythagoras_point_box<CalculationType>, Point, Box
249 template <typename T>
250 static inline return_type
251 apply(pythagoras_point_box<CalculationType> const& , T const& value)
253 return return_type(value);
258 // Specializations for comparable::pythagoras_point_box
259 template <typename CalculationType>
260 struct tag<comparable::pythagoras_point_box<CalculationType> >
262 typedef strategy_tag_distance_point_box type;
266 template <typename CalculationType, typename Point, typename Box>
269 comparable::pythagoras_point_box<CalculationType>, Point, Box
270 > : comparable::pythagoras_point_box
273 >::template calculation_type<Point, Box>
279 template <typename CalculationType>
280 struct comparable_type<comparable::pythagoras_point_box<CalculationType> >
282 typedef comparable::pythagoras_point_box<CalculationType> type;
286 template <typename CalculationType>
287 struct get_comparable<comparable::pythagoras_point_box<CalculationType> >
289 typedef comparable::pythagoras_point_box<CalculationType> comparable_type;
291 static inline comparable_type apply(comparable_type const& )
293 return comparable_type();
298 template <typename CalculationType, typename Point, typename Box>
299 struct result_from_distance
301 comparable::pythagoras_point_box<CalculationType>, Point, Box
305 typedef typename return_type
307 comparable::pythagoras_point_box<CalculationType>, Point, Box
310 template <typename T>
311 static inline return_type
312 apply(comparable::pythagoras_point_box<CalculationType> const& ,
315 return_type const v = value;
321 template <typename Point, typename BoxPoint>
322 struct default_strategy
324 point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
327 typedef pythagoras_point_box<> type;
330 template <typename BoxPoint, typename Point>
331 struct default_strategy
333 box_tag, point_tag, BoxPoint, Point, cartesian_tag, cartesian_tag
336 typedef typename default_strategy
338 point_tag, box_tag, Point, BoxPoint, cartesian_tag, cartesian_tag
343 } // namespace services
344 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
347 }} // namespace strategy::distance
350 }} // namespace boost::geometry
353 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_POINT_BOX_HPP