// 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 struct default_margin_result { typedef typename select_most_precise< typename coordinate_type::type, long double >::type type; }; //template ::value> //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); // BOOST_STATIC_ASSERT(0 < EdgeDimension); // // static inline typename default_margin_result::type apply(Box const& b) // { // return margin_for_each_edge::apply(b) * // ( geometry::get(b) - geometry::get(b) ); // } //}; // //template //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); // // static inline typename default_margin_result::type apply(Box const& b) // { // return margin_for_each_edge::apply(b); // } //}; // //template //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); // // static inline typename default_margin_result::type apply(Box const& b) // { // return geometry::get(b) - geometry::get(b); // } //}; // //template //struct margin_for_each_edge //{ // static inline typename default_margin_result::type apply(Box const& /*b*/) // { // return 1; // } //}; // //template ::value> //struct margin_for_each_dimension //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); // // static inline typename default_margin_result::type apply(Box const& b) // { // return margin_for_each_dimension::apply(b) + // margin_for_each_edge::apply(b); // } //}; // //template //struct margin_for_each_dimension //{ // static inline typename default_margin_result::type apply(Box const& b) // { // return margin_for_each_edge::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 ::value> struct simple_margin_for_each_dimension { BOOST_STATIC_ASSERT(0 < CurrentDimension); static inline typename default_margin_result::type apply(Box const& b) { return simple_margin_for_each_dimension::apply(b) + geometry::get(b) - geometry::get(b); } }; template struct simple_margin_for_each_dimension { static inline typename default_margin_result::type apply(Box const& b) { return geometry::get(b) - geometry::get(b); } }; namespace dispatch { template struct comparable_margin { BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag)); }; template struct comparable_margin { typedef typename default_margin_result::type result_type; static inline result_type apply(Geometry const& ) { return 0; } }; template struct comparable_margin { typedef typename default_margin_result::type result_type; static inline result_type apply(Box const& g) { //return detail::margin_for_each_dimension::apply(g); return detail::simple_margin_for_each_dimension::apply(g); } }; } // namespace dispatch template typename default_margin_result::type comparable_margin(Geometry const& g) { return dispatch::comparable_margin< Geometry, typename tag::type >::apply(g); } //template //typename default_margin_result::type margin(Box const& b) //{ // return 2 * detail::margin_for_each_dimension::apply(b); //} }}}} // namespace boost::geometry::index::detail #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP