Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:28

0001 // Boost.Geometry Index
0002 //
0003 // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
0004 //
0005 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
0006 //
0007 // This file was modified by Oracle on 2020-2023.
0008 // Modifications copyright (c) 2020-2023, Oracle and/or its affiliates.
0009 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0010 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0011 //
0012 // Use, modification and distribution is subject to the Boost Software License,
0013 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0014 // http://www.boost.org/LICENSE_1_0.txt)
0015 
0016 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
0017 #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
0018 
0019 #include <boost/geometry/core/access.hpp>
0020 #include <boost/geometry/core/coordinate_dimension.hpp>
0021 #include <boost/geometry/core/coordinate_type.hpp>
0022 #include <boost/geometry/core/static_assert.hpp>
0023 #include <boost/geometry/core/tag.hpp>
0024 #include <boost/geometry/core/tags.hpp>
0025 #include <boost/geometry/util/select_most_precise.hpp>
0026 
0027 // WARNING! comparable_margin() will work only if the same Geometries are compared
0028 // so it shouldn't be used in the case of Variants!
0029 
0030 namespace boost { namespace geometry { namespace index { namespace detail {
0031 
0032 template <typename Box>
0033 struct default_margin_result
0034 {
0035     using type = typename select_most_precise
0036         <
0037             typename coordinate_type<Box>::type,
0038             double
0039         >::type;
0040 };
0041 
0042 //template <typename Box,
0043 //          std::size_t CurrentDimension,
0044 //          std::size_t EdgeDimension = dimension<Box>::value>
0045 //struct margin_for_each_edge
0046 //{
0047 //    BOOST_STATIC_ASSERT(0 < CurrentDimension);
0048 //    BOOST_STATIC_ASSERT(0 < EdgeDimension);
0049 //
0050 //    static inline typename default_margin_result<Box>::type apply(Box const& b)
0051 //    {
0052 //        return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
0053 //            ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
0054 //    }
0055 //};
0056 //
0057 //template <typename Box, std::size_t CurrentDimension>
0058 //struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
0059 //{
0060 //    BOOST_STATIC_ASSERT(0 < CurrentDimension);
0061 //
0062 //    static inline typename default_margin_result<Box>::type apply(Box const& b)
0063 //    {
0064 //        return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
0065 //    }
0066 //};
0067 //
0068 //template <typename Box, std::size_t CurrentDimension>
0069 //struct margin_for_each_edge<Box, CurrentDimension, 1>
0070 //{
0071 //    BOOST_STATIC_ASSERT(0 < CurrentDimension);
0072 //
0073 //    static inline typename default_margin_result<Box>::type apply(Box const& b)
0074 //    {
0075 //        return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
0076 //    }
0077 //};
0078 //
0079 //template <typename Box>
0080 //struct margin_for_each_edge<Box, 1, 1>
0081 //{
0082 //    static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
0083 //    {
0084 //        return 1;
0085 //    }
0086 //};
0087 //
0088 //template <typename Box,
0089 //          std::size_t CurrentDimension = dimension<Box>::value>
0090 //struct margin_for_each_dimension
0091 //{
0092 //    BOOST_STATIC_ASSERT(0 < CurrentDimension);
0093 //
0094 //    static inline typename default_margin_result<Box>::type apply(Box const& b)
0095 //    {
0096 //        return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
0097 //            margin_for_each_edge<Box, CurrentDimension>::apply(b);
0098 //    }
0099 //};
0100 //
0101 //template <typename Box>
0102 //struct margin_for_each_dimension<Box, 1>
0103 //{
0104 //    static inline typename default_margin_result<Box>::type apply(Box const& b)
0105 //    {
0106 //        return margin_for_each_edge<Box, 1>::apply(b);
0107 //    }
0108 //};
0109 
0110 // TODO - test if this definition of margin is ok for Dimension > 2
0111 // Now it's sum of edges lengths
0112 // maybe margin_for_each_dimension should be used to get more or less hypersurface?
0113 
0114 template <typename Box,
0115           std::size_t CurrentDimension = dimension<Box>::value>
0116 struct simple_margin_for_each_dimension
0117 {
0118     BOOST_STATIC_ASSERT(0 < CurrentDimension);
0119 
0120     static inline typename default_margin_result<Box>::type apply(Box const& b)
0121     {
0122         return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
0123             geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
0124     }
0125 };
0126 
0127 template <typename Box>
0128 struct simple_margin_for_each_dimension<Box, 1>
0129 {
0130     static inline typename default_margin_result<Box>::type apply(Box const& b)
0131     {
0132         return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
0133     }
0134 };
0135 
0136 namespace dispatch {
0137 
0138 template <typename Geometry, typename Tag>
0139 struct comparable_margin
0140 {
0141     BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
0142         "Not implemented for this Geometry type.",
0143         Geometry, Tag);
0144 };
0145 
0146 template <typename Geometry>
0147 struct comparable_margin<Geometry, point_tag>
0148 {
0149     typedef typename default_margin_result<Geometry>::type result_type;
0150 
0151     static inline result_type apply(Geometry const& ) { return 0; }
0152 };
0153 
0154 template <typename Box>
0155 struct comparable_margin<Box, box_tag>
0156 {
0157     typedef typename default_margin_result<Box>::type result_type;
0158 
0159     static inline result_type apply(Box const& g)
0160     {
0161         //return detail::margin_for_each_dimension<Box>::apply(g);
0162         return detail::simple_margin_for_each_dimension<Box>::apply(g);
0163     }
0164 };
0165 
0166 } // namespace dispatch
0167 
0168 template <typename Geometry>
0169 typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
0170 {
0171     return dispatch::comparable_margin<
0172         Geometry,
0173         typename tag<Geometry>::type
0174     >::apply(g);
0175 }
0176 
0177 //template <typename Box>
0178 //typename default_margin_result<Box>::type margin(Box const& b)
0179 //{
0180 //    return 2 * detail::margin_for_each_dimension<Box>::apply(b);
0181 //}
0182 
0183 }}}} // namespace boost::geometry::index::detail
0184 
0185 #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP