summaryrefslogtreecommitdiff
path: root/boost/geometry/index/detail/algorithms/margin.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/index/detail/algorithms/margin.hpp')
-rw-r--r--boost/geometry/index/detail/algorithms/margin.hpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/boost/geometry/index/detail/algorithms/margin.hpp b/boost/geometry/index/detail/algorithms/margin.hpp
new file mode 100644
index 0000000000..d4876600ac
--- /dev/null
+++ b/boost/geometry/index/detail/algorithms/margin.hpp
@@ -0,0 +1,169 @@
+// Boost.Geometry Index
+//
+// n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
+//
+// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
+
+// WARNING! comparable_margin() will work only if the same Geometries are compared
+// so it shouldn't be used in the case of Variants!
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+template <typename Box>
+struct default_margin_result
+{
+ typedef typename select_most_precise<
+ typename coordinate_type<Box>::type,
+ long double
+ >::type type;
+};
+
+//template <typename Box,
+// std::size_t CurrentDimension,
+// std::size_t EdgeDimension = dimension<Box>::value>
+//struct margin_for_each_edge
+//{
+// BOOST_STATIC_ASSERT(0 < CurrentDimension);
+// BOOST_STATIC_ASSERT(0 < EdgeDimension);
+//
+// static inline typename default_margin_result<Box>::type apply(Box const& b)
+// {
+// return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
+// ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
+// }
+//};
+//
+//template <typename Box, std::size_t CurrentDimension>
+//struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
+//{
+// BOOST_STATIC_ASSERT(0 < CurrentDimension);
+//
+// static inline typename default_margin_result<Box>::type apply(Box const& b)
+// {
+// return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
+// }
+//};
+//
+//template <typename Box, std::size_t CurrentDimension>
+//struct margin_for_each_edge<Box, CurrentDimension, 1>
+//{
+// BOOST_STATIC_ASSERT(0 < CurrentDimension);
+//
+// static inline typename default_margin_result<Box>::type apply(Box const& b)
+// {
+// return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
+// }
+//};
+//
+//template <typename Box>
+//struct margin_for_each_edge<Box, 1, 1>
+//{
+// static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
+// {
+// return 1;
+// }
+//};
+//
+//template <typename Box,
+// std::size_t CurrentDimension = dimension<Box>::value>
+//struct margin_for_each_dimension
+//{
+// BOOST_STATIC_ASSERT(0 < CurrentDimension);
+//
+// static inline typename default_margin_result<Box>::type apply(Box const& b)
+// {
+// return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
+// margin_for_each_edge<Box, CurrentDimension>::apply(b);
+// }
+//};
+//
+//template <typename Box>
+//struct margin_for_each_dimension<Box, 1>
+//{
+// static inline typename default_margin_result<Box>::type apply(Box const& b)
+// {
+// return margin_for_each_edge<Box, 1>::apply(b);
+// }
+//};
+
+// TODO - test if this definition of margin is ok for Dimension > 2
+// Now it's sum of edges lengths
+// maybe margin_for_each_dimension should be used to get more or less hypersurface?
+
+template <typename Box,
+ std::size_t CurrentDimension = dimension<Box>::value>
+struct simple_margin_for_each_dimension
+{
+ BOOST_STATIC_ASSERT(0 < CurrentDimension);
+
+ static inline typename default_margin_result<Box>::type apply(Box const& b)
+ {
+ return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
+ geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
+ }
+};
+
+template <typename Box>
+struct simple_margin_for_each_dimension<Box, 1>
+{
+ static inline typename default_margin_result<Box>::type apply(Box const& b)
+ {
+ return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
+ }
+};
+
+namespace dispatch {
+
+template <typename Geometry, typename Tag>
+struct comparable_margin
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
+};
+
+template <typename Geometry>
+struct comparable_margin<Geometry, point_tag>
+{
+ typedef typename default_margin_result<Geometry>::type result_type;
+
+ static inline result_type apply(Geometry const& ) { return 0; }
+};
+
+template <typename Box>
+struct comparable_margin<Box, box_tag>
+{
+ typedef typename default_margin_result<Box>::type result_type;
+
+ static inline result_type apply(Box const& g)
+ {
+ //return detail::margin_for_each_dimension<Box>::apply(g);
+ return detail::simple_margin_for_each_dimension<Box>::apply(g);
+ }
+};
+
+} // namespace dispatch
+
+template <typename Geometry>
+typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
+{
+ return dispatch::comparable_margin<
+ Geometry,
+ typename tag<Geometry>::type
+ >::apply(g);
+}
+
+//template <typename Box>
+//typename default_margin_result<Box>::type margin(Box const& b)
+//{
+// return 2 * detail::margin_for_each_dimension<Box>::apply(b);
+//}
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP