margin.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
  11. #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
  12. // WARNING! comparable_margin() will work only if the same Geometries are compared
  13. // so it shouldn't be used in the case of Variants!
  14. namespace boost { namespace geometry { namespace index { namespace detail {
  15. template <typename Box>
  16. struct default_margin_result
  17. {
  18. typedef typename select_most_precise<
  19. typename coordinate_type<Box>::type,
  20. long double
  21. >::type type;
  22. };
  23. //template <typename Box,
  24. // std::size_t CurrentDimension,
  25. // std::size_t EdgeDimension = dimension<Box>::value>
  26. //struct margin_for_each_edge
  27. //{
  28. // BOOST_STATIC_ASSERT(0 < CurrentDimension);
  29. // BOOST_STATIC_ASSERT(0 < EdgeDimension);
  30. //
  31. // static inline typename default_margin_result<Box>::type apply(Box const& b)
  32. // {
  33. // return margin_for_each_edge<Box, CurrentDimension, EdgeDimension - 1>::apply(b) *
  34. // ( geometry::get<max_corner, EdgeDimension - 1>(b) - geometry::get<min_corner, EdgeDimension - 1>(b) );
  35. // }
  36. //};
  37. //
  38. //template <typename Box, std::size_t CurrentDimension>
  39. //struct margin_for_each_edge<Box, CurrentDimension, CurrentDimension>
  40. //{
  41. // BOOST_STATIC_ASSERT(0 < CurrentDimension);
  42. //
  43. // static inline typename default_margin_result<Box>::type apply(Box const& b)
  44. // {
  45. // return margin_for_each_edge<Box, CurrentDimension, CurrentDimension - 1>::apply(b);
  46. // }
  47. //};
  48. //
  49. //template <typename Box, std::size_t CurrentDimension>
  50. //struct margin_for_each_edge<Box, CurrentDimension, 1>
  51. //{
  52. // BOOST_STATIC_ASSERT(0 < CurrentDimension);
  53. //
  54. // static inline typename default_margin_result<Box>::type apply(Box const& b)
  55. // {
  56. // return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
  57. // }
  58. //};
  59. //
  60. //template <typename Box>
  61. //struct margin_for_each_edge<Box, 1, 1>
  62. //{
  63. // static inline typename default_margin_result<Box>::type apply(Box const& /*b*/)
  64. // {
  65. // return 1;
  66. // }
  67. //};
  68. //
  69. //template <typename Box,
  70. // std::size_t CurrentDimension = dimension<Box>::value>
  71. //struct margin_for_each_dimension
  72. //{
  73. // BOOST_STATIC_ASSERT(0 < CurrentDimension);
  74. //
  75. // static inline typename default_margin_result<Box>::type apply(Box const& b)
  76. // {
  77. // return margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
  78. // margin_for_each_edge<Box, CurrentDimension>::apply(b);
  79. // }
  80. //};
  81. //
  82. //template <typename Box>
  83. //struct margin_for_each_dimension<Box, 1>
  84. //{
  85. // static inline typename default_margin_result<Box>::type apply(Box const& b)
  86. // {
  87. // return margin_for_each_edge<Box, 1>::apply(b);
  88. // }
  89. //};
  90. // TODO - test if this definition of margin is ok for Dimension > 2
  91. // Now it's sum of edges lengths
  92. // maybe margin_for_each_dimension should be used to get more or less hypersurface?
  93. template <typename Box,
  94. std::size_t CurrentDimension = dimension<Box>::value>
  95. struct simple_margin_for_each_dimension
  96. {
  97. BOOST_STATIC_ASSERT(0 < CurrentDimension);
  98. static inline typename default_margin_result<Box>::type apply(Box const& b)
  99. {
  100. return simple_margin_for_each_dimension<Box, CurrentDimension - 1>::apply(b) +
  101. geometry::get<max_corner, CurrentDimension - 1>(b) - geometry::get<min_corner, CurrentDimension - 1>(b);
  102. }
  103. };
  104. template <typename Box>
  105. struct simple_margin_for_each_dimension<Box, 1>
  106. {
  107. static inline typename default_margin_result<Box>::type apply(Box const& b)
  108. {
  109. return geometry::get<max_corner, 0>(b) - geometry::get<min_corner, 0>(b);
  110. }
  111. };
  112. namespace dispatch {
  113. template <typename Geometry, typename Tag>
  114. struct comparable_margin
  115. {
  116. BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
  117. };
  118. template <typename Geometry>
  119. struct comparable_margin<Geometry, point_tag>
  120. {
  121. typedef typename default_margin_result<Geometry>::type result_type;
  122. static inline result_type apply(Geometry const& ) { return 0; }
  123. };
  124. template <typename Box>
  125. struct comparable_margin<Box, box_tag>
  126. {
  127. typedef typename default_margin_result<Box>::type result_type;
  128. static inline result_type apply(Box const& g)
  129. {
  130. //return detail::margin_for_each_dimension<Box>::apply(g);
  131. return detail::simple_margin_for_each_dimension<Box>::apply(g);
  132. }
  133. };
  134. } // namespace dispatch
  135. template <typename Geometry>
  136. typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
  137. {
  138. return dispatch::comparable_margin<
  139. Geometry,
  140. typename tag<Geometry>::type
  141. >::apply(g);
  142. }
  143. //template <typename Box>
  144. //typename default_margin_result<Box>::type margin(Box const& b)
  145. //{
  146. // return 2 * detail::margin_for_each_dimension<Box>::apply(b);
  147. //}
  148. }}}} // namespace boost::geometry::index::detail
  149. #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP