Mercurial > hg > vamp-build-and-test
view DEPENDENCIES/generic/include/boost/geometry/index/detail/algorithms/margin.hpp @ 60:01e6213c3f91
Merge
author | Chris Cannam |
---|---|
date | Fri, 12 Sep 2014 08:17:00 +0100 |
parents | 2665513ce2d3 |
children | c530137014c0 |
line wrap: on
line source
// Boost.Geometry Index // // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc... // // Copyright (c) 2011-2013 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, size_t CurrentDimension, size_t EdgeDimension> //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, 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, 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, size_t CurrentDimension> //struct margin_for_each_dimension //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); // BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value); // // 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, detail::traits::dimension<Box>::value>::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, detail::traits::dimension<Box>::value>::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, size_t CurrentDimension> struct simple_margin_for_each_dimension { BOOST_STATIC_ASSERT(0 < CurrentDimension); //BOOST_STATIC_ASSERT(CurrentDimension <= dimension<Box>::value); 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, dimension<Box>::value>::apply(g); return detail::simple_margin_for_each_dimension<Box, dimension<Box>::value>::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, dimension<Box>::value>::apply(b); //} }}}} // namespace boost::geometry::index::detail #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP