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