1 // Boost.Geometry Index
2 //
3 // squared distance between point and centroid of the box or point
4 //
5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
6 //
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP
13 
14 #include <boost/geometry/index/detail/algorithms/sum_for_indexable.hpp>
15 #include <boost/geometry/index/detail/algorithms/diff_abs.hpp>
16 
17 namespace boost { namespace geometry { namespace index { namespace detail {
18 
19 struct comparable_distance_centroid_tag {};
20 
21 template <
22     typename Point,
23     typename PointIndexable,
24     size_t N>
25 struct sum_for_indexable<Point, PointIndexable, point_tag, comparable_distance_centroid_tag, N>
26 {
27     typedef typename geometry::default_comparable_distance_result<Point, PointIndexable>::type result_type;
28 
applyboost::geometry::index::detail::sum_for_indexable29     inline static result_type apply(Point const& pt, PointIndexable const& i)
30     {
31         return geometry::comparable_distance(pt, i);
32     }
33 };
34 
35 template <
36     typename Point,
37     typename BoxIndexable,
38     size_t DimensionIndex>
39 struct sum_for_indexable_dimension<Point, BoxIndexable, box_tag, comparable_distance_centroid_tag, DimensionIndex>
40 {
41     typedef typename geometry::default_comparable_distance_result<Point, BoxIndexable>::type result_type;
42 
applyboost::geometry::index::detail::sum_for_indexable_dimension43     inline static result_type apply(Point const& pt, BoxIndexable const& i)
44     {
45         typedef typename coordinate_type<Point>::type point_coord_t;
46         typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
47 
48         point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
49         indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
50         indexable_coord_t ind_c_max = geometry::get<geometry::max_corner, DimensionIndex>(i);
51 
52         indexable_coord_t ind_c_avg = ind_c_min + (ind_c_max - ind_c_min) / 2;
53         // TODO: awulkiew - is (ind_c_min + ind_c_max) / 2 safe?
54 
55         result_type diff = detail::diff_abs(ind_c_avg, pt_c);
56 
57         return diff * diff;
58     }
59 };
60 
61 template <typename Point, typename Indexable>
62 typename geometry::default_comparable_distance_result<Point, Indexable>::type
comparable_distance_centroid(Point const & pt,Indexable const & i)63 comparable_distance_centroid(Point const& pt, Indexable const& i)
64 {
65     return detail::sum_for_indexable<
66         Point,
67         Indexable,
68         typename tag<Indexable>::type,
69         detail::comparable_distance_centroid_tag,
70         dimension<Indexable>::value
71     >::apply(pt, i);
72 }
73 
74 }}}} // namespace boost::geometry::index::detail
75 
76 #endif // #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP
77 
78