123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // Boost.Geometry Index
- //
- // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
- //
- // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
- //
- // This file was modified by Oracle on 2020-2023.
- // Modifications copyright (c) 2020-2023, Oracle and/or its affiliates.
- // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- //
- // 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
- #include <boost/geometry/core/access.hpp>
- #include <boost/geometry/core/coordinate_dimension.hpp>
- #include <boost/geometry/core/coordinate_type.hpp>
- #include <boost/geometry/core/static_assert.hpp>
- #include <boost/geometry/core/tag.hpp>
- #include <boost/geometry/core/tags.hpp>
- #include <boost/geometry/util/select_most_precise.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
- {
- using type = typename select_most_precise
- <
- typename coordinate_type<Box>::type,
- double
- >::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_GEOMETRY_STATIC_ASSERT_FALSE(
- "Not implemented for this Geometry type.",
- 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
|