overlaps.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  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_ALGORITHMS_OVERLAPS_HPP
  11. #define BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP
  12. #include <cstddef>
  13. #include <boost/geometry/core/access.hpp>
  14. #include <boost/geometry/algorithms/not_implemented.hpp>
  15. #include <boost/geometry/geometries/concepts/check.hpp>
  16. namespace boost { namespace geometry
  17. {
  18. #ifndef DOXYGEN_NO_DETAIL
  19. namespace detail { namespace overlaps
  20. {
  21. template
  22. <
  23. std::size_t Dimension,
  24. std::size_t DimensionCount
  25. >
  26. struct box_box_loop
  27. {
  28. template <typename Box1, typename Box2>
  29. static inline void apply(Box1 const& b1, Box2 const& b2,
  30. bool& overlaps, bool& one_in_two, bool& two_in_one)
  31. {
  32. assert_dimension_equal<Box1, Box2>();
  33. typedef typename coordinate_type<Box1>::type coordinate_type1;
  34. typedef typename coordinate_type<Box2>::type coordinate_type2;
  35. coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
  36. coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
  37. coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
  38. coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
  39. // We might use the (not yet accepted) Boost.Interval
  40. // submission in the future
  41. // If:
  42. // B1: |-------|
  43. // B2: |------|
  44. // in any dimension -> no overlap
  45. if (max1 <= min2 || min1 >= max2)
  46. {
  47. overlaps = false;
  48. return;
  49. }
  50. // If:
  51. // B1: |--------------------|
  52. // B2: |-------------|
  53. // in all dimensions -> within, then no overlap
  54. // B1: |--------------------|
  55. // B2: |-------------|
  56. // this is "within-touch" -> then no overlap. So use < and >
  57. if (min1 < min2 || max1 > max2)
  58. {
  59. one_in_two = false;
  60. }
  61. // Same other way round
  62. if (min2 < min1 || max2 > max1)
  63. {
  64. two_in_one = false;
  65. }
  66. box_box_loop
  67. <
  68. Dimension + 1,
  69. DimensionCount
  70. >::apply(b1, b2, overlaps, one_in_two, two_in_one);
  71. }
  72. };
  73. template
  74. <
  75. std::size_t DimensionCount
  76. >
  77. struct box_box_loop<DimensionCount, DimensionCount>
  78. {
  79. template <typename Box1, typename Box2>
  80. static inline void apply(Box1 const& , Box2 const&, bool&, bool&, bool&)
  81. {
  82. }
  83. };
  84. struct box_box
  85. {
  86. template <typename Box1, typename Box2>
  87. static inline bool apply(Box1 const& b1, Box2 const& b2)
  88. {
  89. bool overlaps = true;
  90. bool within1 = true;
  91. bool within2 = true;
  92. box_box_loop
  93. <
  94. 0,
  95. dimension<Box1>::type::value
  96. >::apply(b1, b2, overlaps, within1, within2);
  97. /*
  98. \see http://docs.codehaus.org/display/GEOTDOC/02+Geometry+Relationships#02GeometryRelationships-Overlaps
  99. where is stated that "inside" is not an "overlap",
  100. this is true and is implemented as such.
  101. */
  102. return overlaps && ! within1 && ! within2;
  103. }
  104. };
  105. }} // namespace detail::overlaps
  106. #endif // DOXYGEN_NO_DETAIL
  107. //struct not_implemented_for_this_geometry_type : public boost::false_type {};
  108. #ifndef DOXYGEN_NO_DISPATCH
  109. namespace dispatch
  110. {
  111. template
  112. <
  113. typename Geometry1,
  114. typename Geometry2,
  115. typename Tag1 = typename tag<Geometry1>::type,
  116. typename Tag2 = typename tag<Geometry2>::type
  117. >
  118. struct overlaps: not_implemented<Tag1, Tag2>
  119. {};
  120. template <typename Box1, typename Box2>
  121. struct overlaps<Box1, Box2, box_tag, box_tag>
  122. : detail::overlaps::box_box
  123. {};
  124. } // namespace dispatch
  125. #endif // DOXYGEN_NO_DISPATCH
  126. /*!
  127. \brief \brief_check2{overlap}
  128. \ingroup overlaps
  129. \return \return_check2{overlap}
  130. \qbk{[include reference/algorithms/overlaps.qbk]}
  131. */
  132. template <typename Geometry1, typename Geometry2>
  133. inline bool overlaps(Geometry1 const& geometry1, Geometry2 const& geometry2)
  134. {
  135. concept::check<Geometry1 const>();
  136. concept::check<Geometry2 const>();
  137. return dispatch::overlaps
  138. <
  139. Geometry1,
  140. Geometry2
  141. >::apply(geometry1, geometry2);
  142. }
  143. }} // namespace boost::geometry
  144. #endif // BOOST_GEOMETRY_ALGORITHMS_OVERLAPS_HPP