Ticket #6366: polygon_traits.patch

File polygon_traits.patch, 2.8 KB (added by Andrii Sydorchuk, 10 years ago)

Patch

  • polygon_traits.hpp

     
    11361136    typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
    11371137    typedef typename polygon_traits<polygon_type>::iterator_type iterator;
    11381138    typedef typename std::iterator_traits<iterator>::value_type point_type;
    1139     iterator iter, iter_end;
    1140     iter_end = end_points(polygon);
    1141     iter = begin_points(polygon);
    1142     point_type prev_pt = *iter;
    1143     std::size_t num = size(polygon);
    1144     std::size_t counts[2] = {0, 0};
    1145     for(std::size_t i = 0; i < num; ++i) {
    1146       if(i == num-1) iter = begin_points(polygon);
    1147       else ++iter;
    1148       point_type current_pt = *iter;
    1149       if(x(current_pt) ==
    1150          x(prev_pt)) {
    1151         unsigned int index = x(current_pt) >
    1152           x(point);
    1153         std::size_t increment = 0;
    1154         interval_data<coordinate_type> ivl(y(current_pt),
    1155                                            y(prev_pt));
    1156         if(contains(ivl, y(point), true)) {
    1157           if(x(current_pt) ==
    1158              x(point)) return consider_touch;
    1159           ++increment;
    1160           if(y(current_pt) !=
    1161              y(point) &&
    1162              y(prev_pt) !=
    1163              y(point)) {
    1164             ++increment;
     1139    coordinate_type point_x = x(point);
     1140    coordinate_type point_y = y(point);
     1141    bool inside = false;
     1142    for (iterator iter = begin_points(polygon); iter != end_points(polygon);) {
     1143      point_type curr_point = *iter;
     1144      ++iter;
     1145      point_type next_point = (iter == end_points(polygon)) ? *begin_points(polygon) : *iter;
     1146      if (x(curr_point) == x(next_point)) {
     1147        if (x(curr_point) > point_x) {
     1148          continue;
     1149        }
     1150        coordinate_type min_y = (std::min)(y(curr_point), y(next_point));
     1151        coordinate_type max_y = (std::max)(y(curr_point), y(next_point));
     1152        if (point_y > min_y && point_y < max_y) {
     1153          if (x(curr_point) == point_x) {
     1154            return consider_touch;
    11651155          }
    1166           counts[index] += increment;
     1156          inside ^= true;
    11671157        }
     1158      } else {
     1159        coordinate_type min_x = (std::min)(x(curr_point), x(next_point));
     1160        coordinate_type max_x = (std::max)(x(curr_point), x(next_point));
     1161        if (point_x >= min_x && point_x <= max_x) {
     1162          if (y(curr_point) == point_y) {
     1163            return consider_touch;
     1164          }
     1165        }
    11681166      }
    1169       prev_pt = current_pt;
    11701167    }
    1171     //odd count implies boundary condition
    1172     if(counts[0] % 2 || counts[1] % 2) return consider_touch;
    1173     //an odd number of edges to the left implies interior pt
    1174     return counts[winding(polygon) == COUNTERCLOCKWISE ? 0 : 1] % 4 != 0;
     1168    return inside;
    11751169  }
    11761170
    11771171  //TODO: refactor to expose as user APIs