1 // Boost.Geometry Index
3 // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
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)
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
14 // WARNING! comparable_margin() will work only if the same Geometries are compared
15 // so it shouldn't be used in the case of Variants!
17 namespace boost { namespace geometry { namespace index { namespace detail {
19 template <typename Box>
20 struct default_margin_result
22 typedef typename select_most_precise<
23 typename coordinate_type<Box>::type,
28 //template <typename Box,
29 // std::size_t CurrentDimension,
30 // std::size_t EdgeDimension = dimension<Box>::value>
31 //struct margin_for_each_edge
33 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
34 // BOOST_STATIC_ASSERT(0 < EdgeDimension);
36 // static inline typename default_margin_result<Box>::type apply(Box const& b)
38 // return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
39 // ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
43 //template <typename Box, std::size_t CurrentDimension>
44 //struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
46 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
48 // static inline typename default_margin_result<Box>::type apply(Box const& b)
50 // return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
54 //template <typename Box, std::size_t CurrentDimension>
55 //struct margin_for_each_edge<Box, CurrentDimension, 1>
57 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
59 // static inline typename default_margin_result<Box>::type apply(Box const& b)
61 // return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
65 //template <typename Box>
66 //struct margin_for_each_edge<Box, 1, 1>
68 // static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
74 //template <typename Box,
75 // std::size_t CurrentDimension = dimension<Box>::value>
76 //struct margin_for_each_dimension
78 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
80 // static inline typename default_margin_result<Box>::type apply(Box const& b)
82 // return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
83 // margin_for_each_edge<Box, CurrentDimension>::apply(b);
87 //template <typename Box>
88 //struct margin_for_each_dimension<Box, 1>
90 // static inline typename default_margin_result<Box>::type apply(Box const& b)
92 // return margin_for_each_edge<Box, 1>::apply(b);
96 // TODO - test if this definition of margin is ok for Dimension > 2
97 // Now it's sum of edges lengths
98 // maybe margin_for_each_dimension should be used to get more or less hypersurface?
100 template <typename Box,
101 std::size_t CurrentDimension = dimension<Box>::value>
102 struct simple_margin_for_each_dimension
104 BOOST_STATIC_ASSERT(0 < CurrentDimension);
106 static inline typename default_margin_result<Box>::type apply(Box const& b)
108 return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
109 geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
113 template <typename Box>
114 struct simple_margin_for_each_dimension<Box, 1>
116 static inline typename default_margin_result<Box>::type apply(Box const& b)
118 return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
124 template <typename Geometry, typename Tag>
125 struct comparable_margin
127 BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
130 template <typename Geometry>
131 struct comparable_margin<Geometry, point_tag>
133 typedef typename default_margin_result<Geometry>::type result_type;
135 static inline result_type apply(Geometry const& ) { return 0; }
138 template <typename Box>
139 struct comparable_margin<Box, box_tag>
141 typedef typename default_margin_result<Box>::type result_type;
143 static inline result_type apply(Box const& g)
145 //return detail::margin_for_each_dimension<Box>::apply(g);
146 return detail::simple_margin_for_each_dimension<Box>::apply(g);
150 } // namespace dispatch
152 template <typename Geometry>
153 typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
155 return dispatch::comparable_margin<
157 typename tag<Geometry>::type
161 //template <typename Box>
162 //typename default_margin_result<Box>::type margin(Box const& b)
164 // return 2 * detail::margin_for_each_dimension<Box>::apply(b);
167 }}}} // namespace boost::geometry::index::detail
169 #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP