/* Copyright 2008 Intel Corporation Use, modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). */ #ifndef BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP #define BOOST_POLYGON_ITERATOR_GEOMETRY_TO_SET_HPP namespace boost { namespace polygon{ template class iterator_geometry_to_set {}; template class iterator_geometry_to_set { public: typedef typename rectangle_traits::coordinate_type coordinate_type; typedef std::forward_iterator_tag iterator_category; typedef std::pair > value_type; typedef std::ptrdiff_t difference_type; typedef const value_type* pointer; //immutable typedef const value_type& reference; //immutable private: rectangle_data rectangle_; mutable value_type vertex_; unsigned int corner_; orientation_2d orient_; bool is_hole_; public: iterator_geometry_to_set() : rectangle_(), vertex_(), corner_(4), orient_(), is_hole_() {} iterator_geometry_to_set(const rectangle_type& rectangle, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) : rectangle_(), vertex_(), corner_(0), orient_(orient), is_hole_(is_hole) { assign(rectangle_, rectangle); if(dir == HIGH) corner_ = 4; } inline iterator_geometry_to_set& operator++() { ++corner_; return *this; } inline const iterator_geometry_to_set operator++(int) { iterator_geometry_to_set tmp(*this); ++(*this); return tmp; } inline bool operator==(const iterator_geometry_to_set& that) const { return corner_ == that.corner_; } inline bool operator!=(const iterator_geometry_to_set& that) const { return !(*this == that); } inline reference operator*() const { if(corner_ == 0) { vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), LOW); vertex_.second.first = get(get(rectangle_, orient_), LOW); vertex_.second.second = 1; if(is_hole_) vertex_.second.second *= -1; } else if(corner_ == 1) { vertex_.second.first = get(get(rectangle_, orient_), HIGH); vertex_.second.second = -1; if(is_hole_) vertex_.second.second *= -1; } else if(corner_ == 2) { vertex_.first = get(get(rectangle_, orient_.get_perpendicular()), HIGH); vertex_.second.first = get(get(rectangle_, orient_), LOW); } else { vertex_.second.first = get(get(rectangle_, orient_), HIGH); vertex_.second.second = 1; if(is_hole_) vertex_.second.second *= -1; } return vertex_; } }; template class iterator_geometry_to_set { public: typedef typename polygon_traits::coordinate_type coordinate_type; typedef std::forward_iterator_tag iterator_category; typedef std::pair > value_type; typedef std::ptrdiff_t difference_type; typedef const value_type* pointer; //immutable typedef const value_type& reference; //immutable typedef typename polygon_traits::iterator_type coord_iterator_type; private: value_type vertex_; typename polygon_traits::iterator_type itrb, itre; bool last_vertex_; bool is_hole_; int multiplier_; point_data first_pt, second_pt, pts[3]; bool use_wrap; orientation_2d orient_; int polygon_index; public: iterator_geometry_to_set() : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) {} iterator_geometry_to_set(const polygon_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false, bool winding_override = false, direction_1d w = CLOCKWISE) : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(is_hole), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(orient), polygon_index(0) { itrb = begin_points(polygon); itre = end_points(polygon); use_wrap = false; if(itrb == itre || dir == HIGH || size(polygon) < 4) { polygon_index = -1; } else { direction_1d wdir = w; if(!winding_override) wdir = winding(polygon); multiplier_ = wdir == LOW ? -1 : 1; if(is_hole_) multiplier_ *= -1; first_pt = pts[0] = *itrb; ++itrb; second_pt = pts[1] = *itrb; ++itrb; pts[2] = *itrb; evaluate_(); } } iterator_geometry_to_set(const iterator_geometry_to_set& that) : vertex_(), itrb(), itre(), last_vertex_(), is_hole_(), multiplier_(), first_pt(), second_pt(), pts(), use_wrap(), orient_(), polygon_index(-1) { vertex_ = that.vertex_; itrb = that.itrb; itre = that.itre; last_vertex_ = that.last_vertex_; is_hole_ = that.is_hole_; multiplier_ = that.multiplier_; first_pt = that.first_pt; second_pt = that.second_pt; pts[0] = that.pts[0]; pts[1] = that.pts[1]; pts[2] = that.pts[2]; use_wrap = that.use_wrap; orient_ = that.orient_; polygon_index = that.polygon_index; } inline iterator_geometry_to_set& operator++() { ++polygon_index; if(itrb == itre) { if(first_pt == pts[1]) polygon_index = -1; else { pts[0] = pts[1]; pts[1] = pts[2]; if(first_pt == pts[2]) { pts[2] = second_pt; } else { pts[2] = first_pt; } } } else { ++itrb; pts[0] = pts[1]; pts[1] = pts[2]; if(itrb == itre) { if(first_pt == pts[2]) { pts[2] = second_pt; } else { pts[2] = first_pt; } } else { pts[2] = *itrb; } } evaluate_(); return *this; } inline const iterator_geometry_to_set operator++(int) { iterator_geometry_to_set tmp(*this); ++(*this); return tmp; } inline bool operator==(const iterator_geometry_to_set& that) const { return polygon_index == that.polygon_index; } inline bool operator!=(const iterator_geometry_to_set& that) const { return !(*this == that); } inline reference operator*() const { return vertex_; } inline void evaluate_() { vertex_.first = pts[1].get(orient_.get_perpendicular()); vertex_.second.first =pts[1].get(orient_); if(pts[1] == pts[2]) { vertex_.second.second = 0; } else if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) { vertex_.second.second = -1; } else if(pts[0].get(VERTICAL) != pts[1].get(VERTICAL)) { vertex_.second.second = 1; } else { vertex_.second.second = 0; } vertex_.second.second *= multiplier_; } }; template class iterator_geometry_to_set { public: typedef typename polygon_90_traits::coordinate_type coordinate_type; typedef std::forward_iterator_tag iterator_category; typedef std::pair > value_type; typedef std::ptrdiff_t difference_type; typedef const value_type* pointer; //immutable typedef const value_type& reference; //immutable private: iterator_geometry_to_set itrb, itre; iterator_geometry_to_set::hole_type> itrhib, itrhie; typename polygon_with_holes_traits::iterator_holes_type itrhb, itrhe; orientation_2d orient_; bool is_hole_; bool started_holes; public: iterator_geometry_to_set() : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() {} iterator_geometry_to_set(const polygon_with_holes_type& polygon, direction_1d dir, orientation_2d orient = HORIZONTAL, bool is_hole = false, bool = false, direction_1d = CLOCKWISE) : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(orient), is_hole_(is_hole), started_holes() { itre = iterator_geometry_to_set(polygon, HIGH, orient, is_hole_); itrhe = end_holes(polygon); if(dir == HIGH) { itrb = itre; itrhb = itrhe; started_holes = true; } else { itrb = iterator_geometry_to_set(polygon, LOW, orient, is_hole_); itrhb = begin_holes(polygon); started_holes = false; } } iterator_geometry_to_set(const iterator_geometry_to_set& that) : itrb(), itre(), itrhib(), itrhie(), itrhb(), itrhe(), orient_(), is_hole_(), started_holes() { itrb = that.itrb; itre = that.itre; if(that.itrhib != that.itrhie) { itrhib = that.itrhib; itrhie = that.itrhie; } itrhb = that.itrhb; itrhe = that.itrhe; orient_ = that.orient_; is_hole_ = that.is_hole_; started_holes = that.started_holes; } inline iterator_geometry_to_set& operator++() { //this code can be folded with flow control factoring if(itrb == itre) { if(itrhib == itrhie) { if(itrhb != itrhe) { itrhib = iterator_geometry_to_set::hole_type>(*itrhb, LOW, orient_, !is_hole_); itrhie = iterator_geometry_to_set::hole_type>(*itrhb, HIGH, orient_, !is_hole_); ++itrhb; } else { itrhib = itrhie = iterator_geometry_to_set::hole_type>(); } } else { ++itrhib; if(itrhib == itrhie) { if(itrhb != itrhe) { itrhib = iterator_geometry_to_set::hole_type>(*itrhb, LOW, orient_, !is_hole_); itrhie = iterator_geometry_to_set::hole_type>(*itrhb, HIGH, orient_, !is_hole_); ++itrhb; } else { itrhib = itrhie = iterator_geometry_to_set::hole_type>(); } } } } else { ++itrb; if(itrb == itre) { if(itrhb != itrhe) { itrhib = iterator_geometry_to_set::hole_type>(*itrhb, LOW, orient_, !is_hole_); itrhie = iterator_geometry_to_set::hole_type>(*itrhb, HIGH, orient_, !is_hole_); ++itrhb; } } } return *this; } inline const iterator_geometry_to_set operator++(int) { iterator_geometry_to_set tmp(*this); ++(*this); return tmp; } inline bool operator==(const iterator_geometry_to_set& that) const { return itrb == that.itrb && itrhb == that.itrhb && itrhib == that.itrhib; } inline bool operator!=(const iterator_geometry_to_set& that) const { return !(*this == that); } inline reference operator*() const { if(itrb != itre) return *itrb; return *itrhib; } }; } } #endif