File indexing completed on 2025-01-18 09:35:17
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 typedef typename coordinate_type<Point>::type coord_type;
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 typename coordinate_type<Point>::type const& eps)
0055 {
0056 typedef typename coordinate_type<Point>::type coord_type;
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&, typename coordinate_type<Point>::type const&) {}
0076 };
0077
0078 template
0079 <
0080 typename Box,
0081 bool Enable = ! std::is_integral<typename coordinate_type<Box>::type>::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 typename coordinate_type<Box>::type 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 &, typename coordinate_type<Box>::type 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,
0126 typename coordinate_type<Box>::type const& eps)
0127 {
0128 expand::expand_by_epsilon<Box>::apply(box, eps);
0129 }
0130
0131 }
0132 #endif
0133
0134 }}
0135
0136 #endif