File indexing completed on 2025-09-13 08:35:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_EXPAND_BY_EPSILON_HPP
0012 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_EXPAND_BY_EPSILON_HPP
0013
0014 #include <algorithm>
0015 #include <cstddef>
0016 #include <type_traits>
0017
0018 #include <boost/geometry/core/access.hpp>
0019 #include <boost/geometry/core/coordinate_dimension.hpp>
0020 #include <boost/geometry/core/coordinate_type.hpp>
0021
0022 #include <boost/geometry/util/math.hpp>
0023
0024 #include <boost/geometry/views/detail/indexed_point_view.hpp>
0025
0026 namespace boost { namespace geometry
0027 {
0028
0029 #ifndef DOXYGEN_NO_DETAIL
0030 namespace detail { namespace expand
0031 {
0032
0033 template
0034 <
0035 typename Point,
0036 template <typename> class PlusOrMinus,
0037 std::size_t I = 0,
0038 std::size_t D = dimension<Point>::value
0039 >
0040 struct corner_by_epsilon
0041 {
0042 static inline void apply(Point & point)
0043 {
0044 using coord_type = coordinate_type_t<Point>;
0045 coord_type const coord = get<I>(point);
0046 coord_type const seps = math::scaled_epsilon(coord);
0047
0048 set<I>(point, PlusOrMinus<coord_type>()(coord, seps));
0049
0050 corner_by_epsilon<Point, PlusOrMinus, I+1>::apply(point);
0051 }
0052
0053 static inline void apply(Point & point,
0054 coordinate_type_t<Point> const& eps)
0055 {
0056 using coord_type = coordinate_type_t<Point>;
0057 coord_type const coord = get<I>(point);
0058 coord_type const seps = math::scaled_epsilon(coord, eps);
0059
0060 set<I>(point, PlusOrMinus<coord_type>()(coord, seps));
0061
0062 corner_by_epsilon<Point, PlusOrMinus, I + 1>::apply(point);
0063 }
0064 };
0065
0066 template
0067 <
0068 typename Point,
0069 template <typename> class PlusOrMinus,
0070 std::size_t D
0071 >
0072 struct corner_by_epsilon<Point, PlusOrMinus, D, D>
0073 {
0074 static inline void apply(Point const&) {}
0075 static inline void apply(Point const&, coordinate_type_t<Point> const&) {}
0076 };
0077
0078 template
0079 <
0080 typename Box,
0081 bool Enable = ! std::is_integral<coordinate_type_t<Box>>::value
0082 >
0083 struct expand_by_epsilon
0084 {
0085 static inline void apply(Box & box)
0086 {
0087 typedef detail::indexed_point_view<Box, min_corner> min_type;
0088 min_type min_point(box);
0089 corner_by_epsilon<min_type, std::minus>::apply(min_point);
0090
0091 typedef detail::indexed_point_view<Box, max_corner> max_type;
0092 max_type max_point(box);
0093 corner_by_epsilon<max_type, std::plus>::apply(max_point);
0094 }
0095
0096 static inline void apply(Box & box,
0097 coordinate_type_t<Box> const& eps)
0098 {
0099 typedef detail::indexed_point_view<Box, min_corner> min_type;
0100 min_type min_point(box);
0101 corner_by_epsilon<min_type, std::minus>::apply(min_point, eps);
0102
0103 typedef detail::indexed_point_view<Box, max_corner> max_type;
0104 max_type max_point(box);
0105 corner_by_epsilon<max_type, std::plus>::apply(max_point, eps);
0106 }
0107 };
0108
0109 template <typename Box>
0110 struct expand_by_epsilon<Box, false>
0111 {
0112 static inline void apply(Box &) {}
0113 static inline void apply(Box &, coordinate_type_t<Box> const&) {}
0114 };
0115
0116 }
0117
0118 template <typename Box>
0119 inline void expand_by_epsilon(Box & box)
0120 {
0121 expand::expand_by_epsilon<Box>::apply(box);
0122 }
0123
0124 template <typename Box>
0125 inline void expand_by_epsilon(Box & box, coordinate_type_t<Box> const& eps)
0126 {
0127 expand::expand_by_epsilon<Box>::apply(box, eps);
0128 }
0129
0130 }
0131 #endif
0132
0133 }}
0134
0135 #endif