Chris@16: // Boost.Geometry Index Chris@16: // Chris@16: // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc... Chris@16: // Chris@101: // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. Chris@16: // Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP Chris@16: #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP Chris@16: Chris@16: // WARNING! comparable_margin() will work only if the same Geometries are compared Chris@16: // so it shouldn't be used in the case of Variants! Chris@16: Chris@16: namespace boost { namespace geometry { namespace index { namespace detail { Chris@16: Chris@16: template Chris@16: struct default_margin_result Chris@16: { Chris@16: typedef typename select_most_precise< Chris@16: typename coordinate_type::type, Chris@16: long double Chris@16: >::type type; Chris@16: }; Chris@16: Chris@101: //template ::value> Chris@16: //struct margin_for_each_edge Chris@16: //{ Chris@16: // BOOST_STATIC_ASSERT(0 < CurrentDimension); Chris@16: // BOOST_STATIC_ASSERT(0 < EdgeDimension); Chris@16: // Chris@16: // static inline typename default_margin_result::type apply(Box const& b) Chris@16: // { Chris@16: // return margin_for_each_edge::apply(b) * Chris@16: // ( geometry::get(b) - geometry::get(b) ); Chris@16: // } Chris@16: //}; Chris@16: // Chris@101: //template Chris@16: //struct margin_for_each_edge Chris@16: //{ Chris@16: // BOOST_STATIC_ASSERT(0 < CurrentDimension); Chris@16: // Chris@16: // static inline typename default_margin_result::type apply(Box const& b) Chris@16: // { Chris@16: // return margin_for_each_edge::apply(b); Chris@16: // } Chris@16: //}; Chris@16: // Chris@101: //template Chris@16: //struct margin_for_each_edge Chris@16: //{ Chris@16: // BOOST_STATIC_ASSERT(0 < CurrentDimension); Chris@16: // Chris@16: // static inline typename default_margin_result::type apply(Box const& b) Chris@16: // { Chris@16: // return geometry::get(b) - geometry::get(b); Chris@16: // } Chris@16: //}; Chris@16: // Chris@16: //template Chris@16: //struct margin_for_each_edge Chris@16: //{ Chris@16: // static inline typename default_margin_result::type apply(Box const& /*b*/) Chris@16: // { Chris@16: // return 1; Chris@16: // } Chris@16: //}; Chris@16: // Chris@101: //template ::value> Chris@16: //struct margin_for_each_dimension Chris@16: //{ Chris@16: // BOOST_STATIC_ASSERT(0 < CurrentDimension); Chris@16: // Chris@16: // static inline typename default_margin_result::type apply(Box const& b) Chris@16: // { Chris@16: // return margin_for_each_dimension::apply(b) + Chris@101: // margin_for_each_edge::apply(b); Chris@16: // } Chris@16: //}; Chris@16: // Chris@16: //template Chris@16: //struct margin_for_each_dimension Chris@16: //{ Chris@16: // static inline typename default_margin_result::type apply(Box const& b) Chris@16: // { Chris@101: // return margin_for_each_edge::apply(b); Chris@16: // } Chris@16: //}; Chris@16: Chris@16: // TODO - test if this definition of margin is ok for Dimension > 2 Chris@16: // Now it's sum of edges lengths Chris@16: // maybe margin_for_each_dimension should be used to get more or less hypersurface? Chris@16: Chris@101: template ::value> Chris@16: struct simple_margin_for_each_dimension Chris@16: { Chris@16: BOOST_STATIC_ASSERT(0 < CurrentDimension); Chris@16: Chris@16: static inline typename default_margin_result::type apply(Box const& b) Chris@16: { Chris@16: return simple_margin_for_each_dimension::apply(b) + Chris@16: geometry::get(b) - geometry::get(b); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct simple_margin_for_each_dimension Chris@16: { Chris@16: static inline typename default_margin_result::type apply(Box const& b) Chris@16: { Chris@16: return geometry::get(b) - geometry::get(b); Chris@16: } Chris@16: }; Chris@16: Chris@16: namespace dispatch { Chris@16: Chris@16: template Chris@16: struct comparable_margin Chris@16: { Chris@16: BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag)); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct comparable_margin Chris@16: { Chris@16: typedef typename default_margin_result::type result_type; Chris@16: Chris@16: static inline result_type apply(Geometry const& ) { return 0; } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct comparable_margin Chris@16: { Chris@16: typedef typename default_margin_result::type result_type; Chris@16: Chris@16: static inline result_type apply(Box const& g) Chris@16: { Chris@101: //return detail::margin_for_each_dimension::apply(g); Chris@101: return detail::simple_margin_for_each_dimension::apply(g); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace dispatch Chris@16: Chris@16: template Chris@16: typename default_margin_result::type comparable_margin(Geometry const& g) Chris@16: { Chris@16: return dispatch::comparable_margin< Chris@16: Geometry, Chris@16: typename tag::type Chris@16: >::apply(g); Chris@16: } Chris@16: Chris@16: //template Chris@16: //typename default_margin_result::type margin(Box const& b) Chris@16: //{ Chris@101: // return 2 * detail::margin_for_each_dimension::apply(b); Chris@16: //} Chris@16: Chris@16: }}}} // namespace boost::geometry::index::detail Chris@16: Chris@16: #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP