Ticket #6366: 0001-Polygon-fixing-reopend-issue-6366-defect-in-polygon-.patch

File 0001-Polygon-fixing-reopend-issue-6366-defect-in-polygon-.patch, 3.1 KB (added by Andrii Sydorchuk, 9 years ago)
  • include/boost/polygon/polygon_traits.hpp

    From 3bdefedab16b180841ba5c4b32eaaa494f42d8c8 Mon Sep 17 00:00:00 2001
    From: Andrii Sydorchuk <asydorchuk@spotify.com>
    Date: Wed, 19 Mar 2014 21:10:09 +0100
    Subject: [PATCH] Polygon: fixing reopend issue #6366: defect in polygon 90
     contains.
    
    ---
     include/boost/polygon/polygon_traits.hpp | 34 +++++++++++++++++++++++++-------
     1 file changed, 27 insertions(+), 7 deletions(-)
    
    diff --git a/include/boost/polygon/polygon_traits.hpp b/include/boost/polygon/polygon_traits.hpp
    index 6055bc7..b03d00f 100644
    a b namespace boost { namespace polygon{  
    11291129
    11301130  template <typename T, typename input_point_type>
    11311131  typename enable_if<
    1132     typename gtl_and< typename is_polygon_90_type<T>::type,
    1133                       typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
    1134     bool>::type
    1135   contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
     1132    typename gtl_and<
     1133      typename is_polygon_90_type<T>::type,
     1134      typename gtl_same_type<
     1135        typename geometry_concept<input_point_type>::type,
     1136        point_concept
     1137      >::type
     1138    >::type,
     1139    bool
     1140  >::type contains(
     1141      const T& polygon,
     1142      const input_point_type& point,
     1143      bool consider_touch = true) {
    11361144    typedef T polygon_type;
    11371145    typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
    11381146    typedef typename polygon_traits<polygon_type>::iterator_type iterator;
    11391147    typedef typename std::iterator_traits<iterator>::value_type point_type;
    11401148    coordinate_type point_x = x(point);
    11411149    coordinate_type point_y = y(point);
    1142     bool inside = false;
     1150    // Check how many intersections has the ray extended from the given
     1151    // point in the x-axis negative direction with the polygon edges.
     1152    // If the number is odd the point is within the polygon, otherwise not.
     1153    // We can safely ignore horizontal edges, however intersections with
     1154    // end points of the vertical edges require special handling. We should
     1155    // add one intersection in case horizontal edges that extend vertical edge
     1156    // point in the same direction.
     1157    int num_full_intersections = 0;
     1158    int num_half_intersections = 0;
    11431159    for (iterator iter = begin_points(polygon); iter != end_points(polygon);) {
    11441160      point_type curr_point = *iter;
    11451161      ++iter;
    namespace boost { namespace polygon{  
    11541170          if (x(curr_point) == point_x) {
    11551171            return consider_touch;
    11561172          }
    1157           inside ^= true;
     1173          ++num_full_intersections;
     1174        }
     1175        if (point_y == min_y || point_y == max_y) {
     1176          num_half_intersections += (y(curr_point) < y(next_point) ? 1 : -1);
    11581177        }
    11591178      } else {
    11601179        coordinate_type min_x = (std::min)(x(curr_point), x(next_point));
    namespace boost { namespace polygon{  
    11661185        }
    11671186      }
    11681187    }
    1169     return inside;
     1188    int total_intersections = num_full_intersections + (num_half_intersections >> 1);
     1189    return total_intersections & 1;
    11701190  }
    11711191
    11721192  //TODO: refactor to expose as user APIs