Chris@16
|
1 // Boost.Geometry Index
|
Chris@16
|
2 //
|
Chris@16
|
3 // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc...
|
Chris@16
|
4 //
|
Chris@101
|
5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
|
Chris@16
|
6 //
|
Chris@16
|
7 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
9 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
|
Chris@16
|
12 #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
|
Chris@16
|
13
|
Chris@16
|
14 // WARNING! comparable_margin() will work only if the same Geometries are compared
|
Chris@16
|
15 // so it shouldn't be used in the case of Variants!
|
Chris@16
|
16
|
Chris@16
|
17 namespace boost { namespace geometry { namespace index { namespace detail {
|
Chris@16
|
18
|
Chris@16
|
19 template <typename Box>
|
Chris@16
|
20 struct default_margin_result
|
Chris@16
|
21 {
|
Chris@16
|
22 typedef typename select_most_precise<
|
Chris@16
|
23 typename coordinate_type<Box>::type,
|
Chris@16
|
24 long double
|
Chris@16
|
25 >::type type;
|
Chris@16
|
26 };
|
Chris@16
|
27
|
Chris@101
|
28 //template <typename Box,
|
Chris@101
|
29 // std::size_t CurrentDimension,
|
Chris@101
|
30 // std::size_t EdgeDimension = dimension<Box>::value>
|
Chris@16
|
31 //struct margin_for_each_edge
|
Chris@16
|
32 //{
|
Chris@16
|
33 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
Chris@16
|
34 // BOOST_STATIC_ASSERT(0 < EdgeDimension);
|
Chris@16
|
35 //
|
Chris@16
|
36 // static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
37 // {
|
Chris@16
|
38 // return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
|
Chris@16
|
39 // ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
|
Chris@16
|
40 // }
|
Chris@16
|
41 //};
|
Chris@16
|
42 //
|
Chris@101
|
43 //template <typename Box, std::size_t CurrentDimension>
|
Chris@16
|
44 //struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
|
Chris@16
|
45 //{
|
Chris@16
|
46 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
Chris@16
|
47 //
|
Chris@16
|
48 // static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
49 // {
|
Chris@16
|
50 // return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
|
Chris@16
|
51 // }
|
Chris@16
|
52 //};
|
Chris@16
|
53 //
|
Chris@101
|
54 //template <typename Box, std::size_t CurrentDimension>
|
Chris@16
|
55 //struct margin_for_each_edge<Box, CurrentDimension, 1>
|
Chris@16
|
56 //{
|
Chris@16
|
57 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
Chris@16
|
58 //
|
Chris@16
|
59 // static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
60 // {
|
Chris@16
|
61 // return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
|
Chris@16
|
62 // }
|
Chris@16
|
63 //};
|
Chris@16
|
64 //
|
Chris@16
|
65 //template <typename Box>
|
Chris@16
|
66 //struct margin_for_each_edge<Box, 1, 1>
|
Chris@16
|
67 //{
|
Chris@16
|
68 // static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
|
Chris@16
|
69 // {
|
Chris@16
|
70 // return 1;
|
Chris@16
|
71 // }
|
Chris@16
|
72 //};
|
Chris@16
|
73 //
|
Chris@101
|
74 //template <typename Box,
|
Chris@101
|
75 // std::size_t CurrentDimension = dimension<Box>::value>
|
Chris@16
|
76 //struct margin_for_each_dimension
|
Chris@16
|
77 //{
|
Chris@16
|
78 // BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
Chris@16
|
79 //
|
Chris@16
|
80 // static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
81 // {
|
Chris@16
|
82 // return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
|
Chris@101
|
83 // margin_for_each_edge<Box, CurrentDimension>::apply(b);
|
Chris@16
|
84 // }
|
Chris@16
|
85 //};
|
Chris@16
|
86 //
|
Chris@16
|
87 //template <typename Box>
|
Chris@16
|
88 //struct margin_for_each_dimension<Box, 1>
|
Chris@16
|
89 //{
|
Chris@16
|
90 // static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
91 // {
|
Chris@101
|
92 // return margin_for_each_edge<Box, 1>::apply(b);
|
Chris@16
|
93 // }
|
Chris@16
|
94 //};
|
Chris@16
|
95
|
Chris@16
|
96 // TODO - test if this definition of margin is ok for Dimension > 2
|
Chris@16
|
97 // Now it's sum of edges lengths
|
Chris@16
|
98 // maybe margin_for_each_dimension should be used to get more or less hypersurface?
|
Chris@16
|
99
|
Chris@101
|
100 template <typename Box,
|
Chris@101
|
101 std::size_t CurrentDimension = dimension<Box>::value>
|
Chris@16
|
102 struct simple_margin_for_each_dimension
|
Chris@16
|
103 {
|
Chris@16
|
104 BOOST_STATIC_ASSERT(0 < CurrentDimension);
|
Chris@16
|
105
|
Chris@16
|
106 static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
107 {
|
Chris@16
|
108 return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
|
Chris@16
|
109 geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
|
Chris@16
|
110 }
|
Chris@16
|
111 };
|
Chris@16
|
112
|
Chris@16
|
113 template <typename Box>
|
Chris@16
|
114 struct simple_margin_for_each_dimension<Box, 1>
|
Chris@16
|
115 {
|
Chris@16
|
116 static inline typename default_margin_result<Box>::type apply(Box const& b)
|
Chris@16
|
117 {
|
Chris@16
|
118 return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
|
Chris@16
|
119 }
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 namespace dispatch {
|
Chris@16
|
123
|
Chris@16
|
124 template <typename Geometry, typename Tag>
|
Chris@16
|
125 struct comparable_margin
|
Chris@16
|
126 {
|
Chris@16
|
127 BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
|
Chris@16
|
128 };
|
Chris@16
|
129
|
Chris@16
|
130 template <typename Geometry>
|
Chris@16
|
131 struct comparable_margin<Geometry, point_tag>
|
Chris@16
|
132 {
|
Chris@16
|
133 typedef typename default_margin_result<Geometry>::type result_type;
|
Chris@16
|
134
|
Chris@16
|
135 static inline result_type apply(Geometry const& ) { return 0; }
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 template <typename Box>
|
Chris@16
|
139 struct comparable_margin<Box, box_tag>
|
Chris@16
|
140 {
|
Chris@16
|
141 typedef typename default_margin_result<Box>::type result_type;
|
Chris@16
|
142
|
Chris@16
|
143 static inline result_type apply(Box const& g)
|
Chris@16
|
144 {
|
Chris@101
|
145 //return detail::margin_for_each_dimension<Box>::apply(g);
|
Chris@101
|
146 return detail::simple_margin_for_each_dimension<Box>::apply(g);
|
Chris@16
|
147 }
|
Chris@16
|
148 };
|
Chris@16
|
149
|
Chris@16
|
150 } // namespace dispatch
|
Chris@16
|
151
|
Chris@16
|
152 template <typename Geometry>
|
Chris@16
|
153 typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
|
Chris@16
|
154 {
|
Chris@16
|
155 return dispatch::comparable_margin<
|
Chris@16
|
156 Geometry,
|
Chris@16
|
157 typename tag<Geometry>::type
|
Chris@16
|
158 >::apply(g);
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 //template <typename Box>
|
Chris@16
|
162 //typename default_margin_result<Box>::type margin(Box const& b)
|
Chris@16
|
163 //{
|
Chris@101
|
164 // return 2 * detail::margin_for_each_dimension<Box>::apply(b);
|
Chris@16
|
165 //}
|
Chris@16
|
166
|
Chris@16
|
167 }}}} // namespace boost::geometry::index::detail
|
Chris@16
|
168
|
Chris@16
|
169 #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
|