diff options
author | bugaevskiy <bugaevskiy@yandex-team.com> | 2022-08-06 16:20:48 +0300 |
---|---|---|
committer | bugaevskiy <bugaevskiy@yandex-team.com> | 2022-08-06 16:20:48 +0300 |
commit | 539aa27ec83e9e9b91d482a713fab0d3becfd4ee (patch) | |
tree | 13764227d34f75df1d98c9f7611d3be2016865a0 /contrib/restricted | |
parent | 917b626b554722237d40288db91f6b26e2d25759 (diff) | |
download | ydb-539aa27ec83e9e9b91d482a713fab0d3becfd4ee.tar.gz |
Reimport boost/polygon as a separate project
Diffstat (limited to 'contrib/restricted')
65 files changed, 21 insertions, 34205 deletions
diff --git a/contrib/restricted/boost/CMakeLists.txt b/contrib/restricted/boost/CMakeLists.txt index 451dbd7d14..c9209bd3b7 100644 --- a/contrib/restricted/boost/CMakeLists.txt +++ b/contrib/restricted/boost/CMakeLists.txt @@ -27,6 +27,7 @@ target_link_libraries(contrib-restricted-boost INTERFACE restricted-boost-move restricted-boost-mp11 restricted-boost-mpl + restricted-boost-polygon restricted-boost-predef restricted-boost-preprocessor restricted-boost-rational diff --git a/contrib/restricted/boost/boost/polygon/detail/boolean_op.hpp b/contrib/restricted/boost/boost/polygon/detail/boolean_op.hpp deleted file mode 100644 index 0c674a22b3..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/boolean_op.hpp +++ /dev/null @@ -1,442 +0,0 @@ -/* - 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_BOOLEAN_OP_HPP -#define BOOST_POLYGON_BOOLEAN_OP_HPP -namespace boost { namespace polygon{ -namespace boolean_op { - - //BooleanOp is the generic boolean operation scanline algorithm that provides - //all the simple boolean set operations on manhattan data. By templatizing - //the intersection count of the input and algorithm internals it is extensible - //to multi-layer scans, properties and other advanced scanline operations above - //and beyond simple booleans. - //T must cast to int - template <class T, typename Unit> - class BooleanOp { - public: - typedef std::map<Unit, T> ScanData; - typedef std::pair<Unit, T> ElementType; - protected: - ScanData scanData_; - typename ScanData::iterator nextItr_; - T nullT_; - public: - inline BooleanOp () : scanData_(), nextItr_(), nullT_() { nextItr_ = scanData_.end(); nullT_ = 0; } - inline BooleanOp (T nullT) : scanData_(), nextItr_(), nullT_(nullT) { nextItr_ = scanData_.end(); } - inline BooleanOp (const BooleanOp& that) : scanData_(that.scanData_), nextItr_(), - nullT_(that.nullT_) { nextItr_ = scanData_.begin(); } - inline BooleanOp& operator=(const BooleanOp& that); - - //moves scanline forward - inline void advanceScan() { nextItr_ = scanData_.begin(); } - - //proceses the given interval and T data - //appends output edges to cT - template <class cT> - inline void processInterval(cT& outputContainer, interval_data<Unit> ivl, T deltaCount); - - private: - inline typename ScanData::iterator lookup_(Unit pos){ - if(nextItr_ != scanData_.end() && nextItr_->first >= pos) { - return nextItr_; - } - return nextItr_ = scanData_.lower_bound(pos); - } - inline typename ScanData::iterator insert_(Unit pos, T count){ - return nextItr_ = scanData_.insert(nextItr_, ElementType(pos, count)); - } - template <class cT> - inline void evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl, T beforeCount, T afterCount); - }; - - class BinaryAnd { - public: - inline BinaryAnd() {} - inline bool operator()(int a, int b) { return (a > 0) & (b > 0); } - }; - class BinaryOr { - public: - inline BinaryOr() {} - inline bool operator()(int a, int b) { return (a > 0) | (b > 0); } - }; - class BinaryNot { - public: - inline BinaryNot() {} - inline bool operator()(int a, int b) { return (a > 0) & !(b > 0); } - }; - class BinaryXor { - public: - inline BinaryXor() {} - inline bool operator()(int a, int b) { return (a > 0) ^ (b > 0); } - }; - - //BinaryCount is an array of two deltaCounts coming from two different layers - //of scan event data. It is the merged count of the two suitable for consumption - //as the template argument of the BooleanOp algorithm because BinaryCount casts to int. - //T is a binary functor object that evaluates the array of counts and returns a logical - //result of some operation on those values. - //BinaryCount supports many of the operators that work with int, particularly the - //binary operators, but cannot support less than or increment. - template <class T> - class BinaryCount { - public: - inline BinaryCount() -#ifndef BOOST_POLYGON_MSVC - : counts_() -#endif - { counts_[0] = counts_[1] = 0; } - // constructs from two integers - inline BinaryCount(int countL, int countR) -#ifndef BOOST_POLYGON_MSVC - : counts_() -#endif - { counts_[0] = countL, counts_[1] = countR; } - inline BinaryCount& operator=(int count) { counts_[0] = count, counts_[1] = count; return *this; } - inline BinaryCount& operator=(const BinaryCount& that); - inline BinaryCount(const BinaryCount& that) -#ifndef BOOST_POLYGON_MSVC - : counts_() -#endif - { *this = that; } - inline bool operator==(const BinaryCount& that) const; - inline bool operator!=(const BinaryCount& that) const { return !((*this) == that);} - inline BinaryCount& operator+=(const BinaryCount& that); - inline BinaryCount& operator-=(const BinaryCount& that); - inline BinaryCount operator+(const BinaryCount& that) const; - inline BinaryCount operator-(const BinaryCount& that) const; - inline BinaryCount operator-() const; - inline int& operator[](bool index) { return counts_[index]; } - - //cast to int operator evaluates data using T binary functor - inline operator int() const { return T()(counts_[0], counts_[1]); } - private: - int counts_[2]; - }; - - class UnaryCount { - public: - inline UnaryCount() : count_(0) {} - // constructs from two integers - inline explicit UnaryCount(int count) : count_(count) {} - inline UnaryCount& operator=(int count) { count_ = count; return *this; } - inline UnaryCount& operator=(const UnaryCount& that) { count_ = that.count_; return *this; } - inline UnaryCount(const UnaryCount& that) : count_(that.count_) {} - inline bool operator==(const UnaryCount& that) const { return count_ == that.count_; } - inline bool operator!=(const UnaryCount& that) const { return !((*this) == that);} - inline UnaryCount& operator+=(const UnaryCount& that) { count_ += that.count_; return *this; } - inline UnaryCount& operator-=(const UnaryCount& that) { count_ -= that.count_; return *this; } - inline UnaryCount operator+(const UnaryCount& that) const { UnaryCount tmp(*this); tmp += that; return tmp; } - inline UnaryCount operator-(const UnaryCount& that) const { UnaryCount tmp(*this); tmp -= that; return tmp; } - inline UnaryCount operator-() const { UnaryCount tmp; return tmp - *this; } - - //cast to int operator evaluates data using T binary functor - inline operator int() const { return count_ % 2; } - private: - int count_; - }; - - template <class T, typename Unit> - inline BooleanOp<T, Unit>& BooleanOp<T, Unit>::operator=(const BooleanOp& that) { - scanData_ = that.scanData_; - nextItr_ = scanData_.begin(); - nullT_ = that.nullT_; - return *this; - } - - //appends output edges to cT - template <class T, typename Unit> - template <class cT> - inline void BooleanOp<T, Unit>::processInterval(cT& outputContainer, interval_data<Unit> ivl, T deltaCount) { - typename ScanData::iterator lowItr = lookup_(ivl.low()); - typename ScanData::iterator highItr = lookup_(ivl.high()); - //add interval to scan data if it is past the end - if(lowItr == scanData_.end()) { - lowItr = insert_(ivl.low(), deltaCount); - highItr = insert_(ivl.high(), nullT_); - evaluateInterval_(outputContainer, ivl, nullT_, deltaCount); - return; - } - //ensure that highItr points to the end of the ivl - if(highItr == scanData_.end() || (*highItr).first > ivl.high()) { - T value = nullT_; - if(highItr != scanData_.begin()) { - --highItr; - value = highItr->second; - } - nextItr_ = highItr; - highItr = insert_(ivl.high(), value); - } - //split the low interval if needed - if(lowItr->first > ivl.low()) { - if(lowItr != scanData_.begin()) { - --lowItr; - nextItr_ = lowItr; - lowItr = insert_(ivl.low(), lowItr->second); - } else { - nextItr_ = lowItr; - lowItr = insert_(ivl.low(), nullT_); - } - } - //process scan data intersecting interval - for(typename ScanData::iterator itr = lowItr; itr != highItr; ){ - T beforeCount = itr->second; - T afterCount = itr->second += deltaCount; - Unit low = itr->first; - ++itr; - Unit high = itr->first; - evaluateInterval_(outputContainer, interval_data<Unit>(low, high), beforeCount, afterCount); - } - //merge the bottom interval with the one below if they have the same count - if(lowItr != scanData_.begin()){ - typename ScanData::iterator belowLowItr = lowItr; - --belowLowItr; - if(belowLowItr->second == lowItr->second) { - scanData_.erase(lowItr); - } - } - //merge the top interval with the one above if they have the same count - if(highItr != scanData_.begin()) { - typename ScanData::iterator beforeHighItr = highItr; - --beforeHighItr; - if(beforeHighItr->second == highItr->second) { - scanData_.erase(highItr); - highItr = beforeHighItr; - ++highItr; - } - } - nextItr_ = highItr; - } - - template <class T, typename Unit> - template <class cT> - inline void BooleanOp<T, Unit>::evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl, - T beforeCount, T afterCount) { - bool before = (int)beforeCount > 0; - bool after = (int)afterCount > 0; - int value = (!before & after) - (before & !after); - if(value) { - outputContainer.insert(outputContainer.end(), std::pair<interval_data<Unit>, int>(ivl, value)); - } - } - - template <class T> - inline BinaryCount<T>& BinaryCount<T>::operator=(const BinaryCount<T>& that) { - counts_[0] = that.counts_[0]; - counts_[1] = that.counts_[1]; - return *this; - } - template <class T> - inline bool BinaryCount<T>::operator==(const BinaryCount<T>& that) const { - return counts_[0] == that.counts_[0] && - counts_[1] == that.counts_[1]; - } - template <class T> - inline BinaryCount<T>& BinaryCount<T>::operator+=(const BinaryCount<T>& that) { - counts_[0] += that.counts_[0]; - counts_[1] += that.counts_[1]; - return *this; - } - template <class T> - inline BinaryCount<T>& BinaryCount<T>::operator-=(const BinaryCount<T>& that) { - counts_[0] += that.counts_[0]; - counts_[1] += that.counts_[1]; - return *this; - } - template <class T> - inline BinaryCount<T> BinaryCount<T>::operator+(const BinaryCount<T>& that) const { - BinaryCount retVal(*this); - retVal += that; - return retVal; - } - template <class T> - inline BinaryCount<T> BinaryCount<T>::operator-(const BinaryCount<T>& that) const { - BinaryCount retVal(*this); - retVal -= that; - return retVal; - } - template <class T> - inline BinaryCount<T> BinaryCount<T>::operator-() const { - return BinaryCount<T>() - *this; - } - - - template <class T, typename Unit, typename iterator_type_1, typename iterator_type_2> - inline void applyBooleanBinaryOp(std::vector<std::pair<Unit, std::pair<Unit, int> > >& output, - //const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input1, - //const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input2, - iterator_type_1 itr1, iterator_type_1 itr1_end, - iterator_type_2 itr2, iterator_type_2 itr2_end, - T defaultCount) { - BooleanOp<T, Unit> boolean(defaultCount); - //typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::const_iterator itr1 = input1.begin(); - //typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::const_iterator itr2 = input2.begin(); - std::vector<std::pair<interval_data<Unit>, int> > container; - //output.reserve((std::max)(input1.size(), input2.size())); - - //consider eliminating dependecy on limits with bool flag for initial state - Unit UnitMax = (std::numeric_limits<Unit>::max)(); - Unit prevCoord = UnitMax; - Unit prevPosition = UnitMax; - T count(defaultCount); - //define the starting point - if(itr1 != itr1_end) { - prevCoord = (*itr1).first; - prevPosition = (*itr1).second.first; - count[0] += (*itr1).second.second; - } - if(itr2 != itr2_end) { - if((*itr2).first < prevCoord || - ((*itr2).first == prevCoord && (*itr2).second.first < prevPosition)) { - prevCoord = (*itr2).first; - prevPosition = (*itr2).second.first; - count = defaultCount; - count[1] += (*itr2).second.second; - ++itr2; - } else if((*itr2).first == prevCoord && (*itr2).second.first == prevPosition) { - count[1] += (*itr2).second.second; - ++itr2; - if(itr1 != itr1_end) ++itr1; - } else { - if(itr1 != itr1_end) ++itr1; - } - } else { - if(itr1 != itr1_end) ++itr1; - } - - while(itr1 != itr1_end || itr2 != itr2_end) { - Unit curCoord = UnitMax; - Unit curPosition = UnitMax; - T curCount(defaultCount); - if(itr1 != itr1_end) { - curCoord = (*itr1).first; - curPosition = (*itr1).second.first; - curCount[0] += (*itr1).second.second; - } - if(itr2 != itr2_end) { - if((*itr2).first < curCoord || - ((*itr2).first == curCoord && (*itr2).second.first < curPosition)) { - curCoord = (*itr2).first; - curPosition = (*itr2).second.first; - curCount = defaultCount; - curCount[1] += (*itr2).second.second; - ++itr2; - } else if((*itr2).first == curCoord && (*itr2).second.first == curPosition) { - curCount[1] += (*itr2).second.second; - ++itr2; - if(itr1 != itr1_end) ++itr1; - } else { - if(itr1 != itr1_end) ++itr1; - } - } else { - ++itr1; - } - - if(prevCoord != curCoord) { - boolean.advanceScan(); - prevCoord = curCoord; - prevPosition = curPosition; - count = curCount; - continue; - } - if(curPosition != prevPosition && count != defaultCount) { - interval_data<Unit> ivl(prevPosition, curPosition); - container.clear(); - boolean.processInterval(container, ivl, count); - for(std::size_t i = 0; i < container.size(); ++i) { - std::pair<interval_data<Unit>, int>& element = container[i]; - if(!output.empty() && output.back().first == prevCoord && - output.back().second.first == element.first.low() && - output.back().second.second == element.second * -1) { - output.pop_back(); - } else { - output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.low(), - element.second))); - } - output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.high(), - element.second * -1))); - } - } - prevPosition = curPosition; - count += curCount; - } - } - - template <class T, typename Unit> - inline void applyBooleanBinaryOp(std::vector<std::pair<Unit, std::pair<Unit, int> > >& inputOutput, - const std::vector<std::pair<Unit, std::pair<Unit, int> > >& input2, - T defaultCount) { - std::vector<std::pair<Unit, std::pair<Unit, int> > > output; - applyBooleanBinaryOp(output, inputOutput, input2, defaultCount); - if(output.size() < inputOutput.size() / 2) { - inputOutput = std::vector<std::pair<Unit, std::pair<Unit, int> > >(); - } else { - inputOutput.clear(); - } - inputOutput.insert(inputOutput.end(), output.begin(), output.end()); - } - - template <typename count_type = int> - struct default_arg_workaround { - template <typename Unit> - static inline void applyBooleanOr(std::vector<std::pair<Unit, std::pair<Unit, int> > >& input) { - BooleanOp<count_type, Unit> booleanOr; - std::vector<std::pair<interval_data<Unit>, int> > container; - std::vector<std::pair<Unit, std::pair<Unit, int> > > output; - output.reserve(input.size()); - //consider eliminating dependecy on limits with bool flag for initial state - Unit UnitMax = (std::numeric_limits<Unit>::max)(); - Unit prevPos = UnitMax; - Unit prevY = UnitMax; - int count = 0; - for(typename std::vector<std::pair<Unit, std::pair<Unit, int> > >::iterator itr = input.begin(); - itr != input.end(); ++itr) { - Unit pos = (*itr).first; - Unit y = (*itr).second.first; - if(pos != prevPos) { - booleanOr.advanceScan(); - prevPos = pos; - prevY = y; - count = (*itr).second.second; - continue; - } - if(y != prevY && count != 0) { - interval_data<Unit> ivl(prevY, y); - container.clear(); - booleanOr.processInterval(container, ivl, count_type(count)); - for(std::size_t i = 0; i < container.size(); ++i) { - std::pair<interval_data<Unit>, int>& element = container[i]; - if(!output.empty() && output.back().first == prevPos && - output.back().second.first == element.first.low() && - output.back().second.second == element.second * -1) { - output.pop_back(); - } else { - output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.low(), - element.second))); - } - output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.high(), - element.second * -1))); - } - } - prevY = y; - count += (*itr).second.second; - } - if(output.size() < input.size() / 2) { - input = std::vector<std::pair<Unit, std::pair<Unit, int> > >(); - } else { - input.clear(); - } - input.insert(input.end(), output.begin(), output.end()); - } - }; - -} - -} - -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/boolean_op_45.hpp b/contrib/restricted/boost/boost/polygon/detail/boolean_op_45.hpp deleted file mode 100644 index 0d6550185f..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/boolean_op_45.hpp +++ /dev/null @@ -1,1398 +0,0 @@ -/* - 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_BOOLEAN_OP_45_HPP -#define BOOST_POLYGON_BOOLEAN_OP_45_HPP -namespace boost { namespace polygon{ - - template <typename Unit> - struct boolean_op_45 { - typedef point_data<Unit> Point; - typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit; - - class Count2 { - public: - inline Count2() -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { counts[0] = counts[1] = 0; } - //inline Count2(int count) { counts[0] = counts[1] = count; } - inline Count2(int count1, int count2) -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { counts[0] = count1; counts[1] = count2; } - inline Count2(const Count2& count) -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { counts[0] = count.counts[0]; counts[1] = count.counts[1]; } - inline bool operator==(const Count2& count) const { return counts[0] == count.counts[0] && counts[1] == count.counts[1]; } - inline bool operator!=(const Count2& count) const { return !((*this) == count); } - inline Count2& operator=(int count) { counts[0] = counts[1] = count; return *this; } - inline Count2& operator=(const Count2& count) { counts[0] = count.counts[0]; counts[1] = count.counts[1]; return *this; } - inline int& operator[](bool index) { return counts[index]; } - inline int operator[](bool index) const {return counts[index]; } - inline Count2& operator+=(const Count2& count){ - counts[0] += count[0]; - counts[1] += count[1]; - return *this; - } - inline Count2& operator-=(const Count2& count){ - counts[0] -= count[0]; - counts[1] -= count[1]; - return *this; - } - inline Count2 operator+(const Count2& count) const { - return Count2(*this)+=count; - } - inline Count2 operator-(const Count2& count) const { - return Count2(*this)-=count; - } - inline Count2 invert() const { - return Count2(-counts[0], -counts[1]); - } - private: - int counts[2]; - }; - - class Count1 { - public: - inline Count1() : count_(0) { } - inline Count1(int count) : count_(count) { } - inline Count1(const Count1& count) : count_(count.count_) { } - inline bool operator==(const Count1& count) const { return count_ == count.count_; } - inline bool operator!=(const Count1& count) const { return !((*this) == count); } - inline Count1& operator=(int count) { count_ = count; return *this; } - inline Count1& operator=(const Count1& count) { count_ = count.count_; return *this; } - inline Count1& operator+=(const Count1& count){ - count_ += count.count_; - return *this; - } - inline Count1& operator-=(const Count1& count){ - count_ -= count.count_; - return *this; - } - inline Count1 operator+(const Count1& count) const { - return Count1(*this)+=count; - } - inline Count1 operator-(const Count1& count) const { - return Count1(*this)-=count; - } - inline Count1 invert() const { - return Count1(-count_); - } - int count_; - }; - - // inline std::ostream& operator<< (std::ostream& o, const Count2& c) { - // o << c[0] << " " << c[1]; - // return o; - // } - - template <typename CountType> - class Scan45ElementT { - public: - Unit x; - Unit y; - int rise; //-1, 0, +1 - mutable CountType count; - inline Scan45ElementT() : x(), y(), rise(), count() {} - inline Scan45ElementT(Unit xIn, Unit yIn, int riseIn, CountType countIn = CountType()) : - x(xIn), y(yIn), rise(riseIn), count(countIn) {} - inline Scan45ElementT(const Scan45ElementT& that) : - x(that.x), y(that.y), rise(that.rise), count(that.count) {} - inline Scan45ElementT& operator=(const Scan45ElementT& that) { - x = that.x; y = that.y; rise = that.rise; count = that.count; - return *this; - } - inline Unit evalAtX(Unit xIn) const { - return y + rise * (xIn - x); - } - - inline bool cross(Point& crossPoint, const Scan45ElementT& edge, Unit currentX) const { - Unit y1 = evalAtX(currentX); - Unit y2 = edge.evalAtX(currentX); - int rise1 = rise; - int rise2 = edge.rise; - if(rise > edge.rise){ - if(y1 > y2) return false; - } else if(rise < edge.rise){ - if(y2 > y1) return false; - std::swap(y1, y2); - std::swap(rise1, rise2); - } else { return false; } - if(rise1 == 1) { - if(rise2 == 0) { - crossPoint = Point(currentX + y2 - y1, y2); - } else { - //rise2 == -1 - Unit delta = (y2 - y1)/2; - crossPoint = Point(currentX + delta, y1 + delta); - } - } else { - //rise1 == 0 and rise2 == -1 - crossPoint = Point(currentX + y2 - y1, y1); - } - return true; - } - }; - - typedef Scan45ElementT<Count2> Scan45Element; - - // inline std::ostream& operator<< (std::ostream& o, const Scan45Element& c) { - // o << c.x << " " << c.y << " " << c.rise << " " << c.count; - // return o; - // } - - class lessScan45ElementRise { - public: - typedef Scan45Element first_argument_type; - typedef Scan45Element second_argument_type; - typedef bool result_type; - inline lessScan45ElementRise() {} //default constructor is only constructor - inline bool operator () (Scan45Element elm1, Scan45Element elm2) const { - return elm1.rise < elm2.rise; - } - }; - - template <typename CountType> - class lessScan45Element { - private: - Unit *x_; //x value at which to apply comparison - int *justBefore_; - public: - inline lessScan45Element() : x_(0), justBefore_(0) {} - inline lessScan45Element(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {} - inline lessScan45Element(const lessScan45Element& that) : x_(that.x_), justBefore_(that.justBefore_) {} - inline lessScan45Element& operator=(const lessScan45Element& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; } - inline bool operator () (const Scan45ElementT<CountType>& elm1, - const Scan45ElementT<CountType>& elm2) const { - Unit y1 = elm1.evalAtX(*x_); - Unit y2 = elm2.evalAtX(*x_); - if(y1 < y2) return true; - if(y1 == y2) { - //if justBefore is true we invert the result of the comparison of slopes - if(*justBefore_) { - return elm1.rise > elm2.rise; - } else { - return elm1.rise < elm2.rise; - } - } - return false; - } - }; - - template <typename CountType> - class Scan45CountT { - public: - inline Scan45CountT() : counts() {} //counts[0] = counts[1] = counts[2] = counts[3] = 0; } - inline Scan45CountT(CountType count) : counts() { counts[0] = counts[1] = counts[2] = counts[3] = count; } - inline Scan45CountT(const CountType& count1, const CountType& count2, const CountType& count3, - const CountType& count4) : counts() { - counts[0] = count1; - counts[1] = count2; - counts[2] = count3; - counts[3] = count4; - } - inline Scan45CountT(const Scan45CountT& count) : counts() { - (*this) = count; - } - inline bool operator==(const Scan45CountT& count) const { - for(unsigned int i = 0; i < 4; ++i) { - if(counts[i] != count.counts[i]) return false; - } - return true; - } - inline bool operator!=(const Scan45CountT& count) const { return !((*this) == count); } - inline Scan45CountT& operator=(CountType count) { - counts[0] = counts[1] = counts[2] = counts[3] = count; return *this; } - inline Scan45CountT& operator=(const Scan45CountT& count) { - for(unsigned int i = 0; i < 4; ++i) { - counts[i] = count.counts[i]; - } - return *this; - } - inline CountType& operator[](int index) { return counts[index]; } - inline CountType operator[](int index) const {return counts[index]; } - inline Scan45CountT& operator+=(const Scan45CountT& count){ - for(unsigned int i = 0; i < 4; ++i) { - counts[i] += count.counts[i]; - } - return *this; - } - inline Scan45CountT& operator-=(const Scan45CountT& count){ - for(unsigned int i = 0; i < 4; ++i) { - counts[i] -= count.counts[i]; - } - return *this; - } - inline Scan45CountT operator+(const Scan45CountT& count) const { - return Scan45CountT(*this)+=count; - } - inline Scan45CountT operator-(const Scan45CountT& count) const { - return Scan45CountT(*this)-=count; - } - inline Scan45CountT invert() const { - return Scan45CountT(CountType())-=(*this); - } - inline Scan45CountT& operator+=(const Scan45ElementT<CountType>& element){ - counts[element.rise+1] += element.count; return *this; - } - private: - CountType counts[4]; - }; - - typedef Scan45CountT<Count2> Scan45Count; - - // inline std::ostream& operator<< (std::ostream& o, const Scan45Count& c) { - // o << c[0] << ", " << c[1] << ", "; - // o << c[2] << ", " << c[3]; - // return o; - // } - - - // inline std::ostream& operator<< (std::ostream& o, const Scan45Vertex& c) { - // o << c.first << ": " << c.second; - // return o; - // } - - - //vetex45 is sortable - template <typename ct> - class Vertex45T { - public: - Point pt; - int rise; // 1, 0 or -1 - ct count; //dxdydTheta - inline Vertex45T() : pt(), rise(), count() {} - inline Vertex45T(const Point& point, int riseIn, ct countIn) : pt(point), rise(riseIn), count(countIn) {} - inline Vertex45T(const Vertex45T& vertex) : pt(vertex.pt), rise(vertex.rise), count(vertex.count) {} - inline Vertex45T& operator=(const Vertex45T& vertex){ - pt = vertex.pt; rise = vertex.rise; count = vertex.count; return *this; } - inline bool operator==(const Vertex45T& vertex) const { - return pt == vertex.pt && rise == vertex.rise && count == vertex.count; } - inline bool operator!=(const Vertex45T& vertex) const { return !((*this) == vertex); } - inline bool operator<(const Vertex45T& vertex) const { - if(pt.x() < vertex.pt.x()) return true; - if(pt.x() == vertex.pt.x()) { - if(pt.y() < vertex.pt.y()) return true; - if(pt.y() == vertex.pt.y()) { return rise < vertex.rise; } - } - return false; - } - inline bool operator>(const Vertex45T& vertex) const { return vertex < (*this); } - inline bool operator<=(const Vertex45T& vertex) const { return !((*this) > vertex); } - inline bool operator>=(const Vertex45T& vertex) const { return !((*this) < vertex); } - inline Unit evalAtX(Unit xIn) const { return pt.y() + rise * (xIn - pt.x()); } - }; - - typedef Vertex45T<int> Vertex45; - - // inline std::ostream& operator<< (std::ostream& o, const Vertex45& c) { - // o << c.pt << " " << c.rise << " " << c.count; - // return o; - // } - - //when scanning Vertex45 for polygon formation we need a scanline comparator functor - class lessVertex45 { - private: - Unit *x_; //x value at which to apply comparison - int *justBefore_; - public: - inline lessVertex45() : x_(0), justBefore_() {} - - inline lessVertex45(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {} - - inline lessVertex45(const lessVertex45& that) : x_(that.x_), justBefore_(that.justBefore_) {} - - inline lessVertex45& operator=(const lessVertex45& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; } - - template <typename ct> - inline bool operator () (const Vertex45T<ct>& elm1, const Vertex45T<ct>& elm2) const { - Unit y1 = elm1.evalAtX(*x_); - Unit y2 = elm2.evalAtX(*x_); - if(y1 < y2) return true; - if(y1 == y2) { - //if justBefore is true we invert the result of the comparison of slopes - if(*justBefore_) { - return elm1.rise > elm2.rise; - } else { - return elm1.rise < elm2.rise; - } - } - return false; - } - }; - - // 0 right to left - // 1 upper right to lower left - // 2 high to low - // 3 upper left to lower right - // 4 left to right - // 5 lower left to upper right - // 6 low to high - // 7 lower right to upper left - static inline int classifyEdge45(const Point& prevPt, const Point& nextPt) { - if(prevPt.x() == nextPt.x()) { - //2 or 6 - return predicated_value(prevPt.y() < nextPt.y(), 6, 2); - } - if(prevPt.y() == nextPt.y()) { - //0 or 4 - return predicated_value(prevPt.x() < nextPt.x(), 4, 0); - } - if(prevPt.x() < nextPt.x()) { - //3 or 5 - return predicated_value(prevPt.y() < nextPt.y(), 5, 3); - } - //prevPt.x() > nextPt.y() - //1 or 7 - return predicated_value(prevPt.y() < nextPt.y(), 7, 1); - } - - template <int op, typename CountType> - static int applyLogic(CountType count1, CountType count2){ - bool l1 = applyLogic<op>(count1); - bool l2 = applyLogic<op>(count2); - if(l1 && !l2) - return -1; //was true before and became false like a trailing edge - if(!l1 && l2) - return 1; //was false before and became true like a leading edge - return 0; //no change in logic between the two counts - } - template <int op> - static bool applyLogic(Count2 count) { -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op == 0) { //apply or - return count[0] > 0 || count[1] > 0; - } else if(op == 1) { //apply and - return count[0] > 0 && count[1] > 0; - } else if(op == 2) { //apply not - return count[0] > 0 && !(count[1] > 0); - } else if(op == 3) { //apply xor - return (count[0] > 0) ^ (count[1] > 0); - } else - return false; -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - } - - template <int op> - struct boolean_op_45_output_functor { - template <typename cT> - void operator()(cT& output, const Count2& count1, const Count2& count2, - const Point& pt, int rise, direction_1d end) { - int edgeType = applyLogic<op>(count1, count2); - if(edgeType) { - int multiplier = end == LOW ? -1 : 1; - //std::cout << "cross logic: " << edgeType << "\n"; - output.insert(output.end(), Vertex45(pt, rise, edgeType * multiplier)); - //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n"; - } - } - }; - - template <int op> - static bool applyLogic(Count1 count) { -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op == 0) { //apply or - return count.count_ > 0; - } else if(op == 1) { //apply and - return count.count_ > 1; - } else if(op == 3) { //apply xor - return (count.count_ % 2) != 0; - } else - return false; -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - } - - template <int op> - struct unary_op_45_output_functor { - template <typename cT> - void operator()(cT& output, const Count1& count1, const Count1& count2, - const Point& pt, int rise, direction_1d end) { - int edgeType = applyLogic<op>(count1, count2); - if(edgeType) { - int multiplier = end == LOW ? -1 : 1; - //std::cout << "cross logic: " << edgeType << "\n"; - output.insert(output.end(), Vertex45(pt, rise, edgeType * multiplier)); - //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n"; - } - } - }; - - class lessScan45Vertex { - public: - inline lessScan45Vertex() {} //default constructor is only constructor - template <typename Scan45Vertex> - inline bool operator () (const Scan45Vertex& v1, const Scan45Vertex& v2) const { - return (v1.first.x() < v2.first.x()) || (v1.first.x() == v2.first.x() && v1.first.y() < v2.first.y()); - } - }; - template <typename S45V> - static inline void sortScan45Vector(S45V& vec) { - polygon_sort(vec.begin(), vec.end(), lessScan45Vertex()); - } - - template <typename CountType, typename output_functor> - class Scan45 { - public: - typedef Scan45CountT<CountType> Scan45Count; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - - //index is the index into the vertex - static inline Scan45Element getElement(const Scan45Vertex& vertex, int index) { - return Scan45Element(vertex.first.x(), vertex.first.y(), index - 1, vertex.second[index]); - } - - class lessScan45Point { - public: - typedef Point first_argument_type; - typedef Point second_argument_type; - typedef bool result_type; - inline lessScan45Point() {} //default constructor is only constructor - inline bool operator () (const Point& v1, const Point& v2) const { - return (v1.x() < v2.x()) || (v1.x() == v2.x() && v1.y() < v2.y()); - } - }; - - typedef std::vector<Scan45Vertex> Scan45Vector; - - //definitions - typedef std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> > Scan45Data; - typedef typename Scan45Data::iterator iterator; - typedef typename Scan45Data::const_iterator const_iterator; - typedef std::set<Point, lessScan45Point> CrossQueue; - - //data - Scan45Data scanData_; - CrossQueue crossQueue_; - Scan45Vector crossVector_; - Unit x_; - int justBefore_; - public: - inline Scan45() : scanData_(), crossQueue_(), crossVector_(), - x_((std::numeric_limits<Unit>::min)()), justBefore_(false) { - lessScan45Element<CountType> lessElm(&x_, &justBefore_); - scanData_ = std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >(lessElm); - } - inline Scan45(const Scan45& that) : scanData_(), crossQueue_(), crossVector_(), - x_((std::numeric_limits<Unit>::min)()), justBefore_(false) { - (*this) = that; } - inline Scan45& operator=(const Scan45& that) { - x_ = that.x_; - justBefore_ = that.justBefore_; - crossQueue_ = that.crossQueue_; - crossVector_ = that.crossVector_; - lessScan45Element<CountType> lessElm(&x_, &justBefore_); - scanData_ = std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >(lessElm); - for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){ - scanData_.insert(scanData_.end(), *itr); - } - return *this; - } - - //cT is an output container of Vertex45 - //iT is an iterator over Scan45Vertex elements - template <class cT, class iT> - void scan(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "1\n"; - while(inputBegin != inputEnd) { - //std::cout << "2\n"; - //std::cout << "x_ = " << x_ << "\n"; - //std::cout << "scan line size: " << scanData_.size() << "\n"; - //for(iterator iter = scanData_.begin(); - // iter != scanData_.end(); ++iter) { - // std::cout << "scan element\n"; - // std::cout << *iter << " " << iter->evalAtX(x_) << "\n"; - // } - // std::cout << "cross queue size: " << crossQueue_.size() << "\n"; - // std::cout << "cross vector size: " << crossVector_.size() << "\n"; - //for(CrossQueue::iterator cqitr = crossQueue_.begin(); cqitr != crossQueue_.end(); ++cqitr) { - // std::cout << *cqitr << " "; - //} std::cout << "\n"; - Unit nextX = (*inputBegin).first.x(); - if(!crossVector_.empty() && crossVector_[0].first.x() < nextX) nextX = crossVector_[0].first.x(); - if(nextX != x_) { - //std::cout << "3\n"; - //we need to move to the next scanline stop - //we need to process end events then cross events - //process end events - if(!crossQueue_.empty() && - (*crossQueue_.begin()).x() < nextX) { - //std::cout << "4\n"; - nextX = (std::min)(nextX, (*crossQueue_.begin()).x()); - } - //std::cout << "6\n"; - justBefore_ = true; - x_ = nextX; - advance_(output); - justBefore_ = false; - if(!crossVector_.empty() && - nextX == (*inputBegin).first.x()) { - inputBegin = mergeCross_(inputBegin, inputEnd); - } - processEvent_(output, crossVector_.begin(), crossVector_.end()); - crossVector_.clear(); - } else { - //std::cout << "7\n"; - //our scanline has progressed to the event that is next in the queue - inputBegin = processEvent_(output, inputBegin, inputEnd); - } - } - //std::cout << "done scanning\n"; - } - - private: - //functions - - template <class cT> - inline void advance_(cT& output) { - //process all cross points on the cross queue at the current x_ - //std::cout << "advance_\n"; - std::vector<iterator> eraseVec; - while(!crossQueue_.empty() && - (*crossQueue_.begin()).x() == x_){ - //std::cout << "loop\n"; - //pop point off the cross queue - Point crossPoint = *(crossQueue_.begin()); - //std::cout << crossPoint << "\n"; - //for(iterator iter = scanData_.begin(); - // iter != scanData_.end(); ++iter) { - // std::cout << "scan element\n"; - // std::cout << *iter << " " << iter->evalAtX(x_) << "\n"; - //} - crossQueue_.erase(crossQueue_.begin()); - Scan45Vertex vertex(crossPoint, Scan45Count()); - iterator lowIter = lookUp_(vertex.first.y()); - //std::cout << "searching at: " << vertex.first.y() << "\n"; - //if(lowIter == scanData_.end()) std::cout << "could not find\n"; - //else std::cout << "found: " << *lowIter << "\n"; - if(lowIter == scanData_.end() || - lowIter->evalAtX(x_) != vertex.first.y()) { - // std::cout << "skipping\n"; - //there weren't any edges at this potential cross point - continue; - } - CountType countBelow; - iterator searchDownItr = lowIter; - while(searchDownItr != scanData_.begin() - && searchDownItr->evalAtX(x_) == vertex.first.y()) { - //get count from below - --searchDownItr; - countBelow = searchDownItr->count; - } - //std::cout << "Below Count: " << countBelow << "\n"; - Scan45Count count(countBelow); - std::size_t numEdges = 0; - iterator eraseItrs[3]; - while(lowIter != scanData_.end() && - lowIter->evalAtX(x_) == vertex.first.y()) { - for(int index = lowIter->rise +1; index >= 0; --index) - count[index] = lowIter->count; - //std::cout << count << "\n"; - eraseItrs[numEdges] = lowIter; - ++numEdges; - ++lowIter; - } - if(numEdges == 1) { - //look for the next crossing point and continue - //std::cout << "found only one edge\n"; - findCross_(eraseItrs[0]); - continue; - } - //before we erase the elements we need to decide if they should be written out - CountType currentCount = countBelow; - for(std::size_t i = 0; i < numEdges; ++i) { - output_functor f; - f(output, currentCount, eraseItrs[i]->count, crossPoint, eraseItrs[i]->rise, LOW); - currentCount = eraseItrs[i]->count; - } - //schedule erase of the elements - for(std::size_t i = 0; i < numEdges; ++i) { - eraseVec.push_back(eraseItrs[i]); - } - - //take the derivative wrt theta of the count at the crossing point - vertex.second[2] = count[2] - countBelow; - vertex.second[1] = count[1] - count[2]; - vertex.second[0] = count[0] - count[1]; - //add the point, deriviative pair into the cross vector - //std::cout << "LOOK HERE!\n"; - //std::cout << count << "\n"; - //std::cout << vertex << "\n"; - crossVector_.push_back(vertex); - } - //erase crossing elements - std::vector<iterator> searchVec; - for(std::size_t i = 0; i < eraseVec.size(); ++i) { - if(eraseVec[i] != scanData_.begin()) { - iterator searchItr = eraseVec[i]; - --searchItr; - if(searchVec.empty() || - searchVec.back() != searchItr) - searchVec.push_back(searchItr); - } - scanData_.erase(eraseVec[i]); - } - for(std::size_t i = 0; i < searchVec.size(); ++i) { - findCross_(searchVec[i]); - } - } - - template <class iT> - inline iT mergeCross_(iT inputBegin, iT inputEnd) { - Scan45Vector vec; - swap(vec, crossVector_); - iT mergeEnd = inputBegin; - std::size_t mergeCount = 0; - while(mergeEnd != inputEnd && - (*mergeEnd).first.x() == x_) { - ++mergeCount; - ++mergeEnd; - } - crossVector_.reserve((std::max)(vec.capacity(), vec.size() + mergeCount)); - for(std::size_t i = 0; i < vec.size(); ++i){ - while(inputBegin != mergeEnd && - (*inputBegin).first.y() < vec[i].first.y()) { - crossVector_.push_back(*inputBegin); - ++inputBegin; - } - crossVector_.push_back(vec[i]); - } - while(inputBegin != mergeEnd){ - crossVector_.push_back(*inputBegin); - ++inputBegin; - } - return inputBegin; - } - - template <class cT, class iT> - inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "processEvent_\n"; - CountType verticalCount = CountType(); - Point prevPoint; - iterator prevIter = scanData_.end(); - while(inputBegin != inputEnd && - (*inputBegin).first.x() == x_) { - //std::cout << (*inputBegin) << "\n"; - //std::cout << "loop\n"; - Scan45Vertex vertex = *inputBegin; - //std::cout << vertex.first << "\n"; - //if vertical count propigating up fake a null event at the next element - if(verticalCount != CountType() && (prevIter != scanData_.end() && - prevIter->evalAtX(x_) < vertex.first.y())) { - //std::cout << "faking null event\n"; - vertex = Scan45Vertex(Point(x_, prevIter->evalAtX(x_)), Scan45Count()); - } else { - ++inputBegin; - //std::cout << "after increment\n"; - //accumulate overlapping changes in Scan45Count - while(inputBegin != inputEnd && - (*inputBegin).first.x() == x_ && - (*inputBegin).first.y() == vertex.first.y()) { - //std::cout << "accumulate\n"; - vertex.second += (*inputBegin).second; - ++inputBegin; - } - } - //std::cout << vertex.second << "\n"; - //integrate vertex - CountType currentCount = verticalCount;// + vertex.second[0]; - for(unsigned int i = 0; i < 3; ++i) { - vertex.second[i] = currentCount += vertex.second[i]; - } - //std::cout << vertex.second << "\n"; - //vertex represents the change in state at this point - - //get counts at current vertex - CountType countBelow; - iterator lowIter = lookUp_(vertex.first.y()); - if(lowIter != scanData_.begin()) { - //get count from below - --lowIter; - countBelow = lowIter->count; - ++lowIter; - } - //std::cout << "Count Below: " << countBelow[0] << " " << countBelow[1] << "\n"; - //std::cout << "vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n"; - Scan45Count countAt(countBelow - verticalCount); - //check if the vertical edge should be written out - if(verticalCount != CountType()) { - output_functor f; - f(output, countBelow - verticalCount, countBelow, prevPoint, 2, HIGH); - f(output, countBelow - verticalCount, countBelow, vertex.first, 2, LOW); - } - currentCount = countBelow - verticalCount; - while(lowIter != scanData_.end() && - lowIter->evalAtX(x_) == vertex.first.y()) { - for(unsigned int i = lowIter->rise + 1; i < 3; ++i) { - countAt[i] = lowIter->count; - } - Point lp(lowIter->x, lowIter->y); - if(lp != vertex.first) { - output_functor f; - f(output, currentCount, lowIter->count, vertex.first, lowIter->rise, LOW); - } - currentCount = lowIter->count; - iterator nextIter = lowIter; - ++nextIter; - //std::cout << "erase\n"; - scanData_.erase(lowIter); - if(nextIter != scanData_.end()) - findCross_(nextIter); - lowIter = nextIter; - } - verticalCount += vertex.second[3]; - prevPoint = vertex.first; - //std::cout << "new vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n"; - prevIter = lowIter; - //count represents the current state at this point - //std::cout << vertex.second << "\n"; - //std::cout << countAt << "\n"; - //std::cout << "ADD\n"; - vertex.second += countAt; - //std::cout << vertex.second << "\n"; - - //add elements to the scanline - for(int i = 0; i < 3; ++i) { - if(vertex.second[i] != countBelow) { - //std::cout << "insert: " << vertex.first.x() << " " << vertex.first.y() << " " << i-1 << - // " " << vertex.second[i][0] << " " << vertex.second[i][1] << "\n"; - iterator insertIter = scanData_.insert(scanData_.end(), - Scan45ElementT<CountType>(vertex.first.x(), - vertex.first.y(), - i - 1, vertex.second[i])); - findCross_(insertIter); - output_functor f; - f(output, countBelow, vertex.second[i], vertex.first, i - 1, HIGH); - } - countBelow = vertex.second[i]; - } - } - //std::cout << "end processEvent\n"; - return inputBegin; - } - - //iter1 is horizontal - inline void scheduleCross0_(iterator iter1, iterator iter2) { - //std::cout << "0, "; - Unit y1 = iter1->evalAtX(x_); - Unit y2 = iter2->evalAtX(x_); - LongUnit delta = local_abs(LongUnit(y1) - LongUnit(y2)); - if(delta + static_cast<LongUnit>(x_) <= (std::numeric_limits<Unit>::max)()) - crossQueue_.insert(crossQueue_.end(), Point(x_ + static_cast<Unit>(delta), y1)); - //std::cout << Point(x_ + delta, y1); - } - - //neither iter is horizontal - inline void scheduleCross1_(iterator iter1, iterator iter2) { - //std::cout << "1, "; - Unit y1 = iter1->evalAtX(x_); - Unit y2 = iter2->evalAtX(x_); - //std::cout << y1 << " " << y2 << ": "; - //note that half the delta cannot exceed the positive inter range - LongUnit delta = y1; - delta -= y2; - Unit UnitMax = (std::numeric_limits<Unit>::max)(); - if((delta & 1) == 1) { - //delta is odd, division by 2 will result in integer trunctaion - if(delta == 1) { - //the cross point is not on the integer grid and cannot be represented - //we must throw an exception - std::string msg = "GTL 45 Boolean error, precision insufficient to represent edge intersection coordinate value."; - throw(msg); - } else { - //note that result of this subtraction is always positive because itr1 is above itr2 in scanline - LongUnit halfDelta2 = (LongUnit)((((LongUnit)y1) - y2)/2); - //note that halfDelta2 has been truncated - if(halfDelta2 + x_ <= UnitMax && halfDelta2 + y2 <= UnitMax) { - crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta2), y2+static_cast<Unit>(halfDelta2))); - crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta2), y2+static_cast<Unit>(halfDelta2)+1)); - } - } - } else { - LongUnit halfDelta = (LongUnit)((((LongUnit)y1) - y2)/2); - if(halfDelta + x_ <= UnitMax && halfDelta + y2 <= UnitMax) - crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta), y2+static_cast<Unit>(halfDelta))); - //std::cout << Point(x_+halfDelta, y2+halfDelta); - } - } - - inline void findCross_(iterator iter) { - //std::cout << "find cross "; - iterator iteratorBelow = iter; - iterator iteratorAbove = iter; - if(iter != scanData_.begin() && iter->rise < 1) { - --iteratorBelow; - if(iter->rise == 0){ - if(iteratorBelow->rise == 1) { - scheduleCross0_(iter, iteratorBelow); - } - } else { - //iter->rise == -1 - if(iteratorBelow->rise == 1) { - scheduleCross1_(iter, iteratorBelow); - } else if(iteratorBelow->rise == 0) { - scheduleCross0_(iteratorBelow, iter); - } - } - } - ++iteratorAbove; - if(iteratorAbove != scanData_.end() && iter->rise > -1) { - if(iter->rise == 0) { - if(iteratorAbove->rise == -1) { - scheduleCross0_(iter, iteratorAbove); - } - } else { - //iter->rise == 1 - if(iteratorAbove->rise == -1) { - scheduleCross1_(iteratorAbove, iter); - } else if(iteratorAbove->rise == 0) { - scheduleCross0_(iteratorAbove, iter); - } - } - } - //std::cout << "\n"; - } - - inline iterator lookUp_(Unit y){ - //if just before then we need to look from 1 not -1 - return scanData_.lower_bound(Scan45ElementT<CountType>(x_, y, -1+2*justBefore_)); - } - }; - - //template <typename CountType> - //static inline void print45Data(const std::set<Scan45ElementT<CountType>, - // lessScan45Element<CountType> >& data) { - // typename std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >::const_iterator iter; - // for(iter = data.begin(); iter != data.end(); ++iter) { - // std::cout << iter->x << " " << iter->y << " " << iter->rise << "\n"; - // } - //} - - template <typename streamtype> - static inline bool testScan45Data(streamtype& stdcout) { - Unit x = 0; - int justBefore = false; - lessScan45Element<Count2> lessElm(&x, &justBefore); - std::set<Scan45ElementT<Count2>, lessScan45Element<Count2> > testData(lessElm); - //Unit size = testData.size(); - typedef std::set<Scan45ElementT<Count2>, lessScan45Element<Count2> > Scan45Data; - typename Scan45Data::iterator itr10 = testData.insert(testData.end(), Scan45Element(0, 10, 1)); - typename Scan45Data::iterator itr20 = testData.insert(testData.end(), Scan45Element(0, 20, 1)); - typename Scan45Data::iterator itr30 = testData.insert(testData.end(), Scan45Element(0, 30, -1)); - typename Scan45Data::iterator itr40 = testData.insert(testData.end(), Scan45Element(0, 40, -1)); - typename Scan45Data::iterator itrA = testData.lower_bound(Scan45Element(0, 29, -1)); - typename Scan45Data::iterator itr1 = testData.lower_bound(Scan45Element(0, 10, -1)); - x = 4; - //now at 14 24 26 36 - typename Scan45Data::iterator itrB = testData.lower_bound(Scan45Element(4, 29, -1)); - typename Scan45Data::iterator itr2 = testData.lower_bound(Scan45Element(4, 14, -1)); - if(itr1 != itr2) stdcout << "test1 failed\n"; - if(itrA == itrB) stdcout << "test2 failed\n"; - //remove crossing elements - testData.erase(itr20); - testData.erase(itr30); - x = 5; - itr20 = testData.insert(testData.end(), Scan45Element(0, 20, 1)); - itr30 = testData.insert(testData.end(), Scan45Element(0, 30, -1)); - //now at 15 25 25 35 - typename Scan45Data::iterator itr = testData.begin(); - if(itr != itr10) stdcout << "test3 failed\n"; - ++itr; - if(itr != itr30) stdcout << "test4 failed\n"; - ++itr; - if(itr != itr20) stdcout << "test5 failed\n"; - ++itr; - if(itr != itr40) stdcout << "test6 failed\n"; - stdcout << "done testing Scan45Data\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45Rect(stream_type& stdcout) { - stdcout << "testing Scan45Rect\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 8 - // result == 0 0 0 1 - // result == 0 0 2 1 - // result == 0 10 2 -1 - // result == 0 10 0 -1 - // result == 10 0 0 -1 - // result == 10 0 2 -1 - // result == 10 10 2 1 - // result == 10 10 0 1 - std::vector<Vertex45> reference; - reference.push_back(Vertex45(Point(0, 0), 0, 1)); - reference.push_back(Vertex45(Point(0, 0), 2, 1)); - reference.push_back(Vertex45(Point(0, 10), 2, -1)); - reference.push_back(Vertex45(Point(0, 10), 0, -1)); - reference.push_back(Vertex45(Point(10, 0), 0, -1)); - reference.push_back(Vertex45(Point(10, 0), 2, -1)); - reference.push_back(Vertex45(Point(10, 10), 2, 1)); - reference.push_back(Vertex45(Point(10, 10), 0, 1)); - if(result != reference) { - stdcout << "result size == " << result.size() << "\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - //std::cout << "result == " << result[i]<< "\n"; - } - stdcout << "reference size == " << reference.size() << "\n"; - for(std::size_t i = 0; i < reference.size(); ++i) { - //std::cout << "reference == " << reference[i]<< "\n"; - } - return false; - } - stdcout << "done testing Scan45Rect\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45P1(stream_type& stdcout) { - stdcout << "testing Scan45P1\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count))); - vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), Count2(0, 0), ncount, ncount))); - vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), Count2(0, 0), ncount, ncount))); - vertices.push_back(Scan45Vertex(Point(10,20), Scan45Count(Count2(0, 0), Count2(0, 0), count, count))); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 8 - // result == 0 0 1 1 - // result == 0 0 2 1 - // result == 0 10 2 -1 - // result == 0 10 1 -1 - // result == 10 10 1 -1 - // result == 10 10 2 -1 - // result == 10 20 2 1 - // result == 10 20 1 1 - std::vector<Vertex45> reference; - reference.push_back(Vertex45(Point(0, 0), 1, 1)); - reference.push_back(Vertex45(Point(0, 0), 2, 1)); - reference.push_back(Vertex45(Point(0, 10), 2, -1)); - reference.push_back(Vertex45(Point(0, 10), 1, -1)); - reference.push_back(Vertex45(Point(10, 10), 1, -1)); - reference.push_back(Vertex45(Point(10, 10), 2, -1)); - reference.push_back(Vertex45(Point(10, 20), 2, 1)); - reference.push_back(Vertex45(Point(10, 20), 1, 1)); - if(result != reference) { - stdcout << "result size == " << result.size() << "\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - //std::cout << "result == " << result[i]<< "\n"; - } - stdcout << "reference size == " << reference.size() << "\n"; - for(std::size_t i = 0; i < reference.size(); ++i) { - //std::cout << "reference == " << reference[i]<< "\n"; - } - return false; - } - stdcout << "done testing Scan45P1\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45P2(stream_type& stdcout) { - stdcout << "testing Scan45P2\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, count, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), ncount, count, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(20,10), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 8 - // result == 0 0 0 1 - // result == 0 0 1 -1 - // result == 10 0 0 -1 - // result == 10 0 1 1 - // result == 10 10 1 1 - // result == 10 10 0 -1 - // result == 20 10 1 -1 - // result == 20 10 0 1 - std::vector<Vertex45> reference; - reference.push_back(Vertex45(Point(0, 0), 0, 1)); - reference.push_back(Vertex45(Point(0, 0), 1, -1)); - reference.push_back(Vertex45(Point(10, 0), 0, -1)); - reference.push_back(Vertex45(Point(10, 0), 1, 1)); - reference.push_back(Vertex45(Point(10, 10), 1, 1)); - reference.push_back(Vertex45(Point(10, 10), 0, -1)); - reference.push_back(Vertex45(Point(20, 10), 1, -1)); - reference.push_back(Vertex45(Point(20, 10), 0, 1)); - if(result != reference) { - stdcout << "result size == " << result.size() << "\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - //stdcout << "result == " << result[i]<< "\n"; - } - stdcout << "reference size == " << reference.size() << "\n"; - for(std::size_t i = 0; i < reference.size(); ++i) { - //stdcout << "reference == " << reference[i]<< "\n"; - } - return false; - } - stdcout << "done testing Scan45P2\n"; - return true; - } - - template <typename streamtype> - static inline bool testScan45And(streamtype& stdcout) { - stdcout << "testing Scan45And\n"; - Scan45<Count2, boolean_op_45_output_functor<1> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(2,2), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - vertices.push_back(Scan45Vertex(Point(2,12), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(12,2), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(12,12), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - //result size == 8 - //result == 2 2 0 1 - //result == 2 2 2 1 - //result == 2 10 2 -1 - //result == 2 10 0 -1 - //result == 10 2 0 -1 - //result == 10 2 2 -1 - //result == 10 10 2 1 - //result == 10 10 0 1 - std::vector<Vertex45> reference; - reference.push_back(Vertex45(Point(2, 2), 0, 1)); - reference.push_back(Vertex45(Point(2, 2), 2, 1)); - reference.push_back(Vertex45(Point(2, 10), 2, -1)); - reference.push_back(Vertex45(Point(2, 10), 0, -1)); - reference.push_back(Vertex45(Point(10, 2), 0, -1)); - reference.push_back(Vertex45(Point(10, 2), 2, -1)); - reference.push_back(Vertex45(Point(10, 10), 2, 1)); - reference.push_back(Vertex45(Point(10, 10), 0, 1)); - if(result != reference) { - stdcout << "result size == " << result.size() << "\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - //stdcout << "result == " << result[i]<< "\n"; - } - stdcout << "reference size == " << reference.size() << "\n"; - for(std::size_t i = 0; i < reference.size(); ++i) { - //stdcout << "reference == " << reference[i]<< "\n"; - } - return false; - } - stdcout << "done testing Scan45And\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45Star1(stream_type& stdcout) { - stdcout << "testing Scan45Star1\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(8,16), Scan45Count(Count2(0, 0), Count2(0, 0), count, count))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(12,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(4,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count))); - vertices.push_back(Scan45Vertex(Point(4,16), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 24 - // result == 0 8 -1 1 - // result == 0 8 1 -1 - // result == 4 0 1 1 - // result == 4 0 2 1 - // result == 4 4 2 -1 - // result == 4 4 -1 -1 - // result == 4 12 1 1 - // result == 4 12 2 1 - // result == 4 16 2 -1 - // result == 4 16 -1 -1 - // result == 6 2 1 -1 - // result == 6 14 -1 1 - // result == 6 2 -1 1 - // result == 6 14 1 -1 - // result == 8 0 -1 -1 - // result == 8 0 2 -1 - // result == 8 4 2 1 - // result == 8 4 1 1 - // result == 8 12 -1 -1 - // result == 8 12 2 -1 - // result == 8 16 2 1 - // result == 8 16 1 1 - // result == 12 8 1 -1 - // result == 12 8 -1 1 - if(result.size() != 24) { - //stdcout << "result size == " << result.size() << "\n"; - //stdcout << "reference size == " << 24 << "\n"; - return false; - } - stdcout << "done testing Scan45Star1\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45Star2(stream_type& stdcout) { - stdcout << "testing Scan45Star2\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 24 - // result == 0 4 0 1 - // result == 0 4 1 -1 - // result == 0 8 -1 1 - // result == 0 8 0 -1 - // result == 2 6 1 1 - // result == 2 6 -1 -1 - // result == 4 4 0 -1 - // result == 4 8 0 1 - // result == 4 4 -1 1 - // result == 4 8 1 -1 - // result == 8 0 -1 -1 - // result == 8 0 1 1 - // result == 8 12 1 1 - // result == 8 12 -1 -1 - // result == 12 4 1 -1 - // result == 12 8 -1 1 - // result == 12 4 0 1 - // result == 12 8 0 -1 - // result == 14 6 -1 -1 - // result == 14 6 1 1 - // result == 16 4 0 -1 - // result == 16 4 -1 1 - // result == 16 8 1 -1 - // result == 16 8 0 1 - if(result.size() != 24) { - //std::cout << "result size == " << result.size() << "\n"; - //std::cout << "reference size == " << 24 << "\n"; - return false; - } - stdcout << "done testing Scan45Star2\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45Star3(stream_type& stdcout) { - stdcout << "testing Scan45Star3\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(8,16), Scan45Count(Count2(0, 0), Count2(0, 0), count, count))); - - vertices.push_back(Scan45Vertex(Point(6,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - vertices.push_back(Scan45Vertex(Point(6,14), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(12,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(12,14), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(12,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(4,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count))); - vertices.push_back(Scan45Vertex(Point(4,16), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 28 - // result == 0 8 -1 1 - // result == 0 8 1 -1 - // result == 4 0 1 1 - // result == 4 0 2 1 - // result == 4 4 2 -1 - // result == 4 4 -1 -1 - // result == 4 12 1 1 - // result == 4 12 2 1 - // result == 4 16 2 -1 - // result == 4 16 -1 -1 - // result == 6 2 1 -1 - // result == 6 14 -1 1 - // result == 6 0 0 1 - // result == 6 0 2 1 - // result == 6 2 2 -1 - // result == 6 14 1 -1 - // result == 8 0 0 -1 - // result == 8 0 0 1 - // result == 8 14 0 -1 - // result == 8 14 2 -1 - // result == 8 16 2 1 - // result == 8 16 1 1 - // result == 12 0 0 -1 - // result == 12 0 2 -1 - // result == 12 8 2 1 - // result == 12 8 2 -1 - // result == 12 14 2 1 - // result == 12 14 0 1 - if(result.size() != 28) { - //std::cout << "result size == " << result.size() << "\n"; - //std::cout << "reference size == " << 28 << "\n"; - return false; - } - - stdcout << "done testing Scan45Star3\n"; - return true; - } - - - template <typename stream_type> - static inline bool testScan45Star4(stream_type& stdcout) { - stdcout << "testing Scan45Star4\n"; - Scan45<Count2, boolean_op_45_output_functor<0> > scan45; - std::vector<Vertex45 > result; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - - vertices.push_back(Scan45Vertex(Point(0,6), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - vertices.push_back(Scan45Vertex(Point(0,12), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(16,6), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount))); - vertices.push_back(Scan45Vertex(Point(16,12), Scan45Count(Count2(0, 0), count, Count2(0, 0), count))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - stdcout << "done scanning\n"; - // result size == 28 - // result == 0 4 0 1 - // result == 0 4 1 -1 - // result == 0 6 0 1 - // result == 0 6 2 1 - // result == 0 8 2 -1 - // result == 0 8 2 1 - // result == 0 12 2 -1 - // result == 0 12 0 -1 - // result == 2 6 1 1 - // result == 2 6 0 -1 - // result == 4 4 0 -1 - // result == 4 4 -1 1 - // result == 8 12 0 1 - // result == 8 0 -1 -1 - // result == 8 0 1 1 - // result == 8 12 0 -1 - // result == 12 4 1 -1 - // result == 12 4 0 1 - // result == 14 6 -1 -1 - // result == 14 6 0 1 - // result == 16 4 0 -1 - // result == 16 4 -1 1 - // result == 16 6 0 -1 - // result == 16 6 2 -1 - // result == 16 8 2 1 - // result == 16 8 2 -1 - // result == 16 12 2 1 - // result == 16 12 0 1 - if(result.size() != 28) { - //stdcout << "result size == " << result.size() << "\n"; - //stdcout << "reference size == " << 28 << "\n"; - return false; - } - - stdcout << "done testing Scan45Star4\n"; - return true; - } - - template <typename stream_type> - static inline bool testScan45(stream_type& stdcout) { - if(!testScan45Rect(stdcout)) return false; - if(!testScan45P1(stdcout)) return false; - if(!testScan45P2(stdcout)) return false; - if(!testScan45And(stdcout)) return false; - if(!testScan45Star1(stdcout)) return false; - if(!testScan45Star2(stdcout)) return false; - if(!testScan45Star3(stdcout)) return false; - if(!testScan45Star4(stdcout)) return false; - return true; - } - - }; - -} - -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/iterator_compact_to_points.hpp b/contrib/restricted/boost/boost/polygon/detail/iterator_compact_to_points.hpp deleted file mode 100644 index e0f61d3834..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/iterator_compact_to_points.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - 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_COMPACT_TO_POINTS_HPP -#define BOOST_POLYGON_ITERATOR_COMPACT_TO_POINTS_HPP -namespace boost { namespace polygon{ -template <typename iterator_type, typename point_type> -class iterator_compact_to_points { -private: - iterator_type iter_; - iterator_type iter_end_; - point_type pt_; - typename point_traits<point_type>::coordinate_type firstX_; - orientation_2d orient_; -public: - typedef std::forward_iterator_tag iterator_category; - typedef point_type value_type; - typedef std::ptrdiff_t difference_type; - typedef const point_type* pointer; //immutable - typedef const point_type& reference; //immutable - - inline iterator_compact_to_points() : iter_(), iter_end_(), pt_(), firstX_(), orient_() {} - inline iterator_compact_to_points(iterator_type iter, iterator_type iter_end) : - iter_(iter), iter_end_(iter_end), pt_(), firstX_(), orient_(HORIZONTAL) { - if(iter_ != iter_end_) { - firstX_ = *iter_; - x(pt_, firstX_); - ++iter_; - if(iter_ != iter_end_) { - y(pt_, *iter_); - } - } - } - //use bitwise copy and assign provided by the compiler - inline iterator_compact_to_points& operator++() { - iterator_type prev_iter = iter_; - ++iter_; - if(iter_ == iter_end_) { - if(x(pt_) != firstX_) { - iter_ = prev_iter; - x(pt_, firstX_); - } - } else { - set(pt_, orient_, *iter_); - orient_.turn_90(); - } - return *this; - } - inline const iterator_compact_to_points operator++(int) { - iterator_compact_to_points tmp(*this); - ++(*this); - return tmp; - } - inline bool operator==(const iterator_compact_to_points& that) const { - if (iter_ == iter_end_) { - return iter_ == that.iter_; - } - return (iter_ == that.iter_) && (x(pt_) == x(that.pt_)); - } - inline bool operator!=(const iterator_compact_to_points& that) const { - if (iter_ == iter_end_) { - return iter_ != that.iter_; - } - return (iter_ != that.iter_) || (x(pt_) != x(that.pt_)); - } - inline reference operator*() const { return pt_; } -}; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/iterator_geometry_to_set.hpp b/contrib/restricted/boost/boost/polygon/detail/iterator_geometry_to_set.hpp deleted file mode 100644 index 95840e2001..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/iterator_geometry_to_set.hpp +++ /dev/null @@ -1,314 +0,0 @@ -/* - 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 <typename concept_type, typename geometry_type> -class iterator_geometry_to_set {}; - -template <typename rectangle_type> -class iterator_geometry_to_set<rectangle_concept, rectangle_type> { -public: - typedef typename rectangle_traits<rectangle_type>::coordinate_type coordinate_type; - typedef std::forward_iterator_tag iterator_category; - typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type; - typedef std::ptrdiff_t difference_type; - typedef const value_type* pointer; //immutable - typedef const value_type& reference; //immutable -private: - rectangle_data<coordinate_type> 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 <typename polygon_type> -class iterator_geometry_to_set<polygon_90_concept, polygon_type> { -public: - typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type; - typedef std::forward_iterator_tag iterator_category; - typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > value_type; - typedef std::ptrdiff_t difference_type; - typedef const value_type* pointer; //immutable - typedef const value_type& reference; //immutable - typedef typename polygon_traits<polygon_type>::iterator_type coord_iterator_type; -private: - value_type vertex_; - typename polygon_traits<polygon_type>::iterator_type itrb, itre; - bool last_vertex_; - bool is_hole_; - int multiplier_; - point_data<coordinate_type> 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 <typename polygon_with_holes_type> -class iterator_geometry_to_set<polygon_90_with_holes_concept, polygon_with_holes_type> { -public: - typedef typename polygon_90_traits<polygon_with_holes_type>::coordinate_type coordinate_type; - typedef std::forward_iterator_tag iterator_category; - typedef std::pair<coordinate_type, std::pair<coordinate_type, int> > 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<polygon_90_concept, polygon_with_holes_type> itrb, itre; - iterator_geometry_to_set<polygon_90_concept, typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type> itrhib, itrhie; - typename polygon_with_holes_traits<polygon_with_holes_type>::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_90_concept, polygon_with_holes_type>(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_90_concept, polygon_with_holes_type>(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<polygon_90_concept, - typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_); - itrhie = iterator_geometry_to_set<polygon_90_concept, - typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_); - ++itrhb; - } else { - //in this case we have no holes so we just need the iterhib == itrhie, which - //is always true if they were default initialized in the initial case or - //both point to end of the previous hole processed - //no need to explicitly reset them, and it causes an stl debug assertion to use - //the default constructed iterator this way - //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, - // typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(); - } - } else { - ++itrhib; - if(itrhib == itrhie) { - if(itrhb != itrhe) { - itrhib = iterator_geometry_to_set<polygon_90_concept, - typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_); - itrhie = iterator_geometry_to_set<polygon_90_concept, - typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, HIGH, orient_, !is_hole_); - ++itrhb; - } else { - //this is the same case as above - //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, - // typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(); - } - } - } - } else { - ++itrb; - if(itrb == itre) { - if(itrhb != itrhe) { - itrhib = iterator_geometry_to_set<polygon_90_concept, - typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(*itrhb, LOW, orient_, !is_hole_); - itrhie = iterator_geometry_to_set<polygon_90_concept, - typename polygon_with_holes_traits<polygon_with_holes_type>::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 diff --git a/contrib/restricted/boost/boost/polygon/detail/iterator_points_to_compact.hpp b/contrib/restricted/boost/boost/polygon/detail/iterator_points_to_compact.hpp deleted file mode 100644 index 25ddb15889..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/iterator_points_to_compact.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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_POINTS_TO_COMPACT_HPP -#define BOOST_POLYGON_ITERATOR_POINTS_TO_COMPACT_HPP -namespace boost { namespace polygon{ -template <typename iT, typename point_type> -class iterator_points_to_compact { -private: - iT iter_, iterEnd_; - orientation_2d orient_; - mutable typename point_traits<point_type>::coordinate_type coord_; -public: - typedef typename point_traits<point_type>::coordinate_type coordinate_type; - typedef std::forward_iterator_tag iterator_category; - typedef coordinate_type value_type; - typedef std::ptrdiff_t difference_type; - typedef const coordinate_type* pointer; //immutable - typedef const coordinate_type& reference; //immutable - - inline iterator_points_to_compact() : iter_(), iterEnd_(), orient_(), coord_() {} - inline iterator_points_to_compact(iT iter, iT iterEnd) : - iter_(iter), iterEnd_(iterEnd), orient_(HORIZONTAL), coord_() {} - inline iterator_points_to_compact(const iterator_points_to_compact& that) : - iter_(that.iter_), iterEnd_(that.iterEnd_), orient_(that.orient_), coord_(that.coord_) {} - //use bitwise copy and assign provided by the compiler - inline iterator_points_to_compact& operator++() { - //iT tmp = iter_; - ++iter_; - //iT tmp2 = iter_; - orient_.turn_90(); - //while(tmp2 != iterEnd_ && get(*tmp2, orient_) == get(*tmp, orient_)) { - // iter_ = tmp2; - // ++tmp2; - //} - return *this; - } - inline const iterator_points_to_compact operator++(int) { - iT tmp(*this); - ++(*this); - return tmp; - } - inline bool operator==(const iterator_points_to_compact& that) const { - return (iter_ == that.iter_); - } - inline bool operator!=(const iterator_points_to_compact& that) const { - return (iter_ != that.iter_); - } - inline reference operator*() const { coord_ = get(*iter_, orient_); - return coord_; - } -}; -} -} -#endif - diff --git a/contrib/restricted/boost/boost/polygon/detail/max_cover.hpp b/contrib/restricted/boost/boost/polygon/detail/max_cover.hpp deleted file mode 100644 index f01eac8a7c..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/max_cover.hpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - 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_MAX_COVER_HPP -#define BOOST_POLYGON_MAX_COVER_HPP -namespace boost { namespace polygon{ - - template <typename Unit> - struct MaxCover { - typedef interval_data<Unit> Interval; - typedef rectangle_data<Unit> Rectangle; - - class Node { - private: - std::vector<Node*> children_; - std::set<Interval> tracedPaths_; - public: - Rectangle rect; - Node() : children_(), tracedPaths_(), rect() {} - Node(const Rectangle rectIn) : children_(), tracedPaths_(), rect(rectIn) {} - typedef typename std::vector<Node*>::iterator iterator; - inline iterator begin() { return children_.begin(); } - inline iterator end() { return children_.end(); } - inline void add(Node* child) { children_.push_back(child); } - inline bool tracedPath(const Interval& ivl) const { - return tracedPaths_.find(ivl) != tracedPaths_.end(); - } - inline void addPath(const Interval& ivl) { - tracedPaths_.insert(tracedPaths_.end(), ivl); - } - }; - - typedef std::pair<std::pair<Unit, Interval>, Node* > EdgeAssociation; - - class lessEdgeAssociation { - public: - typedef const EdgeAssociation& first_argument_type; - typedef const EdgeAssociation& second_argument_type; - typedef bool result_type; - inline lessEdgeAssociation() {} - inline bool operator () (const EdgeAssociation& elem1, const EdgeAssociation& elem2) const { - if(elem1.first.first < elem2.first.first) return true; - if(elem1.first.first > elem2.first.first) return false; - return elem1.first.second < elem2.first.second; - } - }; - - template <class cT> - static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient) { - Interval rectIvl = node->rect.get(orient); - if(node->tracedPath(rectIvl)) { - return; - } - node->addPath(rectIvl); - if(node->begin() == node->end()) { - //std::cout << "WRITE OUT 3: " << node->rect << std::endl; - outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(node->rect)); - return; - } - bool writeOut = true; - for(typename Node::iterator itr = node->begin(); itr != node->end(); ++itr) { - getMaxCover(outputContainer, *itr, orient, node->rect); //get rectangles down path - Interval nodeIvl = (*itr)->rect.get(orient); - if(contains(nodeIvl, rectIvl, true)) writeOut = false; - } - if(writeOut) { - //std::cout << "WRITE OUT 2: " << node->rect << std::endl; - outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(node->rect)); - } - } - - struct stack_element { - inline stack_element() : - node(), rect(), itr() {} - inline stack_element(Node* n, - const Rectangle& r, - typename Node::iterator i) : - node(n), rect(r), itr(i) {} - Node* node; - Rectangle rect; - typename Node::iterator itr; - }; - - template <class cT> - static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient, - Rectangle rect) { - //std::cout << "New Root\n"; - std::vector<stack_element> stack; - typename Node::iterator itr = node->begin(); - do { - //std::cout << "LOOP\n"; - //std::cout << node->rect << std::endl; - Interval rectIvl = rect.get(orient); - Interval nodeIvl = node->rect.get(orient); - bool iresult = intersect(rectIvl, nodeIvl, false); - bool tresult = !node->tracedPath(rectIvl); - //std::cout << (itr != node->end()) << " " << iresult << " " << tresult << std::endl; - Rectangle nextRect1 = Rectangle(rectIvl, rectIvl); - Unit low = rect.get(orient.get_perpendicular()).low(); - Unit high = node->rect.get(orient.get_perpendicular()).high(); - nextRect1.set(orient.get_perpendicular(), Interval(low, high)); - if(iresult && tresult) { - node->addPath(rectIvl); - bool writeOut = true; - //check further visibility beyond this node - for(typename Node::iterator itr2 = node->begin(); itr2 != node->end(); ++itr2) { - Interval nodeIvl3 = (*itr2)->rect.get(orient); - //if a child of this node can contain the interval then we can extend through - if(contains(nodeIvl3, rectIvl, true)) writeOut = false; - //std::cout << "child " << (*itr2)->rect << std::endl; - } - Rectangle nextRect2 = Rectangle(rectIvl, rectIvl); - Unit low2 = rect.get(orient.get_perpendicular()).low(); - Unit high2 = node->rect.get(orient.get_perpendicular()).high(); - nextRect2.set(orient.get_perpendicular(), Interval(low2, high2)); - if(writeOut) { - //std::cout << "write out " << nextRect << std::endl; - outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(nextRect2)); - } else { - //std::cout << "suppress " << nextRect << std::endl; - } - } - if(itr != node->end() && iresult && tresult) { - //std::cout << "recurse into child\n"; - stack.push_back(stack_element(node, rect, itr)); - rect = nextRect1; - node = *itr; - itr = node->begin(); - } else { - if(!stack.empty()) { - //std::cout << "recurse out of child\n"; - node = stack.back().node; - rect = stack.back().rect; - itr = stack.back().itr; - stack.pop_back(); - } else { - //std::cout << "empty stack\n"; - //if there were no children of the root node -// Rectangle nextRect = Rectangle(rectIvl, rectIvl); -// Unit low = rect.get(orient.get_perpendicular()).low(); -// Unit high = node->rect.get(orient.get_perpendicular()).high(); -// nextRect.set(orient.get_perpendicular(), Interval(low, high)); -// outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(nextRect)); - } - //std::cout << "increment " << (itr != node->end()) << std::endl; - if(itr != node->end()) { - ++itr; - if(itr != node->end()) { - //std::cout << "recurse into next child.\n"; - stack.push_back(stack_element(node, rect, itr)); - Interval rectIvl2 = rect.get(orient); - Interval nodeIvl2 = node->rect.get(orient); - /*bool iresult =*/ intersect(rectIvl2, nodeIvl2, false); - Rectangle nextRect2 = Rectangle(rectIvl2, rectIvl2); - Unit low2 = rect.get(orient.get_perpendicular()).low(); - Unit high2 = node->rect.get(orient.get_perpendicular()).high(); - nextRect2.set(orient.get_perpendicular(), Interval(low2, high2)); - rect = nextRect2; - //std::cout << "rect for next child" << rect << std::endl; - node = *itr; - itr = node->begin(); - } - } - } - } while(!stack.empty() || itr != node->end()); - } - - /* Function recursive version of getMaxCover - Because the code is so much simpler than the loop algorithm I retain it for clarity - - template <class cT> - static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient, - const Rectangle& rect) { - Interval rectIvl = rect.get(orient); - Interval nodeIvl = node->rect.get(orient); - if(!intersect(rectIvl, nodeIvl, false)) { - return; - } - if(node->tracedPath(rectIvl)) { - return; - } - node->addPath(rectIvl); - Rectangle nextRect(rectIvl, rectIvl); - Unit low = rect.get(orient.get_perpendicular()).low(); - Unit high = node->rect.get(orient.get_perpendicular()).high(); - nextRect.set(orient.get_perpendicular(), Interval(low, high)); - bool writeOut = true; - rectIvl = nextRect.get(orient); - for(typename Node::iterator itr = node->begin(); itr != node->end(); ++itr) { - nodeIvl = (*itr)->rect.get(orient); - if(contains(nodeIvl, rectIvl, true)) writeOut = false; - } - if(writeOut) { - outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(nextRect)); - } - for(typename Node::iterator itr = node->begin(); itr != node->end(); ++itr) { - getMaxCover(outputContainer, *itr, orient, nextRect); - } - } - */ - - //iterator range is assummed to be in topological order meaning all node's trailing - //edges are in sorted order - template <class iT> - static inline void computeDag(iT beginNode, iT endNode, orientation_2d orient, - std::size_t size) { - std::vector<EdgeAssociation> leadingEdges; - leadingEdges.reserve(size); - for(iT iter = beginNode; iter != endNode; ++iter) { - Node* nodep = &(*iter); - Unit leading = nodep->rect.get(orient.get_perpendicular()).low(); - Interval rectIvl = nodep->rect.get(orient); - leadingEdges.push_back(EdgeAssociation(std::pair<Unit, Interval>(leading, rectIvl), nodep)); - } - polygon_sort(leadingEdges.begin(), leadingEdges.end(), lessEdgeAssociation()); - typename std::vector<EdgeAssociation>::iterator leadingBegin = leadingEdges.begin(); - iT trailingBegin = beginNode; - while(leadingBegin != leadingEdges.end()) { - EdgeAssociation& leadingSegment = (*leadingBegin); - Unit trailing = (*trailingBegin).rect.get(orient.get_perpendicular()).high(); - Interval ivl = (*trailingBegin).rect.get(orient); - std::pair<Unit, Interval> trailingSegment(trailing, ivl); - if(leadingSegment.first.first < trailingSegment.first) { - ++leadingBegin; - continue; - } - if(leadingSegment.first.first > trailingSegment.first) { - ++trailingBegin; - continue; - } - if(leadingSegment.first.second.high() <= trailingSegment.second.low()) { - ++leadingBegin; - continue; - } - if(trailingSegment.second.high() <= leadingSegment.first.second.low()) { - ++trailingBegin; - continue; - } - //leading segment intersects trailing segment - (*trailingBegin).add((*leadingBegin).second); - if(leadingSegment.first.second.high() > trailingSegment.second.high()) { - ++trailingBegin; - continue; - } - if(trailingSegment.second.high() > leadingSegment.first.second.high()) { - ++leadingBegin; - continue; - } - ++leadingBegin; - ++trailingBegin; - } - } - - template <class cT> - static inline void getMaxCover(cT& outputContainer, - const std::vector<Rectangle>& rects, orientation_2d orient) { - if(rects.empty()) return; - std::vector<Node> nodes; - { - if(rects.size() == 1) { - outputContainer.push_back(copy_construct<typename cT::value_type, Rectangle>(rects[0])); - return; - } - nodes.reserve(rects.size()); - for(std::size_t i = 0; i < rects.size(); ++i) { nodes.push_back(Node(rects[i])); } - } - computeDag(nodes.begin(), nodes.end(), orient, nodes.size()); - for(std::size_t i = 0; i < nodes.size(); ++i) { - getMaxCover(outputContainer, &(nodes[i]), orient); - } - } - - }; -} -} - -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/minkowski.hpp b/contrib/restricted/boost/boost/polygon/detail/minkowski.hpp deleted file mode 100644 index ce349472c6..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/minkowski.hpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - 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). -*/ -namespace boost { namespace polygon { namespace detail { - -template <typename coordinate_type> -struct minkowski_offset { - typedef point_data<coordinate_type> point; - typedef polygon_set_data<coordinate_type> polygon_set; - typedef polygon_with_holes_data<coordinate_type> polygon; - typedef std::pair<point, point> edge; - - static void convolve_two_segments(std::vector<point>& figure, const edge& a, const edge& b) { - figure.clear(); - figure.push_back(point(a.first)); - figure.push_back(point(a.first)); - figure.push_back(point(a.second)); - figure.push_back(point(a.second)); - convolve(figure[0], b.second); - convolve(figure[1], b.first); - convolve(figure[2], b.first); - convolve(figure[3], b.second); - } - - template <typename itrT1, typename itrT2> - static void convolve_two_point_sequences(polygon_set& result, itrT1 ab, itrT1 ae, itrT2 bb, itrT2 be) { - if(ab == ae || bb == be) - return; - point first_a = *ab; - point prev_a = *ab; - std::vector<point> vec; - polygon poly; - ++ab; - for( ; ab != ae; ++ab) { - point first_b = *bb; - point prev_b = *bb; - itrT2 tmpb = bb; - ++tmpb; - for( ; tmpb != be; ++tmpb) { - convolve_two_segments(vec, std::make_pair(prev_b, *tmpb), std::make_pair(prev_a, *ab)); - set_points(poly, vec.begin(), vec.end()); - result.insert(poly); - prev_b = *tmpb; - } - prev_a = *ab; - } - } - - template <typename itrT> - static void convolve_point_sequence_with_polygons(polygon_set& result, itrT b, itrT e, const std::vector<polygon>& polygons) { - for(std::size_t i = 0; i < polygons.size(); ++i) { - convolve_two_point_sequences(result, b, e, begin_points(polygons[i]), end_points(polygons[i])); - for(typename polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(polygons[i]); - itrh != end_holes(polygons[i]); ++itrh) { - convolve_two_point_sequences(result, b, e, begin_points(*itrh), end_points(*itrh)); - } - } - } - - static void convolve_two_polygon_sets(polygon_set& result, const polygon_set& a, const polygon_set& b) { - result.clear(); - std::vector<polygon> a_polygons; - std::vector<polygon> b_polygons; - a.get(a_polygons); - b.get(b_polygons); - for(std::size_t ai = 0; ai < a_polygons.size(); ++ai) { - convolve_point_sequence_with_polygons(result, begin_points(a_polygons[ai]), - end_points(a_polygons[ai]), b_polygons); - for(typename polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(a_polygons[ai]); - itrh != end_holes(a_polygons[ai]); ++itrh) { - convolve_point_sequence_with_polygons(result, begin_points(*itrh), - end_points(*itrh), b_polygons); - } - for(std::size_t bi = 0; bi < b_polygons.size(); ++bi) { - polygon tmp_poly = a_polygons[ai]; - result.insert(convolve(tmp_poly, *(begin_points(b_polygons[bi])))); - tmp_poly = b_polygons[bi]; - result.insert(convolve(tmp_poly, *(begin_points(a_polygons[ai])))); - } - } - } -}; - -} - template<typename T> - inline polygon_set_data<T>& - polygon_set_data<T>::resize(coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments) { - using namespace ::boost::polygon::operators; - if(!corner_fill_arc) { - if(resizing < 0) - return shrink(-resizing); - if(resizing > 0) - return bloat(resizing); - return *this; - } - if(resizing == 0) return *this; - if(empty()) return *this; - if(num_circle_segments < 3) num_circle_segments = 4; - rectangle_data<coordinate_type> rect; - extents(rect); - if(resizing < 0) { - ::boost::polygon::bloat(rect, 10); - (*this) = rect - (*this); //invert - } - //make_arc(std::vector<point_data< T> >& return_points, - //point_data< double> start, point_data< double> end, - //point_data< double> center, double r, unsigned int num_circle_segments) - std::vector<point_data<coordinate_type> > circle; - point_data<double> center(0.0, 0.0), start(0.0, (double)resizing); - make_arc(circle, start, start, center, std::abs((double)resizing), - num_circle_segments); - polygon_data<coordinate_type> poly; - set_points(poly, circle.begin(), circle.end()); - polygon_set_data<coordinate_type> offset_set; - offset_set += poly; - polygon_set_data<coordinate_type> result; - detail::minkowski_offset<coordinate_type>::convolve_two_polygon_sets - (result, *this, offset_set); - if(resizing < 0) { - result = result & rect;//eliminate overhang - result = result ^ rect;//invert - } - *this = result; - return *this; - } - -}} diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_45_formation.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_45_formation.hpp deleted file mode 100644 index 7034986938..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_45_formation.hpp +++ /dev/null @@ -1,2238 +0,0 @@ -/* - 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_POLYGON_45_FORMATION_HPP -#define BOOST_POLYGON_POLYGON_45_FORMATION_HPP -namespace boost { namespace polygon{ - - template <typename T, typename T2> - struct PolyLineByConcept {}; - - template <typename T> - class PolyLine45PolygonData; - template <typename T> - class PolyLine45HoleData; - - //polygon45formation algorithm - template <typename Unit> - struct polygon_45_formation : public boolean_op_45<Unit> { - typedef point_data<Unit> Point; - typedef polygon_45_data<Unit> Polygon45; - typedef polygon_45_with_holes_data<Unit> Polygon45WithHoles; - typedef typename boolean_op_45<Unit>::Vertex45 Vertex45; - typedef typename boolean_op_45<Unit>::lessVertex45 lessVertex45; - typedef typename boolean_op_45<Unit>::Count2 Count2; - typedef typename boolean_op_45<Unit>::Scan45Count Scan45Count; - typedef std::pair<Point, Scan45Count> Scan45Vertex; - typedef typename boolean_op_45<Unit>::template - Scan45<Count2, typename boolean_op_45<Unit>::template boolean_op_45_output_functor<0> > Scan45; - - class PolyLine45 { - public: - typedef typename std::list<Point>::const_iterator iterator; - - // default constructor of point does not initialize x and y - inline PolyLine45() : points() {} //do nothing default constructor - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline PolyLine45& set(iT inputBegin, iT inputEnd) { - points.clear(); //just in case there was some old data there - while(inputBegin != inputEnd) { - points.insert(points.end(), *inputBegin); - ++inputBegin; - } - return *this; - } - - // copy constructor (since we have dynamic memory) - inline PolyLine45(const PolyLine45& that) : points(that.points) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline PolyLine45& operator=(const PolyLine45& that) { - points = that.points; - return *this; - } - - // get begin iterator, returns a pointer to a const Unit - inline iterator begin() const { return points.begin(); } - - // get end iterator, returns a pointer to a const Unit - inline iterator end() const { return points.end(); } - - inline std::size_t size() const { return points.size(); } - - //public data member - std::list<Point> points; - }; - - class ActiveTail45 { - private: - //data - PolyLine45* tailp_; - ActiveTail45 *otherTailp_; - std::list<ActiveTail45*> holesList_; - bool head_; - public: - - /** - * @brief iterator over coordinates of the figure - */ - typedef typename PolyLine45::iterator iterator; - - /** - * @brief iterator over holes contained within the figure - */ - typedef typename std::list<ActiveTail45*>::const_iterator iteratorHoles; - - //default constructor - inline ActiveTail45() : tailp_(0), otherTailp_(0), holesList_(), head_(0) {} - - //constructor - inline ActiveTail45(const Vertex45& vertex, ActiveTail45* otherTailp = 0) : - tailp_(0), otherTailp_(0), holesList_(), head_(0) { - tailp_ = new PolyLine45; - tailp_->points.push_back(vertex.pt); - bool headArray[4] = {false, true, true, true}; - bool inverted = vertex.count == -1; - head_ = headArray[vertex.rise+1] ^ inverted; - otherTailp_ = otherTailp; - } - - inline ActiveTail45(Point point, ActiveTail45* otherTailp, bool head = true) : - tailp_(0), otherTailp_(0), holesList_(), head_(0) { - tailp_ = new PolyLine45; - tailp_->points.push_back(point); - head_ = head; - otherTailp_ = otherTailp; - - } - inline ActiveTail45(ActiveTail45* otherTailp) : - tailp_(0), otherTailp_(0), holesList_(), head_(0) { - tailp_ = otherTailp->tailp_; - otherTailp_ = otherTailp; - } - - //copy constructor - inline ActiveTail45(const ActiveTail45& that) : - tailp_(0), otherTailp_(0), holesList_(), head_(0) { (*this) = that; } - - //destructor - inline ~ActiveTail45() { - destroyContents(); - } - - //assignment operator - inline ActiveTail45& operator=(const ActiveTail45& that) { - tailp_ = new PolyLine45(*(that.tailp_)); - head_ = that.head_; - otherTailp_ = that.otherTailp_; - holesList_ = that.holesList_; - return *this; - } - - //equivalence operator - inline bool operator==(const ActiveTail45& b) const { - return tailp_ == b.tailp_ && head_ == b.head_; - } - - /** - * @brief get the pointer to the polyline that this is an active tail of - */ - inline PolyLine45* getTail() const { return tailp_; } - - /** - * @brief get the pointer to the polyline at the other end of the chain - */ - inline PolyLine45* getOtherTail() const { return otherTailp_->tailp_; } - - /** - * @brief get the pointer to the activetail at the other end of the chain - */ - inline ActiveTail45* getOtherActiveTail() const { return otherTailp_; } - - /** - * @brief test if another active tail is the other end of the chain - */ - inline bool isOtherTail(const ActiveTail45& b) const { return &b == otherTailp_; } - - /** - * @brief update this end of chain pointer to new polyline - */ - inline ActiveTail45& updateTail(PolyLine45* newTail) { tailp_ = newTail; return *this; } - - inline bool join(ActiveTail45* tail) { - if(tail == otherTailp_) { - //std::cout << "joining to other tail!\n"; - return false; - } - if(tail->head_ == head_) { - //std::cout << "joining head to head!\n"; - return false; - } - if(!tailp_) { - //std::cout << "joining empty tail!\n"; - return false; - } - if(!(otherTailp_->head_)) { - otherTailp_->copyHoles(*tail); - otherTailp_->copyHoles(*this); - } else { - tail->otherTailp_->copyHoles(*this); - tail->otherTailp_->copyHoles(*tail); - } - PolyLine45* tail1 = tailp_; - PolyLine45* tail2 = tail->tailp_; - if(head_) std::swap(tail1, tail2); - tail1->points.splice(tail1->points.end(), tail2->points); - delete tail2; - otherTailp_->tailp_ = tail1; - tail->otherTailp_->tailp_ = tail1; - otherTailp_->otherTailp_ = tail->otherTailp_; - tail->otherTailp_->otherTailp_ = otherTailp_; - tailp_ = 0; - tail->tailp_ = 0; - tail->otherTailp_ = 0; - otherTailp_ = 0; - return true; - } - - /** - * @brief associate a hole to this active tail by the specified policy - */ - inline ActiveTail45* addHole(ActiveTail45* hole) { - holesList_.push_back(hole); - copyHoles(*hole); - copyHoles(*(hole->otherTailp_)); - return this; - } - - /** - * @brief get the list of holes - */ - inline const std::list<ActiveTail45*>& getHoles() const { return holesList_; } - - /** - * @brief copy holes from that to this - */ - inline void copyHoles(ActiveTail45& that) { holesList_.splice(holesList_.end(), that.holesList_); } - - /** - * @brief find out if solid to right - */ - inline bool solidToRight() const { return !head_; } - inline bool solidToLeft() const { return head_; } - - /** - * @brief get vertex - */ - inline Point getPoint() const { - if(head_) return tailp_->points.front(); - return tailp_->points.back(); - } - - /** - * @brief add a coordinate to the polygon at this active tail end, properly handle degenerate edges by removing redundant coordinate - */ - inline void pushPoint(Point point) { - if(head_) { - //if(tailp_->points.size() < 2) { - // tailp_->points.push_front(point); - // return; - //} - typename std::list<Point>::iterator iter = tailp_->points.begin(); - if(iter == tailp_->points.end()) { - tailp_->points.push_front(point); - return; - } - Unit firstY = (*iter).y(); - Unit firstX = (*iter).x(); - ++iter; - if(iter == tailp_->points.end()) { - tailp_->points.push_front(point); - return; - } - if((iter->y() == point.y() && firstY == point.y()) || - (iter->x() == point.x() && firstX == point.x())){ - --iter; - *iter = point; - } else { - tailp_->points.push_front(point); - } - return; - } - //if(tailp_->points.size() < 2) { - // tailp_->points.push_back(point); - // return; - //} - typename std::list<Point>::reverse_iterator iter = tailp_->points.rbegin(); - if(iter == tailp_->points.rend()) { - tailp_->points.push_back(point); - return; - } - Unit firstY = (*iter).y(); - Unit firstX = (*iter).x(); - ++iter; - if(iter == tailp_->points.rend()) { - tailp_->points.push_back(point); - return; - } - if((iter->y() == point.y() && firstY == point.y()) || - (iter->x() == point.x() && firstX == point.x())){ - --iter; - *iter = point; - } else { - tailp_->points.push_back(point); - } - } - - /** - * @brief joins the two chains that the two active tail tails are ends of - * checks for closure of figure and writes out polygons appropriately - * returns a handle to a hole if one is closed - */ - - template <class cT> - static inline ActiveTail45* joinChains(Point point, ActiveTail45* at1, ActiveTail45* at2, bool solid, - cT& output) { - if(at1->otherTailp_ == at2) { - //if(at2->otherTailp_ != at1) std::cout << "half closed error\n"; - //we are closing a figure - at1->pushPoint(point); - at2->pushPoint(point); - if(solid) { - //we are closing a solid figure, write to output - //std::cout << "test1\n"; - at1->copyHoles(*(at1->otherTailp_)); - //std::cout << "test2\n"; - //Polygon45WithHolesImpl<PolyLine45PolygonData> poly(polyData); - //std::cout << poly << "\n"; - //std::cout << "test3\n"; - typedef typename cT::value_type pType; - output.push_back(pType()); - typedef typename geometry_concept<pType>::type cType; - typename PolyLineByConcept<Unit, cType>::type polyData(at1); - assign(output.back(), polyData); - //std::cout << "test4\n"; - //std::cout << "delete " << at1->otherTailp_ << "\n"; - //at1->print(); - //at1->otherTailp_->print(); - delete at1->otherTailp_; - //at1->print(); - //at1->otherTailp_->print(); - //std::cout << "test5\n"; - //std::cout << "delete " << at1 << "\n"; - delete at1; - //std::cout << "test6\n"; - return 0; - } else { - //we are closing a hole, return the tail end active tail of the figure - return at1; - } - } - //we are not closing a figure - at1->pushPoint(point); - at1->join(at2); - delete at1; - delete at2; - return 0; - } - - inline void destroyContents() { - if(otherTailp_) { - //std::cout << "delete p " << tailp_ << "\n"; - if(tailp_) delete tailp_; - tailp_ = 0; - otherTailp_->otherTailp_ = 0; - otherTailp_->tailp_ = 0; - otherTailp_ = 0; - } - for(typename std::list<ActiveTail45*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) { - //std::cout << "delete p " << (*itr) << "\n"; - if(*itr) { - if((*itr)->otherTailp_) { - delete (*itr)->otherTailp_; - (*itr)->otherTailp_ = 0; - } - delete (*itr); - } - (*itr) = 0; - } - holesList_.clear(); - } - -// inline void print() { -// std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n"; -// } - - static inline std::pair<ActiveTail45*, ActiveTail45*> createActiveTail45sAsPair(Point point, bool solid, - ActiveTail45* phole, bool fractureHoles) { - ActiveTail45* at1 = 0; - ActiveTail45* at2 = 0; - if(phole && fractureHoles) { - //std::cout << "adding hole\n"; - at1 = phole; - //assert solid == false, we should be creating a corner with solid below and to the left if there was a hole - at2 = at1->getOtherActiveTail(); - at2->pushPoint(point); - at1->pushPoint(point); - } else { - at1 = new ActiveTail45(point, at2, solid); - at2 = new ActiveTail45(at1); - at1->otherTailp_ = at2; - at2->head_ = !solid; - if(phole) - at2->addHole(phole); //assert fractureHoles == false - } - return std::pair<ActiveTail45*, ActiveTail45*>(at1, at2); - } - - }; - - template <typename ct> - class Vertex45CountT { - public: - typedef ct count_type; - inline Vertex45CountT() -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { counts[0] = counts[1] = counts[2] = counts[3] = 0; } - //inline Vertex45CountT(ct count) { counts[0] = counts[1] = counts[2] = counts[3] = count; } - inline Vertex45CountT(const ct& count1, const ct& count2, const ct& count3, - const ct& count4) -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { - counts[0] = count1; - counts[1] = count2; - counts[2] = count3; - counts[3] = count4; - } - inline Vertex45CountT(const Vertex45& vertex) -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { - counts[0] = counts[1] = counts[2] = counts[3] = 0; - (*this) += vertex; - } - inline Vertex45CountT(const Vertex45CountT& count) -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { - (*this) = count; - } - inline bool operator==(const Vertex45CountT& count) const { - for(unsigned int i = 0; i < 4; ++i) { - if(counts[i] != count.counts[i]) return false; - } - return true; - } - inline bool operator!=(const Vertex45CountT& count) const { return !((*this) == count); } - inline Vertex45CountT& operator=(ct count) { - counts[0] = counts[1] = counts[2] = counts[3] = count; return *this; } - inline Vertex45CountT& operator=(const Vertex45CountT& count) { - for(unsigned int i = 0; i < 4; ++i) { - counts[i] = count.counts[i]; - } - return *this; - } - inline ct& operator[](int index) { return counts[index]; } - inline ct operator[](int index) const {return counts[index]; } - inline Vertex45CountT& operator+=(const Vertex45CountT& count){ - for(unsigned int i = 0; i < 4; ++i) { - counts[i] += count.counts[i]; - } - return *this; - } - inline Vertex45CountT& operator-=(const Vertex45CountT& count){ - for(unsigned int i = 0; i < 4; ++i) { - counts[i] -= count.counts[i]; - } - return *this; - } - inline Vertex45CountT operator+(const Vertex45CountT& count) const { - return Vertex45CountT(*this)+=count; - } - inline Vertex45CountT operator-(const Vertex45CountT& count) const { - return Vertex45CountT(*this)-=count; - } - inline Vertex45CountT invert() const { - return Vertex45CountT()-=(*this); - } - inline Vertex45CountT& operator+=(const Vertex45& element){ - counts[element.rise+1] += element.count; return *this; - } - inline bool is_45() const { - return counts[0] != 0 || counts[2] != 0; - } - private: - ct counts[4]; - }; - - typedef Vertex45CountT<int> Vertex45Count; - -// inline std::ostream& operator<< (std::ostream& o, const Vertex45Count& c) { -// o << c[0] << ", " << c[1] << ", "; -// o << c[2] << ", " << c[3]; -// return o; -// } - - template <typename ct> - class Vertex45CompactT { - public: - Point pt; - ct count; - typedef typename boolean_op_45<Unit>::template Vertex45T<typename ct::count_type> Vertex45T; - inline Vertex45CompactT() : pt(), count() {} - inline Vertex45CompactT(const Point& point, int riseIn, int countIn) : pt(point), count() { - count[riseIn+1] = countIn; - } - template <typename ct2> - inline Vertex45CompactT(const typename boolean_op_45<Unit>::template Vertex45T<ct2>& vertex) : pt(vertex.pt), count() { - count[vertex.rise+1] = vertex.count; - } - inline Vertex45CompactT(const Vertex45CompactT& vertex) : pt(vertex.pt), count(vertex.count) {} - inline Vertex45CompactT& operator=(const Vertex45CompactT& vertex){ - pt = vertex.pt; count = vertex.count; return *this; } - inline bool operator==(const Vertex45CompactT& vertex) const { - return pt == vertex.pt && count == vertex.count; } - inline bool operator!=(const Vertex45CompactT& vertex) const { return !((*this) == vertex); } - inline bool operator<(const Vertex45CompactT& vertex) const { - if(pt.x() < vertex.pt.x()) return true; - if(pt.x() == vertex.pt.x()) { - return pt.y() < vertex.pt.y(); - } - return false; - } - inline bool operator>(const Vertex45CompactT& vertex) const { return vertex < (*this); } - inline bool operator<=(const Vertex45CompactT& vertex) const { return !((*this) > vertex); } - inline bool operator>=(const Vertex45CompactT& vertex) const { return !((*this) < vertex); } - inline bool haveVertex45(int index) const { return count[index]; } - inline Vertex45T operator[](int index) const { - return Vertex45T(pt, index-1, count[index]); } - }; - - typedef Vertex45CompactT<Vertex45Count> Vertex45Compact; - -// inline std::ostream& operator<< (std::ostream& o, const Vertex45Compact& c) { -// o << c.pt << ", " << c.count; -// return o; -// } - - class Polygon45Formation { - private: - //definitions - typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData; - typedef typename Polygon45FormationData::iterator iterator; - typedef typename Polygon45FormationData::const_iterator const_iterator; - - //data - Polygon45FormationData scanData_; - Unit x_; - int justBefore_; - int fractureHoles_; - public: - inline Polygon45Formation() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { - lessVertex45 lessElm(&x_, &justBefore_); - scanData_ = Polygon45FormationData(lessElm); - } - inline Polygon45Formation(bool fractureHoles) : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(fractureHoles) { - lessVertex45 lessElm(&x_, &justBefore_); - scanData_ = Polygon45FormationData(lessElm); - } - inline Polygon45Formation(const Polygon45Formation& that) : - scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { (*this) = that; } - inline Polygon45Formation& operator=(const Polygon45Formation& that) { - x_ = that.x_; - justBefore_ = that.justBefore_; - fractureHoles_ = that.fractureHoles_; - lessVertex45 lessElm(&x_, &justBefore_); - scanData_ = Polygon45FormationData(lessElm); - for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){ - scanData_.insert(scanData_.end(), *itr); - } - return *this; - } - - //cT is an output container of Polygon45 or Polygon45WithHoles - //iT is an iterator over Vertex45 elements - //inputBegin - inputEnd is a range of sorted iT that represents - //one or more scanline stops worth of data - template <class cT, class iT> - void scan(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "1\n"; - while(inputBegin != inputEnd) { - //std::cout << "2\n"; - x_ = (*inputBegin).pt.x(); - //std::cout << "SCAN FORMATION " << x_ << "\n"; - //std::cout << "x_ = " << x_ << "\n"; - //std::cout << "scan line size: " << scanData_.size() << "\n"; - inputBegin = processEvent_(output, inputBegin, inputEnd); - } - } - - private: - //functions - template <class cT, class cT2> - inline std::pair<int, ActiveTail45*> processPoint_(cT& output, cT2& elements, Point point, - Vertex45Count& counts, ActiveTail45** tails, Vertex45Count& incoming) { - //std::cout << point << "\n"; - //std::cout << counts[0] << " "; - //std::cout << counts[1] << " "; - //std::cout << counts[2] << " "; - //std::cout << counts[3] << "\n"; - //std::cout << incoming[0] << " "; - //std::cout << incoming[1] << " "; - //std::cout << incoming[2] << " "; - //std::cout << incoming[3] << "\n"; - //join any closing solid corners - ActiveTail45* returnValue = 0; - int returnCount = 0; - for(int i = 0; i < 3; ++i) { - //std::cout << i << "\n"; - if(counts[i] == -1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < 4; ++j) { - //std::cout << j << "\n"; - if(counts[j]) { - if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << "\n"; - //if a figure is closed it will be written out by this function to output - ActiveTail45::joinChains(point, tails[i], tails[j], true, output); - counts[i] = 0; - counts[j] = 0; - tails[i] = 0; - tails[j] = 0; - } - break; - } - } - } - } - //find any pairs of incoming edges that need to create pair for leading solid - //std::cout << "checking case2\n"; - for(int i = 0; i < 3; ++i) { - //std::cout << i << "\n"; - if(incoming[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < 4; ++j) { - //std::cout << j << "\n"; - if(incoming[j]) { - if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << "\n"; - //std::cout << "creating active tail pair\n"; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = - ActiveTail45::createActiveTail45sAsPair(point, true, 0, fractureHoles_ != 0); - //tailPair.first->print(); - //tailPair.second->print(); - if(j == 3) { - //vertical active tail becomes return value - returnValue = tailPair.first; - returnCount = 1; - } else { - Vertex45 vertex(point, i -1, incoming[i]); - //std::cout << "new element " << j-1 << " " << -1 << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, -1), tailPair.first)); - } - //std::cout << "new element " << i-1 << " " << 1 << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, 1), tailPair.second)); - incoming[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - } - - //find any active tail that needs to pass through to an incoming edge - //we expect to find no more than two pass through - - //find pass through with solid on top - //std::cout << "checking case 3\n"; - for(int i = 0; i < 4; ++i) { - //std::cout << i << "\n"; - if(counts[i] != 0) { - if(counts[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = 3; j >= 0; --j) { - if(incoming[j] != 0) { - if(incoming[j] == 1) { - //std::cout << "case3: " << i << " " << j << "\n"; - //tails[i]->print(); - //pass through solid on top - tails[i]->pushPoint(point); - //std::cout << "after push\n"; - if(j == 3) { - returnValue = tails[i]; - returnCount = -1; - } else { - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i])); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - //std::cout << "checking case 4\n"; - //find pass through with solid on bottom - for(int i = 3; i >= 0; --i) { - if(counts[i] != 0) { - if(counts[i] == -1) { - for(int j = 0; j < 4; ++j) { - if(incoming[j] != 0) { - if(incoming[j] == -1) { - //std::cout << "case4: " << i << " " << j << "\n"; - //pass through solid on bottom - tails[i]->pushPoint(point); - if(j == 3) { - returnValue = tails[i]; - returnCount = 1; - } else { - //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i])); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - - //find the end of a hole or the beginning of a hole - - //find end of a hole - for(int i = 0; i < 3; ++i) { - if(counts[i] != 0) { - for(int j = i+1; j < 4; ++j) { - if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << "\n"; - //we are ending a hole and may potentially close a figure and have to handle the hole - returnValue = ActiveTail45::joinChains(point, tails[i], tails[j], false, output); - tails[i] = 0; - tails[j] = 0; - counts[i] = 0; - counts[j] = 0; - break; - } - } - break; - } - } - //find beginning of a hole - for(int i = 0; i < 3; ++i) { - if(incoming[i] != 0) { - for(int j = i+1; j < 4; ++j) { - if(incoming[j] != 0) { - //std::cout << "case6: " << i << " " << j << "\n"; - //we are beginning a empty space - ActiveTail45* holep = 0; - if(counts[3] == 0) holep = tails[3]; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = - ActiveTail45::createActiveTail45sAsPair(point, false, holep, fractureHoles_ != 0); - if(j == 3) { - returnValue = tailPair.first; - returnCount = -1; - } else { - //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.first)); - } - //std::cout << "new element " << i-1 << " " << incoming[i] << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, incoming[i]), tailPair.second)); - incoming[i] = 0; - incoming[j] = 0; - break; - } - } - break; - } - } - //assert that tails, counts and incoming are all null - return std::pair<int, ActiveTail45*>(returnCount, returnValue); - } - - template <class cT, class iT> - inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "processEvent_\n"; - justBefore_ = true; - //collect up all elements from the tree that are at the y - //values of events in the input queue - //create vector of new elements to add into tree - ActiveTail45* verticalTail = 0; - int verticalCount = 0; - iT currentIter = inputBegin; - std::vector<iterator> elementIters; - std::vector<std::pair<Vertex45, ActiveTail45*> > elements; - while(currentIter != inputEnd && currentIter->pt.x() == x_) { - //std::cout << "loop\n"; - Unit currentY = (*currentIter).pt.y(); - iterator iter = lookUp_(currentY); - //int counts[4] = {0, 0, 0, 0}; - Vertex45Count counts; - ActiveTail45* tails[4] = {0, 0, 0, verticalTail}; - //std::cout << "finding elements in tree\n"; - while(iter != scanData_.end() && - iter->first.evalAtX(x_) == currentY) { - //std::cout << "loop2\n"; - elementIters.push_back(iter); - int index = iter->first.rise + 1; - //std::cout << index << " " << iter->first.count << "\n"; - counts[index] = iter->first.count; - tails[index] = iter->second; - ++iter; - } - //int incoming[4] = {0, 0, 0, 0}; - Vertex45Count incoming; - //std::cout << "aggregating\n"; - do { - //std::cout << "loop3\n"; - Vertex45Compact currentVertex(*currentIter); - incoming += currentVertex.count; - ++currentIter; - } while(currentIter != inputEnd && currentIter->pt.y() == currentY && - currentIter->pt.x() == x_); - //now counts and tails have the data from the left and - //incoming has the data from the right at this point - //cancel out any end points - //std::cout << counts[0] << " "; - //std::cout << counts[1] << " "; - //std::cout << counts[2] << " "; - //std::cout << counts[3] << "\n"; - //std::cout << incoming[0] << " "; - //std::cout << incoming[1] << " "; - //std::cout << incoming[2] << " "; - //std::cout << incoming[3] << "\n"; - if(verticalTail) { - counts[3] = -verticalCount; - } - incoming[3] *= -1; - for(unsigned int i = 0; i < 4; ++i) incoming[i] += counts[i]; - //std::cout << "calling processPoint_\n"; - std::pair<int, ActiveTail45*> result = processPoint_(output, elements, Point(x_, currentY), counts, tails, incoming); - verticalCount = result.first; - verticalTail = result.second; - //if(verticalTail) std::cout << "have vertical tail\n"; - //std::cout << "verticalCount: " << verticalCount << "\n"; - if(verticalTail && !verticalCount) { - //we got a hole out of the point we just processed - //iter is still at the next y element above the current y value in the tree - //std::cout << "checking whether ot handle hole\n"; - if(currentIter == inputEnd || - currentIter->pt.x() != x_ || - currentIter->pt.y() >= iter->first.evalAtX(x_)) { - //std::cout << "handle hole here\n"; - if(fractureHoles_) { - //std::cout << "fracture hole here\n"; - //we need to handle the hole now and not at the next input vertex - ActiveTail45* at = iter->second; - Point point(x_, iter->first.evalAtX(x_)); - verticalTail->getOtherActiveTail()->pushPoint(point); - iter->second = verticalTail->getOtherActiveTail(); - at->pushPoint(point); - verticalTail->join(at); - delete at; - delete verticalTail; - verticalTail = 0; - } else { - //std::cout << "push hole onto list\n"; - iter->second->addHole(verticalTail); - verticalTail = 0; - } - } - } - } - //std::cout << "erasing\n"; - //erase all elements from the tree - for(typename std::vector<iterator>::iterator iter = elementIters.begin(); - iter != elementIters.end(); ++iter) { - //std::cout << "erasing loop\n"; - scanData_.erase(*iter); - } - //switch comparison tie breaking policy - justBefore_ = false; - //add new elements into tree - //std::cout << "inserting\n"; - for(typename std::vector<std::pair<Vertex45, ActiveTail45*> >::iterator iter = elements.begin(); - iter != elements.end(); ++iter) { - //std::cout << "inserting loop\n"; - scanData_.insert(scanData_.end(), *iter); - } - //std::cout << "end processEvent\n"; - return currentIter; - } - - inline iterator lookUp_(Unit y){ - //if just before then we need to look from 1 not -1 - return scanData_.lower_bound(Vertex45(Point(x_, y), -1+2*justBefore_, 0)); - } - - }; - - template <typename stream_type> - static inline bool testPolygon45FormationRect(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(true); - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 2, 1)); - data.push_back(Vertex45(Point(10, 10), 0, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45FormationP1(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(true); - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 1, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 1, -1)); - data.push_back(Vertex45(Point(10, 10), 1, -1)); - data.push_back(Vertex45(Point(10, 10), 2, -1)); - data.push_back(Vertex45(Point(10, 20), 2, 1)); - data.push_back(Vertex45(Point(10, 20), 1, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - //polygon45set class - - template <typename stream_type> - static inline bool testPolygon45FormationP2(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(true); - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 1, -1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 1, 1)); - data.push_back(Vertex45(Point(10, 10), 1, 1)); - data.push_back(Vertex45(Point(10, 10), 0, -1)); - data.push_back(Vertex45(Point(20, 10), 1, -1)); - data.push_back(Vertex45(Point(20, 10), 0, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - //polygon45set class - - template <typename stream_type> - static inline bool testPolygon45FormationStar1(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(true); - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - // result == 0 8 -1 1 - data.push_back(Vertex45(Point(0, 8), -1, 1)); - // result == 0 8 1 -1 - data.push_back(Vertex45(Point(0, 8), 1, -1)); - // result == 4 0 1 1 - data.push_back(Vertex45(Point(4, 0), 1, 1)); - // result == 4 0 2 1 - data.push_back(Vertex45(Point(4, 0), 2, 1)); - // result == 4 4 2 -1 - data.push_back(Vertex45(Point(4, 4), 2, -1)); - // result == 4 4 -1 -1 - data.push_back(Vertex45(Point(4, 4), -1, -1)); - // result == 4 12 1 1 - data.push_back(Vertex45(Point(4, 12), 1, 1)); - // result == 4 12 2 1 - data.push_back(Vertex45(Point(4, 12), 2, 1)); - // result == 4 16 2 -1 - data.push_back(Vertex45(Point(4, 16), 2, 1)); - // result == 4 16 -1 -1 - data.push_back(Vertex45(Point(4, 16), -1, -1)); - // result == 6 2 1 -1 - data.push_back(Vertex45(Point(6, 2), 1, -1)); - // result == 6 14 -1 1 - data.push_back(Vertex45(Point(6, 14), -1, 1)); - // result == 6 2 -1 1 - data.push_back(Vertex45(Point(6, 2), -1, 1)); - // result == 6 14 1 -1 - data.push_back(Vertex45(Point(6, 14), 1, -1)); - // result == 8 0 -1 -1 - data.push_back(Vertex45(Point(8, 0), -1, -1)); - // result == 8 0 2 -1 - data.push_back(Vertex45(Point(8, 0), 2, -1)); - // result == 8 4 2 1 - data.push_back(Vertex45(Point(8, 4), 2, 1)); - // result == 8 4 1 1 - data.push_back(Vertex45(Point(8, 4), 1, 1)); - // result == 8 12 -1 -1 - data.push_back(Vertex45(Point(8, 12), -1, -1)); - // result == 8 12 2 -1 - data.push_back(Vertex45(Point(8, 12), 2, -1)); - // result == 8 16 2 1 - data.push_back(Vertex45(Point(8, 16), 2, 1)); - // result == 8 16 1 1 - data.push_back(Vertex45(Point(8, 16), 1, 1)); - // result == 12 8 1 -1 - data.push_back(Vertex45(Point(12, 8), 1, -1)); - // result == 12 8 -1 1 - data.push_back(Vertex45(Point(12, 8), -1, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45FormationStar2(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(true); - std::vector<Polygon45> polys; - Scan45 scan45; - std::vector<Vertex45 > result; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - - polygon_sort(result.begin(), result.end()); - pf.scan(polys, result.begin(), result.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45FormationStarHole1(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(true); - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - // result == 0 8 -1 1 - data.push_back(Vertex45(Point(0, 8), -1, 1)); - // result == 0 8 1 -1 - data.push_back(Vertex45(Point(0, 8), 1, -1)); - // result == 4 0 1 1 - data.push_back(Vertex45(Point(4, 0), 1, 1)); - // result == 4 0 2 1 - data.push_back(Vertex45(Point(4, 0), 2, 1)); - // result == 4 4 2 -1 - data.push_back(Vertex45(Point(4, 4), 2, -1)); - // result == 4 4 -1 -1 - data.push_back(Vertex45(Point(4, 4), -1, -1)); - // result == 4 12 1 1 - data.push_back(Vertex45(Point(4, 12), 1, 1)); - // result == 4 12 2 1 - data.push_back(Vertex45(Point(4, 12), 2, 1)); - // result == 4 16 2 -1 - data.push_back(Vertex45(Point(4, 16), 2, 1)); - // result == 4 16 -1 -1 - data.push_back(Vertex45(Point(4, 16), -1, -1)); - // result == 6 2 1 -1 - data.push_back(Vertex45(Point(6, 2), 1, -1)); - // result == 6 14 -1 1 - data.push_back(Vertex45(Point(6, 14), -1, 1)); - // result == 6 2 -1 1 - data.push_back(Vertex45(Point(6, 2), -1, 1)); - // result == 6 14 1 -1 - data.push_back(Vertex45(Point(6, 14), 1, -1)); - // result == 8 0 -1 -1 - data.push_back(Vertex45(Point(8, 0), -1, -1)); - // result == 8 0 2 -1 - data.push_back(Vertex45(Point(8, 0), 2, -1)); - // result == 8 4 2 1 - data.push_back(Vertex45(Point(8, 4), 2, 1)); - // result == 8 4 1 1 - data.push_back(Vertex45(Point(8, 4), 1, 1)); - // result == 8 12 -1 -1 - data.push_back(Vertex45(Point(8, 12), -1, -1)); - // result == 8 12 2 -1 - data.push_back(Vertex45(Point(8, 12), 2, -1)); - // result == 8 16 2 1 - data.push_back(Vertex45(Point(8, 16), 2, 1)); - // result == 8 16 1 1 - data.push_back(Vertex45(Point(8, 16), 1, 1)); - // result == 12 8 1 -1 - data.push_back(Vertex45(Point(12, 8), 1, -1)); - // result == 12 8 -1 1 - data.push_back(Vertex45(Point(12, 8), -1, 1)); - - data.push_back(Vertex45(Point(6, 4), 1, -1)); - data.push_back(Vertex45(Point(6, 4), 2, -1)); - data.push_back(Vertex45(Point(6, 8), -1, 1)); - data.push_back(Vertex45(Point(6, 8), 2, 1)); - data.push_back(Vertex45(Point(8, 6), -1, -1)); - data.push_back(Vertex45(Point(8, 6), 1, 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45FormationStarHole2(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(false); - std::vector<Polygon45WithHoles> polys; - std::vector<Vertex45> data; - // result == 0 8 -1 1 - data.push_back(Vertex45(Point(0, 8), -1, 1)); - // result == 0 8 1 -1 - data.push_back(Vertex45(Point(0, 8), 1, -1)); - // result == 4 0 1 1 - data.push_back(Vertex45(Point(4, 0), 1, 1)); - // result == 4 0 2 1 - data.push_back(Vertex45(Point(4, 0), 2, 1)); - // result == 4 4 2 -1 - data.push_back(Vertex45(Point(4, 4), 2, -1)); - // result == 4 4 -1 -1 - data.push_back(Vertex45(Point(4, 4), -1, -1)); - // result == 4 12 1 1 - data.push_back(Vertex45(Point(4, 12), 1, 1)); - // result == 4 12 2 1 - data.push_back(Vertex45(Point(4, 12), 2, 1)); - // result == 4 16 2 -1 - data.push_back(Vertex45(Point(4, 16), 2, 1)); - // result == 4 16 -1 -1 - data.push_back(Vertex45(Point(4, 16), -1, -1)); - // result == 6 2 1 -1 - data.push_back(Vertex45(Point(6, 2), 1, -1)); - // result == 6 14 -1 1 - data.push_back(Vertex45(Point(6, 14), -1, 1)); - // result == 6 2 -1 1 - data.push_back(Vertex45(Point(6, 2), -1, 1)); - // result == 6 14 1 -1 - data.push_back(Vertex45(Point(6, 14), 1, -1)); - // result == 8 0 -1 -1 - data.push_back(Vertex45(Point(8, 0), -1, -1)); - // result == 8 0 2 -1 - data.push_back(Vertex45(Point(8, 0), 2, -1)); - // result == 8 4 2 1 - data.push_back(Vertex45(Point(8, 4), 2, 1)); - // result == 8 4 1 1 - data.push_back(Vertex45(Point(8, 4), 1, 1)); - // result == 8 12 -1 -1 - data.push_back(Vertex45(Point(8, 12), -1, -1)); - // result == 8 12 2 -1 - data.push_back(Vertex45(Point(8, 12), 2, -1)); - // result == 8 16 2 1 - data.push_back(Vertex45(Point(8, 16), 2, 1)); - // result == 8 16 1 1 - data.push_back(Vertex45(Point(8, 16), 1, 1)); - // result == 12 8 1 -1 - data.push_back(Vertex45(Point(12, 8), 1, -1)); - // result == 12 8 -1 1 - data.push_back(Vertex45(Point(12, 8), -1, 1)); - - data.push_back(Vertex45(Point(6, 4), 1, -1)); - data.push_back(Vertex45(Point(6, 4), 2, -1)); - data.push_back(Vertex45(Point(6, 12), -1, 1)); - data.push_back(Vertex45(Point(6, 12), 2, 1)); - data.push_back(Vertex45(Point(10, 8), -1, -1)); - data.push_back(Vertex45(Point(10, 8), 1, 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45Formation(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - Polygon45Formation pf(false); - std::vector<Polygon45WithHoles> polys; - std::vector<Vertex45> data; - - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 100), 2, -1)); - data.push_back(Vertex45(Point(0, 100), 0, -1)); - data.push_back(Vertex45(Point(100, 0), 0, -1)); - data.push_back(Vertex45(Point(100, 0), 2, -1)); - data.push_back(Vertex45(Point(100, 100), 2, 1)); - data.push_back(Vertex45(Point(100, 100), 0, 1)); - - data.push_back(Vertex45(Point(2, 2), 0, -1)); - data.push_back(Vertex45(Point(2, 2), 2, -1)); - data.push_back(Vertex45(Point(2, 10), 2, 1)); - data.push_back(Vertex45(Point(2, 10), 0, 1)); - data.push_back(Vertex45(Point(10, 2), 0, 1)); - data.push_back(Vertex45(Point(10, 2), 2, 1)); - data.push_back(Vertex45(Point(10, 10), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 0, -1)); - - data.push_back(Vertex45(Point(2, 12), 0, -1)); - data.push_back(Vertex45(Point(2, 12), 2, -1)); - data.push_back(Vertex45(Point(2, 22), 2, 1)); - data.push_back(Vertex45(Point(2, 22), 0, 1)); - data.push_back(Vertex45(Point(10, 12), 0, 1)); - data.push_back(Vertex45(Point(10, 12), 2, 1)); - data.push_back(Vertex45(Point(10, 22), 2, -1)); - data.push_back(Vertex45(Point(10, 22), 0, -1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - - class Polygon45Tiling { - private: - //definitions - typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData; - typedef typename Polygon45FormationData::iterator iterator; - typedef typename Polygon45FormationData::const_iterator const_iterator; - - //data - Polygon45FormationData scanData_; - Unit x_; - int justBefore_; - public: - inline Polygon45Tiling() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false) { - lessVertex45 lessElm(&x_, &justBefore_); - scanData_ = Polygon45FormationData(lessElm); - } - inline Polygon45Tiling(const Polygon45Tiling& that) : - scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false) { (*this) = that; } - inline Polygon45Tiling& operator=(const Polygon45Tiling& that) { - x_ = that.x_; - justBefore_ = that.justBefore_; - lessVertex45 lessElm(&x_, &justBefore_); - scanData_ = Polygon45FormationData(lessElm); - for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){ - scanData_.insert(scanData_.end(), *itr); - } - return *this; - } - - //cT is an output container of Polygon45 or Polygon45WithHoles - //iT is an iterator over Vertex45 elements - //inputBegin - inputEnd is a range of sorted iT that represents - //one or more scanline stops worth of data - template <class cT, class iT> - void scan(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "1\n"; - while(inputBegin != inputEnd) { - //std::cout << "2\n"; - x_ = (*inputBegin).pt.x(); - //std::cout << "SCAN FORMATION " << x_ << "\n"; - //std::cout << "x_ = " << x_ << "\n"; - //std::cout << "scan line size: " << scanData_.size() << "\n"; - inputBegin = processEvent_(output, inputBegin, inputEnd); - } - } - - private: - //functions - - inline void getVerticalPair_(std::pair<ActiveTail45*, ActiveTail45*>& verticalPair, - iterator previter) { - ActiveTail45* iterTail = (*previter).second; - Point prevPoint(x_, previter->first.evalAtX(x_)); - iterTail->pushPoint(prevPoint); - std::pair<ActiveTail45*, ActiveTail45*> tailPair = - ActiveTail45::createActiveTail45sAsPair(prevPoint, true, 0, false); - verticalPair.first = iterTail; - verticalPair.second = tailPair.first; - (*previter).second = tailPair.second; - } - - template <class cT, class cT2> - inline std::pair<int, ActiveTail45*> processPoint_(cT& output, cT2& elements, - std::pair<ActiveTail45*, ActiveTail45*>& verticalPair, - iterator previter, Point point, - Vertex45Count& counts, ActiveTail45** tails, Vertex45Count& incoming) { - //std::cout << point << "\n"; - //std::cout << counts[0] << " "; - //std::cout << counts[1] << " "; - //std::cout << counts[2] << " "; - //std::cout << counts[3] << "\n"; - //std::cout << incoming[0] << " "; - //std::cout << incoming[1] << " "; - //std::cout << incoming[2] << " "; - //std::cout << incoming[3] << "\n"; - //join any closing solid corners - ActiveTail45* returnValue = 0; - std::pair<ActiveTail45*, ActiveTail45*> verticalPairOut; - verticalPairOut.first = 0; - verticalPairOut.second = 0; - int returnCount = 0; - for(int i = 0; i < 3; ++i) { - //std::cout << i << "\n"; - if(counts[i] == -1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < 4; ++j) { - //std::cout << j << "\n"; - if(counts[j]) { - if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << "\n"; - //if a figure is closed it will be written out by this function to output - ActiveTail45::joinChains(point, tails[i], tails[j], true, output); - counts[i] = 0; - counts[j] = 0; - tails[i] = 0; - tails[j] = 0; - } - break; - } - } - } - } - //find any pairs of incoming edges that need to create pair for leading solid - //std::cout << "checking case2\n"; - for(int i = 0; i < 3; ++i) { - //std::cout << i << "\n"; - if(incoming[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < 4; ++j) { - //std::cout << j << "\n"; - if(incoming[j]) { - if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << "\n"; - //std::cout << "creating active tail pair\n"; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = - ActiveTail45::createActiveTail45sAsPair(point, true, 0, false); - //tailPair.first->print(); - //tailPair.second->print(); - if(j == 3) { - //vertical active tail becomes return value - returnValue = tailPair.first; - returnCount = 1; - } else { - Vertex45 vertex(point, i -1, incoming[i]); - //std::cout << "new element " << j-1 << " " << -1 << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, -1), tailPair.first)); - } - //std::cout << "new element " << i-1 << " " << 1 << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, 1), tailPair.second)); - incoming[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - } - - //find any active tail that needs to pass through to an incoming edge - //we expect to find no more than two pass through - - //find pass through with solid on top - //std::cout << "checking case 3\n"; - for(int i = 0; i < 4; ++i) { - //std::cout << i << "\n"; - if(counts[i] != 0) { - if(counts[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = 3; j >= 0; --j) { - if(incoming[j] != 0) { - if(incoming[j] == 1) { - //std::cout << "case3: " << i << " " << j << "\n"; - //tails[i]->print(); - //pass through solid on top - if(i != 3) - tails[i]->pushPoint(point); - //std::cout << "after push\n"; - if(j == 3) { - returnValue = tails[i]; - returnCount = -1; - } else { - verticalPairOut.first = tails[i]; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = - ActiveTail45::createActiveTail45sAsPair(point, true, 0, false); - verticalPairOut.second = tailPair.first; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), - tailPair.second)); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - //std::cout << "checking case 4\n"; - //find pass through with solid on bottom - for(int i = 3; i >= 0; --i) { - if(counts[i] != 0) { - if(counts[i] == -1) { - for(int j = 0; j < 4; ++j) { - if(incoming[j] != 0) { - if(incoming[j] == -1) { - //std::cout << "case4: " << i << " " << j << "\n"; - //pass through solid on bottom - if(i == 3) { - //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; - if(j == 3) { - returnValue = tails[i]; - returnCount = 1; - } else { - tails[i]->pushPoint(point); - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i])); - } - } else if(j == 3) { - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output); - returnValue = verticalPair.second; - returnCount = 1; - } else { - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output); - verticalPair.second->pushPoint(point); - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), - verticalPair.second)); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - - //find the end of a hole or the beginning of a hole - - //find end of a hole - for(int i = 0; i < 3; ++i) { - if(counts[i] != 0) { - for(int j = i+1; j < 4; ++j) { - if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << "\n"; - //we are ending a hole and may potentially close a figure and have to handle the hole - tails[i]->pushPoint(point); - verticalPairOut.first = tails[i]; - if(j == 3) { - verticalPairOut.second = tails[j]; - } else { - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - ActiveTail45::joinChains(point, tails[j], verticalPair.first, true, output); - verticalPairOut.second = verticalPair.second; - } - tails[i] = 0; - tails[j] = 0; - counts[i] = 0; - counts[j] = 0; - break; - } - } - break; - } - } - //find beginning of a hole - for(int i = 0; i < 3; ++i) { - if(incoming[i] != 0) { - for(int j = i+1; j < 4; ++j) { - if(incoming[j] != 0) { - //std::cout << "case6: " << i << " " << j << "\n"; - //we are beginning a empty space - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - verticalPair.second->pushPoint(point); - if(j == 3) { - returnValue = verticalPair.first; - returnCount = -1; - } else { - std::pair<ActiveTail45*, ActiveTail45*> tailPair = - ActiveTail45::createActiveTail45sAsPair(point, true, 0, false); - //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.second)); - verticalPairOut.second = tailPair.first; - verticalPairOut.first = verticalPair.first; - } - //std::cout << "new element " << i-1 << " " << incoming[i] << "\n"; - elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, incoming[i]), verticalPair.second)); - incoming[i] = 0; - incoming[j] = 0; - break; - } - } - break; - } - } - verticalPair = verticalPairOut; - //assert that verticalPair is either both null, or neither null - //assert that returnValue is null if verticalPair is not null - //assert that tails, counts and incoming are all null - return std::pair<int, ActiveTail45*>(returnCount, returnValue); - } - - template <class cT, class iT> - inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "processEvent_\n"; - justBefore_ = true; - //collect up all elements from the tree that are at the y - //values of events in the input queue - //create vector of new elements to add into tree - ActiveTail45* verticalTail = 0; - std::pair<ActiveTail45*, ActiveTail45*> verticalPair; - verticalPair.first = 0; - verticalPair.second = 0; - int verticalCount = 0; - iT currentIter = inputBegin; - std::vector<iterator> elementIters; - std::vector<std::pair<Vertex45, ActiveTail45*> > elements; - while(currentIter != inputEnd && currentIter->pt.x() == x_) { - //std::cout << "loop\n"; - Unit currentY = (*currentIter).pt.y(); - iterator iter = lookUp_(currentY); - //int counts[4] = {0, 0, 0, 0}; - Vertex45Count counts; - ActiveTail45* tails[4] = {0, 0, 0, verticalTail}; - //std::cout << "finding elements in tree\n"; - iterator previter = iter; - if(previter != scanData_.end() && - previter->first.evalAtX(x_) >= currentY && - previter != scanData_.begin()) - --previter; - while(iter != scanData_.end() && - iter->first.evalAtX(x_) == currentY) { - //std::cout << "loop2\n"; - elementIters.push_back(iter); - int index = iter->first.rise + 1; - //std::cout << index << " " << iter->first.count << "\n"; - counts[index] = iter->first.count; - tails[index] = iter->second; - ++iter; - } - //int incoming[4] = {0, 0, 0, 0}; - Vertex45Count incoming; - //std::cout << "aggregating\n"; - do { - //std::cout << "loop3\n"; - Vertex45Compact currentVertex(*currentIter); - incoming += currentVertex.count; - ++currentIter; - } while(currentIter != inputEnd && currentIter->pt.y() == currentY && - currentIter->pt.x() == x_); - //now counts and tails have the data from the left and - //incoming has the data from the right at this point - //cancel out any end points - //std::cout << counts[0] << " "; - //std::cout << counts[1] << " "; - //std::cout << counts[2] << " "; - //std::cout << counts[3] << "\n"; - //std::cout << incoming[0] << " "; - //std::cout << incoming[1] << " "; - //std::cout << incoming[2] << " "; - //std::cout << incoming[3] << "\n"; - if(verticalTail) { - counts[3] = -verticalCount; - } - incoming[3] *= -1; - for(unsigned int i = 0; i < 4; ++i) incoming[i] += counts[i]; - //std::cout << "calling processPoint_\n"; - std::pair<int, ActiveTail45*> result = processPoint_(output, elements, verticalPair, previter, - Point(x_, currentY), counts, tails, incoming); - verticalCount = result.first; - verticalTail = result.second; - if(verticalPair.first != 0 && iter != scanData_.end() && - (currentIter == inputEnd || currentIter->pt.x() != x_ || - currentIter->pt.y() > (*iter).first.evalAtX(x_))) { - //splice vertical pair into edge above - ActiveTail45* tailabove = (*iter).second; - Point point(x_, (*iter).first.evalAtX(x_)); - verticalPair.second->pushPoint(point); - ActiveTail45::joinChains(point, tailabove, verticalPair.first, true, output); - (*iter).second = verticalPair.second; - verticalPair.first = 0; - verticalPair.second = 0; - } - } - //std::cout << "erasing\n"; - //erase all elements from the tree - for(typename std::vector<iterator>::iterator iter = elementIters.begin(); - iter != elementIters.end(); ++iter) { - //std::cout << "erasing loop\n"; - scanData_.erase(*iter); - } - //switch comparison tie breaking policy - justBefore_ = false; - //add new elements into tree - //std::cout << "inserting\n"; - for(typename std::vector<std::pair<Vertex45, ActiveTail45*> >::iterator iter = elements.begin(); - iter != elements.end(); ++iter) { - //std::cout << "inserting loop\n"; - scanData_.insert(scanData_.end(), *iter); - } - //std::cout << "end processEvent\n"; - return currentIter; - } - - inline iterator lookUp_(Unit y){ - //if just before then we need to look from 1 not -1 - return scanData_.lower_bound(Vertex45(Point(x_, y), -1+2*justBefore_, 0)); - } - - }; - - template <typename stream_type> - static inline bool testPolygon45TilingRect(stream_type& stdcout) { - stdcout << "testing polygon tiling\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 2, 1)); - data.push_back(Vertex45(Point(10, 10), 0, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingP1(stream_type& stdcout) { - stdcout << "testing polygon tiling\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 1, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 1, -1)); - data.push_back(Vertex45(Point(10, 10), 1, -1)); - data.push_back(Vertex45(Point(10, 10), 2, -1)); - data.push_back(Vertex45(Point(10, 20), 2, 1)); - data.push_back(Vertex45(Point(10, 20), 1, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingP2(stream_type& stdcout) { - stdcout << "testing polygon tiling\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 1, -1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 1, 1)); - data.push_back(Vertex45(Point(10, 10), 1, 1)); - data.push_back(Vertex45(Point(10, 10), 0, -1)); - data.push_back(Vertex45(Point(20, 10), 1, -1)); - data.push_back(Vertex45(Point(20, 10), 0, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingP3(stream_type& stdcout) { - stdcout << "testing polygon tiling\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 0, -1)); - data.push_back(Vertex45(Point(20, 0), 0, -1)); - data.push_back(Vertex45(Point(20, 0), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 1, -1)); - data.push_back(Vertex45(Point(10, 10), 0, 1)); - data.push_back(Vertex45(Point(20, 20), 1, 1)); - data.push_back(Vertex45(Point(20, 20), 2, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingP4(stream_type& stdcout) { - stdcout << "testing polygon tiling p4\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 0, -1)); - data.push_back(Vertex45(Point(10, 0), -1, 1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(20, 10), 2, 1)); - data.push_back(Vertex45(Point(20, 10), 0, 1)); - data.push_back(Vertex45(Point(20, -10), -1, -1)); - data.push_back(Vertex45(Point(20, -10), 2, -1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingP5(stream_type& stdcout) { - stdcout << "testing polygon tiling P5\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 2, 1)); - data.push_back(Vertex45(Point(10, 10), 0, 1)); - - data.push_back(Vertex45(Point(1, 1), 0, -1)); - data.push_back(Vertex45(Point(1, 1), 1, 1)); - data.push_back(Vertex45(Point(2, 1), 0, 1)); - data.push_back(Vertex45(Point(2, 1), 1, -1)); - data.push_back(Vertex45(Point(2, 2), 1, -1)); - data.push_back(Vertex45(Point(2, 2), 0, 1)); - data.push_back(Vertex45(Point(3, 2), 1, 1)); - data.push_back(Vertex45(Point(3, 2), 0, -1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingP6(stream_type& stdcout) { - stdcout << "testing polygon tiling P6\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 10), 2, -1)); - data.push_back(Vertex45(Point(0, 10), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 0, -1)); - data.push_back(Vertex45(Point(10, 0), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 2, 1)); - data.push_back(Vertex45(Point(10, 10), 0, 1)); - - data.push_back(Vertex45(Point(1, 1), 0, -1)); - data.push_back(Vertex45(Point(1, 1), 2, -1)); - data.push_back(Vertex45(Point(1, 2), 2, 1)); - data.push_back(Vertex45(Point(1, 2), 0, 1)); - data.push_back(Vertex45(Point(2, 1), 0, 1)); - data.push_back(Vertex45(Point(2, 1), 2, 1)); - data.push_back(Vertex45(Point(2, 2), 2, -1)); - data.push_back(Vertex45(Point(2, 2), 0, -1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingStar1(stream_type& stdcout) { - stdcout << "testing polygon tiling star1\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - // result == 0 8 -1 1 - data.push_back(Vertex45(Point(0, 8), -1, 1)); - // result == 0 8 1 -1 - data.push_back(Vertex45(Point(0, 8), 1, -1)); - // result == 4 0 1 1 - data.push_back(Vertex45(Point(4, 0), 1, 1)); - // result == 4 0 2 1 - data.push_back(Vertex45(Point(4, 0), 2, 1)); - // result == 4 4 2 -1 - data.push_back(Vertex45(Point(4, 4), 2, -1)); - // result == 4 4 -1 -1 - data.push_back(Vertex45(Point(4, 4), -1, -1)); - // result == 4 12 1 1 - data.push_back(Vertex45(Point(4, 12), 1, 1)); - // result == 4 12 2 1 - data.push_back(Vertex45(Point(4, 12), 2, 1)); - // result == 4 16 2 -1 - data.push_back(Vertex45(Point(4, 16), 2, 1)); - // result == 4 16 -1 -1 - data.push_back(Vertex45(Point(4, 16), -1, -1)); - // result == 6 2 1 -1 - data.push_back(Vertex45(Point(6, 2), 1, -1)); - // result == 6 14 -1 1 - data.push_back(Vertex45(Point(6, 14), -1, 1)); - // result == 6 2 -1 1 - data.push_back(Vertex45(Point(6, 2), -1, 1)); - // result == 6 14 1 -1 - data.push_back(Vertex45(Point(6, 14), 1, -1)); - // result == 8 0 -1 -1 - data.push_back(Vertex45(Point(8, 0), -1, -1)); - // result == 8 0 2 -1 - data.push_back(Vertex45(Point(8, 0), 2, -1)); - // result == 8 4 2 1 - data.push_back(Vertex45(Point(8, 4), 2, 1)); - // result == 8 4 1 1 - data.push_back(Vertex45(Point(8, 4), 1, 1)); - // result == 8 12 -1 -1 - data.push_back(Vertex45(Point(8, 12), -1, -1)); - // result == 8 12 2 -1 - data.push_back(Vertex45(Point(8, 12), 2, -1)); - // result == 8 16 2 1 - data.push_back(Vertex45(Point(8, 16), 2, 1)); - // result == 8 16 1 1 - data.push_back(Vertex45(Point(8, 16), 1, 1)); - // result == 12 8 1 -1 - data.push_back(Vertex45(Point(12, 8), 1, -1)); - // result == 12 8 -1 1 - data.push_back(Vertex45(Point(12, 8), -1, 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingStar2(stream_type& stdcout) { - stdcout << "testing polygon tiling\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - - Scan45 scan45; - std::vector<Vertex45 > result; - std::vector<Scan45Vertex> vertices; - //is a Rectnagle(0, 0, 10, 10); - Count2 count(1, 0); - Count2 ncount(-1, 0); - vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - count = Count2(0, 1); - ncount = count.invert(); - vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0)))); - vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0)))); - sortScan45Vector(vertices); - stdcout << "scanning\n"; - scan45.scan(result, vertices.begin(), vertices.end()); - - polygon_sort(result.begin(), result.end()); - pf.scan(polys, result.begin(), result.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingStarHole1(stream_type& stdcout) { - stdcout << "testing polygon tiling star hole 1\n"; - Polygon45Tiling pf; - std::vector<Polygon45> polys; - std::vector<Vertex45> data; - // result == 0 8 -1 1 - data.push_back(Vertex45(Point(0, 8), -1, 1)); - // result == 0 8 1 -1 - data.push_back(Vertex45(Point(0, 8), 1, -1)); - // result == 4 0 1 1 - data.push_back(Vertex45(Point(4, 0), 1, 1)); - // result == 4 0 2 1 - data.push_back(Vertex45(Point(4, 0), 2, 1)); - // result == 4 4 2 -1 - data.push_back(Vertex45(Point(4, 4), 2, -1)); - // result == 4 4 -1 -1 - data.push_back(Vertex45(Point(4, 4), -1, -1)); - // result == 4 12 1 1 - data.push_back(Vertex45(Point(4, 12), 1, 1)); - // result == 4 12 2 1 - data.push_back(Vertex45(Point(4, 12), 2, 1)); - // result == 4 16 2 -1 - data.push_back(Vertex45(Point(4, 16), 2, 1)); - // result == 4 16 -1 -1 - data.push_back(Vertex45(Point(4, 16), -1, -1)); - // result == 6 2 1 -1 - data.push_back(Vertex45(Point(6, 2), 1, -1)); - // result == 6 14 -1 1 - data.push_back(Vertex45(Point(6, 14), -1, 1)); - // result == 6 2 -1 1 - data.push_back(Vertex45(Point(6, 2), -1, 1)); - // result == 6 14 1 -1 - data.push_back(Vertex45(Point(6, 14), 1, -1)); - // result == 8 0 -1 -1 - data.push_back(Vertex45(Point(8, 0), -1, -1)); - // result == 8 0 2 -1 - data.push_back(Vertex45(Point(8, 0), 2, -1)); - // result == 8 4 2 1 - data.push_back(Vertex45(Point(8, 4), 2, 1)); - // result == 8 4 1 1 - data.push_back(Vertex45(Point(8, 4), 1, 1)); - // result == 8 12 -1 -1 - data.push_back(Vertex45(Point(8, 12), -1, -1)); - // result == 8 12 2 -1 - data.push_back(Vertex45(Point(8, 12), 2, -1)); - // result == 8 16 2 1 - data.push_back(Vertex45(Point(8, 16), 2, 1)); - // result == 8 16 1 1 - data.push_back(Vertex45(Point(8, 16), 1, 1)); - // result == 12 8 1 -1 - data.push_back(Vertex45(Point(12, 8), 1, -1)); - // result == 12 8 -1 1 - data.push_back(Vertex45(Point(12, 8), -1, 1)); - - data.push_back(Vertex45(Point(6, 4), 1, -1)); - data.push_back(Vertex45(Point(6, 4), 2, -1)); - data.push_back(Vertex45(Point(6, 8), -1, 1)); - data.push_back(Vertex45(Point(6, 8), 2, 1)); - data.push_back(Vertex45(Point(8, 6), -1, -1)); - data.push_back(Vertex45(Point(8, 6), 1, 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45TilingStarHole2(stream_type& stdcout) { - stdcout << "testing polygon tiling star hole 2\n"; - Polygon45Tiling pf; - std::vector<Polygon45WithHoles> polys; - std::vector<Vertex45> data; - // result == 0 8 -1 1 - data.push_back(Vertex45(Point(0, 8), -1, 1)); - // result == 0 8 1 -1 - data.push_back(Vertex45(Point(0, 8), 1, -1)); - // result == 4 0 1 1 - data.push_back(Vertex45(Point(4, 0), 1, 1)); - // result == 4 0 2 1 - data.push_back(Vertex45(Point(4, 0), 2, 1)); - // result == 4 4 2 -1 - data.push_back(Vertex45(Point(4, 4), 2, -1)); - // result == 4 4 -1 -1 - data.push_back(Vertex45(Point(4, 4), -1, -1)); - // result == 4 12 1 1 - data.push_back(Vertex45(Point(4, 12), 1, 1)); - // result == 4 12 2 1 - data.push_back(Vertex45(Point(4, 12), 2, 1)); - // result == 4 16 2 -1 - data.push_back(Vertex45(Point(4, 16), 2, 1)); - // result == 4 16 -1 -1 - data.push_back(Vertex45(Point(4, 16), -1, -1)); - // result == 6 2 1 -1 - data.push_back(Vertex45(Point(6, 2), 1, -1)); - // result == 6 14 -1 1 - data.push_back(Vertex45(Point(6, 14), -1, 1)); - // result == 6 2 -1 1 - data.push_back(Vertex45(Point(6, 2), -1, 1)); - // result == 6 14 1 -1 - data.push_back(Vertex45(Point(6, 14), 1, -1)); - // result == 8 0 -1 -1 - data.push_back(Vertex45(Point(8, 0), -1, -1)); - // result == 8 0 2 -1 - data.push_back(Vertex45(Point(8, 0), 2, -1)); - // result == 8 4 2 1 - data.push_back(Vertex45(Point(8, 4), 2, 1)); - // result == 8 4 1 1 - data.push_back(Vertex45(Point(8, 4), 1, 1)); - // result == 8 12 -1 -1 - data.push_back(Vertex45(Point(8, 12), -1, -1)); - // result == 8 12 2 -1 - data.push_back(Vertex45(Point(8, 12), 2, -1)); - // result == 8 16 2 1 - data.push_back(Vertex45(Point(8, 16), 2, 1)); - // result == 8 16 1 1 - data.push_back(Vertex45(Point(8, 16), 1, 1)); - // result == 12 8 1 -1 - data.push_back(Vertex45(Point(12, 8), 1, -1)); - // result == 12 8 -1 1 - data.push_back(Vertex45(Point(12, 8), -1, 1)); - - data.push_back(Vertex45(Point(6, 4), 1, -1)); - data.push_back(Vertex45(Point(6, 4), 2, -1)); - data.push_back(Vertex45(Point(6, 12), -1, 1)); - data.push_back(Vertex45(Point(6, 12), 2, 1)); - data.push_back(Vertex45(Point(10, 8), -1, -1)); - data.push_back(Vertex45(Point(10, 8), 1, 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygon45Tiling(stream_type& stdcout) { - stdcout << "testing polygon tiling\n"; - Polygon45Tiling pf; - std::vector<Polygon45WithHoles> polys; - std::vector<Vertex45> data; - - data.push_back(Vertex45(Point(0, 0), 0, 1)); - data.push_back(Vertex45(Point(0, 0), 2, 1)); - data.push_back(Vertex45(Point(0, 100), 2, -1)); - data.push_back(Vertex45(Point(0, 100), 0, -1)); - data.push_back(Vertex45(Point(100, 0), 0, -1)); - data.push_back(Vertex45(Point(100, 0), 2, -1)); - data.push_back(Vertex45(Point(100, 100), 2, 1)); - data.push_back(Vertex45(Point(100, 100), 0, 1)); - - data.push_back(Vertex45(Point(2, 2), 0, -1)); - data.push_back(Vertex45(Point(2, 2), 2, -1)); - data.push_back(Vertex45(Point(2, 10), 2, 1)); - data.push_back(Vertex45(Point(2, 10), 0, 1)); - data.push_back(Vertex45(Point(10, 2), 0, 1)); - data.push_back(Vertex45(Point(10, 2), 2, 1)); - data.push_back(Vertex45(Point(10, 10), 2, -1)); - data.push_back(Vertex45(Point(10, 10), 0, -1)); - - data.push_back(Vertex45(Point(2, 12), 0, -1)); - data.push_back(Vertex45(Point(2, 12), 2, -1)); - data.push_back(Vertex45(Point(2, 22), 2, 1)); - data.push_back(Vertex45(Point(2, 22), 0, 1)); - data.push_back(Vertex45(Point(10, 12), 0, 1)); - data.push_back(Vertex45(Point(10, 12), 2, 1)); - data.push_back(Vertex45(Point(10, 22), 2, -1)); - data.push_back(Vertex45(Point(10, 22), 0, -1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon tiling\n"; - return true; - } - }; - - template <typename Unit> - class PolyLine45HoleData { - public: - typedef typename polygon_45_formation<Unit>::ActiveTail45 ActiveTail45; - typedef typename ActiveTail45::iterator iterator; - - typedef polygon_45_concept geometry_type; - typedef Unit coordinate_type; - typedef point_data<Unit> Point; - typedef Point point_type; - // typedef iterator_points_to_compact<iterator, Point> compact_iterator_type; - typedef iterator iterator_type; - typedef typename coordinate_traits<Unit>::area_type area_type; - - inline PolyLine45HoleData() : p_(0) {} - inline PolyLine45HoleData(ActiveTail45* p) : p_(p) {} - //use default copy and assign - inline iterator begin() const { return p_->getTail()->begin(); } - inline iterator end() const { return p_->getTail()->end(); } - inline std::size_t size() const { return 0; } - private: - ActiveTail45* p_; - }; - - template <typename Unit> - class PolyLine45PolygonData { - public: - typedef typename polygon_45_formation<Unit>::ActiveTail45 ActiveTail45; - typedef typename ActiveTail45::iterator iterator; - typedef PolyLine45HoleData<Unit> holeType; - - typedef polygon_45_with_holes_concept geometry_type; - typedef Unit coordinate_type; - typedef point_data<Unit> Point; - typedef Point point_type; - // typedef iterator_points_to_compact<iterator, Point> compact_iterator_type; - typedef iterator iterator_type; - typedef holeType hole_type; - typedef typename coordinate_traits<Unit>::area_type area_type; - class iteratorHoles { - private: - typename ActiveTail45::iteratorHoles itr_; - public: - typedef PolyLine45HoleData<Unit> holeType; - typedef holeType value_type; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; - typedef const value_type* pointer; //immutable - typedef const value_type& reference; //immutable - inline iteratorHoles() : itr_() {} - inline iteratorHoles(typename ActiveTail45::iteratorHoles itr) : itr_(itr) {} - inline iteratorHoles(const iteratorHoles& that) : itr_(that.itr_) {} - inline iteratorHoles& operator=(const iteratorHoles& that) { - itr_ = that.itr_; - return *this; - } - inline bool operator==(const iteratorHoles& that) { return itr_ == that.itr_; } - inline bool operator!=(const iteratorHoles& that) { return itr_ != that.itr_; } - inline iteratorHoles& operator++() { - ++itr_; - return *this; - } - inline const iteratorHoles operator++(int) { - iteratorHoles tmp = *this; - ++(*this); - return tmp; - } - inline holeType operator*() { - return *itr_; - } - }; - typedef iteratorHoles iterator_holes_type; - - - inline PolyLine45PolygonData() : p_(0) {} - inline PolyLine45PolygonData(ActiveTail45* p) : p_(p) {} - //use default copy and assign - inline iterator begin() const { return p_->getTail()->begin(); } - inline iterator end() const { return p_->getTail()->end(); } - inline iteratorHoles begin_holes() const { return iteratorHoles(p_->getHoles().begin()); } - inline iteratorHoles end_holes() const { return iteratorHoles(p_->getHoles().end()); } - inline ActiveTail45* yield() { return p_; } - //stub out these four required functions that will not be used but are needed for the interface - inline std::size_t size_holes() const { return 0; } - inline std::size_t size() const { return 0; } - private: - ActiveTail45* p_; - }; - - template <typename T> - struct PolyLineByConcept<T, polygon_45_with_holes_concept> { typedef PolyLine45PolygonData<T> type; }; - template <typename T> - struct PolyLineByConcept<T, polygon_with_holes_concept> { typedef PolyLine45PolygonData<T> type; }; - template <typename T> - struct PolyLineByConcept<T, polygon_45_concept> { typedef PolyLine45HoleData<T> type; }; - template <typename T> - struct PolyLineByConcept<T, polygon_concept> { typedef PolyLine45HoleData<T> type; }; - - template <typename T> - struct geometry_concept<PolyLine45PolygonData<T> > { typedef polygon_45_with_holes_concept type; }; - template <typename T> - struct geometry_concept<PolyLine45HoleData<T> > { typedef polygon_45_concept type; }; - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_45_set_view.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_45_set_view.hpp deleted file mode 100644 index a0dc0463bc..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_45_set_view.hpp +++ /dev/null @@ -1,380 +0,0 @@ -/* - 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_POLYGON_45_SET_VIEW_HPP -#define BOOST_POLYGON_POLYGON_45_SET_VIEW_HPP -namespace boost { namespace polygon{ - - template <typename ltype, typename rtype, int op_type> - class polygon_45_set_view; - - template <typename ltype, typename rtype, int op_type> - struct polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> > { - typedef typename polygon_45_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type; - typedef typename polygon_45_set_view<ltype, rtype, op_type>::iterator_type iterator_type; - typedef typename polygon_45_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type; - - static inline iterator_type begin(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set); - static inline iterator_type end(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set); - - template <typename input_iterator_type> - static inline void set(polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set, - input_iterator_type input_begin, input_iterator_type input_end); - - static inline bool clean(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set); - - }; - - template <typename value_type, typename ltype, typename rtype, int op_type> - struct compute_45_set_value { - static - void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_) { - output_.set(polygon_45_set_traits<ltype>::begin(lvalue_), - polygon_45_set_traits<ltype>::end(lvalue_)); - value_type rinput_; - rinput_.set(polygon_45_set_traits<rtype>::begin(rvalue_), - polygon_45_set_traits<rtype>::end(rvalue_)); -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op_type == 0) - output_ |= rinput_; - else if(op_type == 1) - output_ &= rinput_; - else if(op_type == 2) - output_ ^= rinput_; - else - output_ -= rinput_; -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - } - }; - - template <typename value_type, typename ltype, typename rcoord, int op_type> - struct compute_45_set_value<value_type, ltype, polygon_45_set_data<rcoord>, op_type> { - static - void value(value_type& output_, const ltype& lvalue_, const polygon_45_set_data<rcoord>& rvalue_) { - output_.set(polygon_45_set_traits<ltype>::begin(lvalue_), - polygon_45_set_traits<ltype>::end(lvalue_)); -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op_type == 0) - output_ |= rvalue_; - else if(op_type == 1) - output_ &= rvalue_; - else if(op_type == 2) - output_ ^= rvalue_; - else - output_ -= rvalue_; -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - } - }; - - template <typename ltype, typename rtype, int op_type> - class polygon_45_set_view { - public: - typedef typename polygon_45_set_traits<ltype>::coordinate_type coordinate_type; - typedef polygon_45_set_data<coordinate_type> value_type; - typedef typename value_type::iterator_type iterator_type; - typedef polygon_45_set_view operator_arg_type; - private: - const ltype& lvalue_; - const rtype& rvalue_; - mutable value_type output_; - mutable bool evaluated_; - - polygon_45_set_view& operator=(const polygon_45_set_view&); - public: - polygon_45_set_view(const ltype& lvalue, - const rtype& rvalue ) : - lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {} - - // get iterator to begin vertex data - public: - const value_type& value() const { - if(!evaluated_) { - evaluated_ = true; - compute_45_set_value<value_type, ltype, rtype, op_type>::value(output_, lvalue_, rvalue_); - } - return output_; - } - public: - iterator_type begin() const { return value().begin(); } - iterator_type end() const { return value().end(); } - - bool dirty() const { return value().dirty(); } //result of a boolean is clean - bool sorted() const { return value().sorted(); } //result of a boolean is sorted - - // template <typename input_iterator_type> - // void set(input_iterator_type input_begin, input_iterator_type input_end, - // orientation_2d orient) const { - // orient_ = orient; - // output_.clear(); - // output_.insert(output_.end(), input_begin, input_end); - // polygon_sort(output_.begin(), output_.end()); - // } - }; - - template <typename ltype, typename rtype, int op_type> - typename polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >::iterator_type - polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >:: - begin(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set) { - return polygon_45_set.begin(); - } - template <typename ltype, typename rtype, int op_type> - typename polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >::iterator_type - polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >:: - end(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set) { - return polygon_45_set.end(); - } - template <typename ltype, typename rtype, int op_type> - bool polygon_45_set_traits<polygon_45_set_view<ltype, rtype, op_type> >:: - clean(const polygon_45_set_view<ltype, rtype, op_type>& polygon_45_set) { - return polygon_45_set.value().clean(); } - - template <typename geometry_type_1, typename geometry_type_2, int op_type> - geometry_type_1& self_assignment_boolean_op_45(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { - typedef geometry_type_1 ltype; - typedef geometry_type_2 rtype; - typedef typename polygon_45_set_traits<ltype>::coordinate_type coordinate_type; - typedef polygon_45_set_data<coordinate_type> value_type; - value_type output_; - value_type rinput_; - output_.set(polygon_45_set_traits<ltype>::begin(lvalue_), - polygon_45_set_traits<ltype>::end(lvalue_)); - rinput_.set(polygon_45_set_traits<rtype>::begin(rvalue_), - polygon_45_set_traits<rtype>::end(rvalue_)); -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op_type == 0) - output_ |= rinput_; - else if(op_type == 1) - output_ &= rinput_; - else if(op_type == 2) - output_ ^= rinput_; - else - output_ -= rinput_; -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - polygon_45_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end()); - return lvalue_; - } - - template <typename concept_type> - struct fracture_holes_option_by_type { - static const bool value = true; - }; - template <> - struct fracture_holes_option_by_type<polygon_45_with_holes_concept> { - static const bool value = false; - }; - template <> - struct fracture_holes_option_by_type<polygon_with_holes_concept> { - static const bool value = false; - }; - - template <typename ltype, typename rtype, int op_type> - struct geometry_concept<polygon_45_set_view<ltype, rtype, op_type> > { typedef polygon_45_set_concept type; }; - - namespace operators { - struct y_ps45_b : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< y_ps45_b, - typename is_polygon_45_or_90_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type, - typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_45_set_view<geometry_type_1, geometry_type_2, 0> >::type - operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_45_set_view<geometry_type_1, geometry_type_2, 0> - (lvalue, rvalue); - } - - struct y_ps45_p : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< y_ps45_p, - typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - typename gtl_if<typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type>::type, - polygon_45_set_view<geometry_type_1, geometry_type_2, 0> >::type - operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_45_set_view<geometry_type_1, geometry_type_2, 0> - (lvalue, rvalue); - } - - struct y_ps45_s : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< y_ps45_s, typename is_polygon_45_or_90_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type, - typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_45_set_view<geometry_type_1, geometry_type_2, 1> >::type - operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_45_set_view<geometry_type_1, geometry_type_2, 1> - (lvalue, rvalue); - } - - struct y_ps45_a : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< y_ps45_a, typename is_polygon_45_or_90_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type, - typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_45_set_view<geometry_type_1, geometry_type_2, 1> >::type - operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_45_set_view<geometry_type_1, geometry_type_2, 1> - (lvalue, rvalue); - } - - struct y_ps45_x : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< y_ps45_x, typename is_polygon_45_or_90_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type, - typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_45_set_view<geometry_type_1, geometry_type_2, 2> >::type - operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_45_set_view<geometry_type_1, geometry_type_2, 2> - (lvalue, rvalue); - } - - struct y_ps45_m : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< y_ps45_m, - typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - typename gtl_if<typename is_either_polygon_45_set_type<geometry_type_1, geometry_type_2>::type>::type>::type, - polygon_45_set_view<geometry_type_1, geometry_type_2, 3> >::type - operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_45_set_view<geometry_type_1, geometry_type_2, 3> - (lvalue, rvalue); - } - - struct y_ps45_pe : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4<y_ps45_pe, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, gtl_yes, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); - } - - struct y_ps45_be : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps45_be, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); - } - - struct y_ps45_se : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps45_se, - typename is_mutable_polygon_45_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); - } - - struct y_ps45_ae : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps45_ae, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); - } - - struct y_ps45_xe : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< - typename gtl_and_3<y_ps45_xe, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue); - } - - struct y_ps45_me : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps45_me, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, - typename is_polygon_45_or_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op_45<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue); - } - - struct y_ps45_rpe : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3< y_ps45_rpe, typename is_mutable_polygon_45_set_type<geometry_type_1>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type>::type, - geometry_type_1>::type & - operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { - return resize(lvalue, rvalue); - } - - struct y_ps45_rme : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps45_rme, typename gtl_if<typename is_mutable_polygon_45_set_type<geometry_type_1>::type>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type>::type, - geometry_type_1>::type & - operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { - return resize(lvalue, -rvalue); - } - - struct y_ps45_rp : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps45_rp, typename gtl_if<typename is_mutable_polygon_45_set_type<geometry_type_1>::type>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type> - ::type, geometry_type_1>::type - operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { - geometry_type_1 retval(lvalue); - retval += rvalue; - return retval; - } - - struct y_ps45_rm : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps45_rm, typename gtl_if<typename is_mutable_polygon_45_set_type<geometry_type_1>::type>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type> - ::type, geometry_type_1>::type - operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { - geometry_type_1 retval(lvalue); - retval -= rvalue; - return retval; - } - } -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_45_touch.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_45_touch.hpp deleted file mode 100644 index 90717e1cca..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_45_touch.hpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - 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_POLYGON_45_TOUCH_HPP -#define BOOST_POLYGON_POLYGON_45_TOUCH_HPP -namespace boost { namespace polygon{ - - template <typename Unit> - struct polygon_45_touch { - - typedef point_data<Unit> Point; - typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit; - - template <typename property_map> - static inline void merge_property_maps(property_map& mp, const property_map& mp2, bool subtract = false) { - property_map newmp; - newmp.reserve(mp.size() + mp2.size()); - std::size_t i = 0; - std::size_t j = 0; - while(i != mp.size() && j != mp2.size()) { - if(mp[i].first < mp2[j].first) { - newmp.push_back(mp[i]); - ++i; - } else if(mp[i].first > mp2[j].first) { - newmp.push_back(mp2[j]); - if(subtract) newmp.back().second *= -1; - ++j; - } else { - int count = mp[i].second; - if(subtract) count -= mp2[j].second; - else count += mp2[j].second; - if(count) { - newmp.push_back(mp[i]); - newmp.back().second = count; - } - ++i; - ++j; - } - } - while(i != mp.size()) { - newmp.push_back(mp[i]); - ++i; - } - while(j != mp2.size()) { - newmp.push_back(mp2[j]); - if(subtract) newmp.back().second *= -1; - ++j; - } - mp.swap(newmp); - } - - class CountTouch { - public: - inline CountTouch() : counts() {} - //inline CountTouch(int count) { counts[0] = counts[1] = count; } - //inline CountTouch(int count1, int count2) { counts[0] = count1; counts[1] = count2; } - inline CountTouch(const CountTouch& count) : counts(count.counts) {} - inline bool operator==(const CountTouch& count) const { return counts == count.counts; } - inline bool operator!=(const CountTouch& count) const { return !((*this) == count); } - //inline CountTouch& operator=(int count) { counts[0] = counts[1] = count; return *this; } - inline CountTouch& operator=(const CountTouch& count) { counts = count.counts; return *this; } - inline int& operator[](int index) { - std::vector<std::pair<int, int> >::iterator itr = - std::lower_bound(counts.begin(), counts.end(), - std::make_pair(index, int(0))); - if(itr != counts.end() && itr->first == index) { - return itr->second; - } - itr = counts.insert(itr, std::make_pair(index, int(0))); - return itr->second; - } -// inline int operator[](int index) const { -// std::vector<std::pair<int, int> >::const_iterator itr = counts.begin(); -// for( ; itr != counts.end() && itr->first <= index; ++itr) { -// if(itr->first == index) { -// return itr->second; -// } -// } -// return 0; -// } - inline CountTouch& operator+=(const CountTouch& count){ - merge_property_maps(counts, count.counts, false); - return *this; - } - inline CountTouch& operator-=(const CountTouch& count){ - merge_property_maps(counts, count.counts, true); - return *this; - } - inline CountTouch operator+(const CountTouch& count) const { - return CountTouch(*this)+=count; - } - inline CountTouch operator-(const CountTouch& count) const { - return CountTouch(*this)-=count; - } - inline CountTouch invert() const { - CountTouch retval; - retval -= *this; - return retval; - } - std::vector<std::pair<int, int> > counts; - }; - - typedef std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, std::map<int, std::set<int> > > map_graph_o; - typedef std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, std::vector<std::set<int> > > vector_graph_o; - - template <typename cT> - static void process_previous_x(cT& output) { - std::map<Unit, std::set<int> >& y_prop_map = output.first.second; - for(typename std::map<Unit, std::set<int> >::iterator itr = y_prop_map.begin(); - itr != y_prop_map.end(); ++itr) { - for(std::set<int>::iterator inner_itr = itr->second.begin(); - inner_itr != itr->second.end(); ++inner_itr) { - std::set<int>& output_edges = (*(output.second))[*inner_itr]; - std::set<int>::iterator inner_inner_itr = inner_itr; - ++inner_inner_itr; - for( ; inner_inner_itr != itr->second.end(); ++inner_inner_itr) { - output_edges.insert(output_edges.end(), *inner_inner_itr); - std::set<int>& output_edges_2 = (*(output.second))[*inner_inner_itr]; - output_edges_2.insert(output_edges_2.end(), *inner_itr); - } - } - } - y_prop_map.clear(); - } - - struct touch_45_output_functor { - template <typename cT> - void operator()(cT& output, const CountTouch& count1, const CountTouch& count2, - const Point& pt, int , direction_1d ) { - Unit& x = output.first.first; - std::map<Unit, std::set<int> >& y_prop_map = output.first.second; - if(pt.x() != x) process_previous_x(output); - x = pt.x(); - std::set<int>& output_set = y_prop_map[pt.y()]; - for(std::vector<std::pair<int, int> >::const_iterator itr1 = count1.counts.begin(); - itr1 != count1.counts.end(); ++itr1) { - if(itr1->second > 0) { - output_set.insert(output_set.end(), itr1->first); - } - } - for(std::vector<std::pair<int, int> >::const_iterator itr2 = count2.counts.begin(); - itr2 != count2.counts.end(); ++itr2) { - if(itr2->second > 0) { - output_set.insert(output_set.end(), itr2->first); - } - } - } - }; - typedef typename std::pair<Point, - typename boolean_op_45<Unit>::template Scan45CountT<CountTouch> > Vertex45Compact; - typedef std::vector<Vertex45Compact> TouchSetData; - - struct lessVertex45Compact { - bool operator()(const Vertex45Compact& l, const Vertex45Compact& r) { - return l.first < r.first; - } - }; - -// template <typename TSD> -// static void print_tsd(TSD& tsd) { -// for(std::size_t i = 0; i < tsd.size(); ++i) { -// std::cout << tsd[i].first << ": "; -// for(unsigned int r = 0; r < 4; ++r) { -// std::cout << r << " { "; -// for(std::vector<std::pair<int, int> >::iterator itr = tsd[i].second[r].counts.begin(); -// itr != tsd[i].second[r].counts.end(); ++itr) { -// std::cout << itr->first << "," << itr->second << " "; -// } std::cout << "} "; -// } -// } std::cout << std::endl; -// } - -// template <typename T> -// static void print_scanline(T& t) { -// for(typename T::iterator itr = t.begin(); itr != t.end(); ++itr) { -// std::cout << itr->x << "," << itr->y << " " << itr->rise << " "; -// for(std::vector<std::pair<int, int> >::iterator itr2 = itr->count.counts.begin(); -// itr2 != itr->count.counts.end(); ++itr2) { -// std::cout << itr2->first << ":" << itr2->second << " "; -// } std::cout << std::endl; -// } -// } - - template <typename graph_type> - static void performTouch(graph_type& graph, TouchSetData& tsd) { - - polygon_sort(tsd.begin(), tsd.end(), lessVertex45Compact()); - typedef std::vector<std::pair<Point, typename boolean_op_45<Unit>::template Scan45CountT<CountTouch> > > TSD; - TSD tsd_; - tsd_.reserve(tsd.size()); - for(typename TouchSetData::iterator itr = tsd.begin(); itr != tsd.end(); ) { - typename TouchSetData::iterator itr2 = itr; - ++itr2; - for(; itr2 != tsd.end() && itr2->first == itr->first; ++itr2) { - (itr->second) += (itr2->second); //accumulate - } - tsd_.push_back(std::make_pair(itr->first, itr->second)); - itr = itr2; - } - std::pair<std::pair<Unit, std::map<Unit, std::set<int> > >, graph_type*> output - (std::make_pair(std::make_pair((std::numeric_limits<Unit>::max)(), std::map<Unit, std::set<int> >()), &graph)); - typename boolean_op_45<Unit>::template Scan45<CountTouch, touch_45_output_functor> scanline; - for(typename TSD::iterator itr = tsd_.begin(); itr != tsd_.end(); ) { - typename TSD::iterator itr2 = itr; - ++itr2; - while(itr2 != tsd_.end() && itr2->first.x() == itr->first.x()) { - ++itr2; - } - scanline.scan(output, itr, itr2); - itr = itr2; - } - process_previous_x(output); - } - - template <typename iT> - static void populateTouchSetData(TouchSetData& tsd, iT begin, iT end, int nodeCount) { - for( ; begin != end; ++begin) { - Vertex45Compact vertex; - vertex.first = typename Vertex45Compact::first_type(begin->pt.x() * 2, begin->pt.y() * 2); - tsd.push_back(vertex); - for(unsigned int i = 0; i < 4; ++i) { - if(begin->count[i]) { - tsd.back().second[i][nodeCount] += begin->count[i]; - } - } - } - } - - }; - - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_90_set_view.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_90_set_view.hpp deleted file mode 100644 index 7e93b0343f..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_90_set_view.hpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - 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_POLYGON_90_SET_VIEW_HPP -#define BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP -namespace boost { namespace polygon{ - struct operator_provides_storage {}; - struct operator_requires_copy {}; - - template <typename value_type, typename arg_type> - inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient); - - template <typename ltype, typename rtype, typename op_type> - class polygon_90_set_view; - - template <typename ltype, typename rtype, typename op_type> - struct polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> > { - typedef typename polygon_90_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type; - typedef typename polygon_90_set_view<ltype, rtype, op_type>::iterator_type iterator_type; - typedef typename polygon_90_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type; - - static inline iterator_type begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set); - static inline iterator_type end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set); - - static inline orientation_2d orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set); - - static inline bool clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set); - - static inline bool sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set); - }; - - template <typename value_type, typename ltype, typename rtype, typename op_type> - struct compute_90_set_value { - static - void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_, orientation_2d orient_) { - value_type linput_(orient_); - value_type rinput_(orient_); - orientation_2d orient_l = polygon_90_set_traits<ltype>::orient(lvalue_); - orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_); - //std::cout << "compute_90_set_value-0 orientations (left, right, out):\t" << orient_l.to_int() - // << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl; - insert_into_view_arg(linput_, lvalue_, orient_l); - insert_into_view_arg(rinput_, rvalue_, orient_r); - output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), - rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); - } - }; - - template <typename value_type, typename lcoord, typename rcoord, typename op_type> - struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, polygon_90_set_data<rcoord>, op_type> { - static - void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_, - const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) { - orientation_2d orient_l = lvalue_.orient(); - orientation_2d orient_r = rvalue_.orient(); - value_type linput_(orient_); - value_type rinput_(orient_); - //std::cout << "compute_90_set_value-1 orientations (left, right, out):\t" << orient_l.to_int() - // << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl; - if((orient_ == orient_l) && (orient_== orient_r)){ // assume that most of the time this condition is met - lvalue_.sort(); - rvalue_.sort(); - output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), - rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); - }else if((orient_ != orient_l) && (orient_!= orient_r)){ // both the orientations are not equal to input - // easier way is to ignore the input orientation and use the input data's orientation, but not done so - insert_into_view_arg(linput_, lvalue_, orient_l); - insert_into_view_arg(rinput_, rvalue_, orient_r); - output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), - rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); - }else if(orient_ != orient_l){ // left hand side orientation is different - insert_into_view_arg(linput_, lvalue_, orient_l); - rvalue_.sort(); - output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), - rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); - } else if(orient_ != orient_r){ // right hand side orientation is different - insert_into_view_arg(rinput_, rvalue_, orient_r); - lvalue_.sort(); - output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), - rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); - } - } - }; - - template <typename value_type, typename lcoord, typename rtype, typename op_type> - struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, rtype, op_type> { - static - void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_, - const rtype& rvalue_, orientation_2d orient_) { - value_type rinput_(orient_); - lvalue_.sort(); - orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_); - //std::cout << "compute_90_set_value-2 orientations (right, out):\t" << orient_r.to_int() - // << "," << orient_.to_int() << std::endl; - insert_into_view_arg(rinput_, rvalue_, orient_r); - output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), - rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); - } - }; - - template <typename value_type, typename ltype, typename rcoord, typename op_type> - struct compute_90_set_value<value_type, ltype, polygon_90_set_data<rcoord>, op_type> { - static - void value(value_type& output_, const ltype& lvalue_, - const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) { - value_type linput_(orient_); - orientation_2d orient_l = polygon_90_set_traits<ltype>::orient(lvalue_); - insert_into_view_arg(linput_, lvalue_, orient_l); - rvalue_.sort(); - //std::cout << "compute_90_set_value-3 orientations (left, out):\t" << orient_l.to_int() - // << "," << orient_.to_int() << std::endl; - - output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), - rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); - } - }; - - template <typename ltype, typename rtype, typename op_type> - class polygon_90_set_view { - public: - typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type; - typedef polygon_90_set_data<coordinate_type> value_type; - typedef typename value_type::iterator_type iterator_type; - typedef polygon_90_set_view operator_arg_type; - private: - const ltype& lvalue_; - const rtype& rvalue_; - orientation_2d orient_; - op_type op_; - mutable value_type output_; - mutable bool evaluated_; - polygon_90_set_view& operator=(const polygon_90_set_view&); - public: - polygon_90_set_view(const ltype& lvalue, - const rtype& rvalue, - orientation_2d orient, - op_type op) : - lvalue_(lvalue), rvalue_(rvalue), orient_(orient), op_(op), output_(orient), evaluated_(false) {} - - // get iterator to begin vertex data - private: - const value_type& value() const { - if(!evaluated_) { - evaluated_ = true; - compute_90_set_value<value_type, ltype, rtype, op_type>::value(output_, lvalue_, rvalue_, orient_); - } - return output_; - } - public: - iterator_type begin() const { return value().begin(); } - iterator_type end() const { return value().end(); } - - orientation_2d orient() const { return orient_; } - bool dirty() const { return false; } //result of a boolean is clean - bool sorted() const { return true; } //result of a boolean is sorted - -// template <typename input_iterator_type> -// void set(input_iterator_type input_begin, input_iterator_type input_end, -// orientation_2d orient) const { -// orient_ = orient; -// output_.clear(); -// output_.insert(output_.end(), input_begin, input_end); -// polygon_sort(output_.begin(), output_.end()); -// } - void sort() const {} //is always sorted - }; - - template <typename ltype, typename rtype, typename op_type> - struct geometry_concept<polygon_90_set_view<ltype, rtype, op_type> > { - typedef polygon_90_set_concept type; - }; - - template <typename ltype, typename rtype, typename op_type> - typename polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::iterator_type - polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >:: - begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { - return polygon_set.begin(); - } - template <typename ltype, typename rtype, typename op_type> - typename polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::iterator_type - polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >:: - end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { - return polygon_set.end(); - } -// template <typename ltype, typename rtype, typename op_type> -// template <typename input_iterator_type> -// void polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >:: -// set(polygon_90_set_view<ltype, rtype, op_type>& polygon_set, -// input_iterator_type input_begin, input_iterator_type input_end, -// orientation_2d orient) { -// polygon_set.set(input_begin, input_end, orient); -// } - template <typename ltype, typename rtype, typename op_type> - orientation_2d polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >:: - orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { - return polygon_set.orient(); } - template <typename ltype, typename rtype, typename op_type> - bool polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >:: - clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { - return !polygon_set.dirty(); } - template <typename ltype, typename rtype, typename op_type> - bool polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >:: - sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { - return polygon_set.sorted(); } - - template <typename value_type, typename arg_type> - inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient) { - typedef typename polygon_90_set_traits<arg_type>::iterator_type literator; - literator itr1, itr2; - itr1 = polygon_90_set_traits<arg_type>::begin(arg); - itr2 = polygon_90_set_traits<arg_type>::end(arg); - dest.insert(itr1, itr2, orient); - dest.sort(); - } - - template <typename T> - template <typename ltype, typename rtype, typename op_type> - inline polygon_90_set_data<T>& polygon_90_set_data<T>::operator=(const polygon_90_set_view<ltype, rtype, op_type>& that) { - set(that.begin(), that.end(), that.orient()); - dirty_ = false; - unsorted_ = false; - return *this; - } - - template <typename T> - template <typename ltype, typename rtype, typename op_type> - inline polygon_90_set_data<T>::polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that) : - orient_(that.orient()), data_(that.begin(), that.end()), dirty_(false), unsorted_(false) {} - - template <typename geometry_type_1, typename geometry_type_2> - struct self_assign_operator_lvalue { - typedef geometry_type_1& type; - }; - - template <typename type_1, typename type_2> - struct by_value_binary_operator { - typedef type_1 type; - }; - - template <typename geometry_type_1, typename geometry_type_2, typename op_type> - geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { - typedef geometry_type_1 ltype; - typedef geometry_type_2 rtype; - typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type; - typedef polygon_90_set_data<coordinate_type> value_type; - orientation_2d orient_ = polygon_90_set_traits<ltype>::orient(lvalue_); - //BM: rvalue_ data set may have its own orientation for scanline - orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_); - //std::cout << "self-assignment boolean-op (left, right, out):\t" << orient_.to_int() - // << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl; - value_type linput_(orient_); - // BM: the rinput_ set's (that stores the rvalue_ dataset polygons) scanline orientation is *forced* - // to be same as linput - value_type rinput_(orient_); - //BM: The output dataset's scanline orient is set as equal to first input dataset's (lvalue_) orientation - value_type output_(orient_); - insert_into_view_arg(linput_, lvalue_, orient_); - // BM: The last argument orient_r is the user initialized scanline orientation for rvalue_ data set. - // But since rinput (see above) is initialized to scanline orientation consistent with the lvalue_ - // data set, this insertion operation will change the incoming rvalue_ dataset's scanline orientation - insert_into_view_arg(rinput_, rvalue_, orient_r); - // BM: boolean operation and output uses lvalue_ dataset's scanline orientation. - output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), - rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); - polygon_90_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end(), orient_); - return lvalue_; - } - - namespace operators { - struct y_ps90_b : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_b, - typename is_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> >::type - operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> - (lvalue, rvalue, - polygon_90_set_traits<geometry_type_1>::orient(lvalue), - boolean_op::BinaryOr()); - } - - struct y_ps90_p : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< - typename gtl_and_3< y_ps90_p, - typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type, - polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> >::type - operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> - (lvalue, rvalue, - polygon_90_set_traits<geometry_type_1>::orient(lvalue), - boolean_op::BinaryOr()); - } - - struct y_ps90_s : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_s, - typename is_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> >::type - operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> - (lvalue, rvalue, - polygon_90_set_traits<geometry_type_1>::orient(lvalue), - boolean_op::BinaryAnd()); - } - - struct y_ps90_a : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_a, - typename is_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> >::type - operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> - (lvalue, rvalue, - polygon_90_set_traits<geometry_type_1>::orient(lvalue), - boolean_op::BinaryAnd()); - } - - struct y_ps90_x : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_x, - typename is_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor> >::type - operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor> - (lvalue, rvalue, - polygon_90_set_traits<geometry_type_1>::orient(lvalue), - boolean_op::BinaryXor()); - } - - struct y_ps90_m : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_m, - typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type, - polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot> >::type - operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot> - (lvalue, rvalue, - polygon_90_set_traits<geometry_type_1>::orient(lvalue), - boolean_op::BinaryNot()); - } - - struct y_ps90_pe : gtl_yes {}; - - template <typename coordinate_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and< y_ps90_pe, typename is_polygon_90_set_type<geometry_type_2>::type>::type, - polygon_90_set_data<coordinate_type_1> >::type & - operator+=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) { - lvalue.insert(polygon_90_set_traits<geometry_type_2>::begin(rvalue), polygon_90_set_traits<geometry_type_2>::end(rvalue), - polygon_90_set_traits<geometry_type_2>::orient(rvalue)); - return lvalue; - } - - struct y_ps90_be : gtl_yes {}; - // - template <typename coordinate_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and< y_ps90_be, typename is_polygon_90_set_type<geometry_type_2>::type>::type, - polygon_90_set_data<coordinate_type_1> >::type & - operator|=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) { - return lvalue += rvalue; - } - - struct y_ps90_pe2 : gtl_yes {}; - - //normal self assignment boolean operations - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_pe2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue); - } - - struct y_ps90_be2 : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps90_be2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue); - } - - struct y_ps90_se : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps90_se, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue); - } - - struct y_ps90_ae : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps90_ae, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue); - } - - struct y_ps90_xe : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3<y_ps90_xe, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryXor>(lvalue, rvalue); - } - - struct y_ps90_me : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< y_ps90_me, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename is_polygon_90_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryNot>(lvalue, rvalue); - } - - struct y_ps90_rpe : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps90_rpe, - typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type, - geometry_type_1>::type & - operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { - return resize(lvalue, rvalue); - } - - struct y_ps90_rme : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps90_rme, - typename is_mutable_polygon_90_set_type<geometry_type_1>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type, - geometry_type_1>::type & - operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { - return resize(lvalue, -rvalue); - } - - struct y_ps90_rp : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps90_rp, - typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type, - geometry_type_1>::type - operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { - geometry_type_1 retval(lvalue); - retval += rvalue; - return retval; - } - - struct y_ps90_rm : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps90_rm, - typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type, - geometry_type_1>::type - operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { - geometry_type_1 retval(lvalue); - retval -= rvalue; - return retval; - } - } -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_90_touch.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_90_touch.hpp deleted file mode 100644 index 77a516b777..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_90_touch.hpp +++ /dev/null @@ -1,418 +0,0 @@ -/* - 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_POLYGON_90_TOUCH_HPP -#define BOOST_POLYGON_POLYGON_90_TOUCH_HPP -namespace boost { namespace polygon{ - - template <typename Unit> - struct touch_90_operation { - typedef interval_data<Unit> Interval; - - class TouchScanEvent { - private: - typedef std::map<Unit, std::set<int> > EventData; - EventData eventData_; - public: - - // The TouchScanEvent::iterator is a lazy algorithm that accumulates - // polygon ids in a set as it is incremented through the - // scan event data structure. - // The iterator provides a forward iterator semantic only. - class iterator { - private: - typename EventData::const_iterator itr_; - std::pair<Interval, std::set<int> > ivlIds_; - bool incremented_; - public: - inline iterator() : itr_(), ivlIds_(), incremented_(false) {} - inline iterator(typename EventData::const_iterator itr, - Unit prevPos, Unit curPos, const std::set<int>& ivlIds) : itr_(itr), ivlIds_(), incremented_(false) { - ivlIds_.second = ivlIds; - ivlIds_.first = Interval(prevPos, curPos); - } - inline iterator(const iterator& that) : itr_(), ivlIds_(), incremented_(false) { (*this) = that; } - inline iterator& operator=(const iterator& that) { - itr_ = that.itr_; - ivlIds_.first = that.ivlIds_.first; - ivlIds_.second = that.ivlIds_.second; - incremented_ = that.incremented_; - return *this; - } - inline bool operator==(const iterator& that) { return itr_ == that.itr_; } - inline bool operator!=(const iterator& that) { return itr_ != that.itr_; } - inline iterator& operator++() { - //std::cout << "increment\n"; - //std::cout << "state\n"; - //for(std::set<int>::iterator itr = ivlIds_.second.begin(); itr != ivlIds_.second.end(); ++itr) { - // std::cout << (*itr) << " "; - //} std::cout << std::endl; - //std::cout << "update\n"; - for(std::set<int>::const_iterator itr = (*itr_).second.begin(); - itr != (*itr_).second.end(); ++itr) { - //std::cout << (*itr) << " "; - std::set<int>::iterator lb = ivlIds_.second.find(*itr); - if(lb != ivlIds_.second.end()) { - ivlIds_.second.erase(lb); - } else { - ivlIds_.second.insert(*itr); - } - } - //std::cout << std::endl; - //std::cout << "new state\n"; - //for(std::set<int>::iterator itr = ivlIds_.second.begin(); itr != ivlIds_.second.end(); ++itr) { - // std::cout << (*itr) << " "; - //} std::cout << std::endl; - ++itr_; - //ivlIds_.first = Interval(ivlIds_.first.get(HIGH), itr_->first); - incremented_ = true; - return *this; - } - inline const iterator operator++(int){ - iterator tmpItr(*this); - ++(*this); - return tmpItr; - } - inline std::pair<Interval, std::set<int> >& operator*() { - if(incremented_) ivlIds_.first = Interval(ivlIds_.first.get(HIGH), itr_->first); - incremented_ = false; - if(ivlIds_.second.empty())(++(*this)); - if(incremented_) ivlIds_.first = Interval(ivlIds_.first.get(HIGH), itr_->first); - incremented_ = false; - return ivlIds_; } - }; - - inline TouchScanEvent() : eventData_() {} - template<class iT> - inline TouchScanEvent(iT begin, iT end) : eventData_() { - for( ; begin != end; ++begin){ - insert(*begin); - } - } - inline TouchScanEvent(const TouchScanEvent& that) : eventData_(that.eventData_) {} - inline TouchScanEvent& operator=(const TouchScanEvent& that){ - eventData_ = that.eventData_; - return *this; - } - - //Insert an interval polygon id into the EventData - inline void insert(const std::pair<Interval, int>& intervalId){ - insert(intervalId.first.low(), intervalId.second); - insert(intervalId.first.high(), intervalId.second); - } - - //Insert an position and polygon id into EventData - inline void insert(Unit pos, int id) { - typename EventData::iterator lb = eventData_.lower_bound(pos); - if(lb != eventData_.end() && lb->first == pos) { - std::set<int>& mr (lb->second); - std::set<int>::iterator mri = mr.find(id); - if(mri == mr.end()) { - mr.insert(id); - } else { - mr.erase(id); - } - } else { - lb = eventData_.insert(lb, std::pair<Unit, std::set<int> >(pos, std::set<int>())); - (*lb).second.insert(id); - } - } - - //merge this scan event with that by inserting its data - inline void insert(const TouchScanEvent& that){ - typename EventData::const_iterator itr; - for(itr = that.eventData_.begin(); itr != that.eventData_.end(); ++itr) { - eventData_[(*itr).first].insert(itr->second.begin(), itr->second.end()); - } - } - - //Get the begin iterator over event data - inline iterator begin() const { - //std::cout << "begin\n"; - if(eventData_.empty()) return end(); - typename EventData::const_iterator itr = eventData_.begin(); - Unit pos = itr->first; - const std::set<int>& idr = itr->second; - ++itr; - return iterator(itr, pos, itr->first, idr); - } - - //Get the end iterator over event data - inline iterator end() const { return iterator(eventData_.end(), 0, 0, std::set<int>()); } - - inline void clear() { eventData_.clear(); } - - inline Interval extents() const { - if(eventData_.empty()) return Interval(); - return Interval((*(eventData_.begin())).first, (*(eventData_.rbegin())).first); - } - }; - - //declaration of a map of scan events by coordinate value used to store all the - //polygon data for a single layer input into the scanline algorithm - typedef std::pair<std::map<Unit, TouchScanEvent>, std::map<Unit, TouchScanEvent> > TouchSetData; - - class TouchOp { - public: - typedef std::map<Unit, std::set<int> > ScanData; - typedef std::pair<Unit, std::set<int> > ElementType; - protected: - ScanData scanData_; - typename ScanData::iterator nextItr_; - public: - inline TouchOp () : scanData_(), nextItr_() { nextItr_ = scanData_.end(); } - inline TouchOp (const TouchOp& that) : scanData_(that.scanData_), nextItr_() { nextItr_ = scanData_.begin(); } - inline TouchOp& operator=(const TouchOp& that); - - //moves scanline forward - inline void advanceScan() { nextItr_ = scanData_.begin(); } - - //proceses the given interval and std::set<int> data - //the output data structre is a graph, the indicies in the vector correspond to graph nodes, - //the integers in the set are vector indicies and are the nodes with which that node shares an edge - template <typename graphT> - inline void processInterval(graphT& outputContainer, Interval ivl, const std::set<int>& ids, bool leadingEdge) { - //print(); - typename ScanData::iterator lowItr = lookup_(ivl.low()); - typename ScanData::iterator highItr = lookup_(ivl.high()); - //std::cout << "Interval: " << ivl << std::endl; - //for(std::set<int>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr) - // std::cout << (*itr) << " "; - //std::cout << std::endl; - //add interval to scan data if it is past the end - if(lowItr == scanData_.end()) { - //std::cout << "case0" << std::endl; - lowItr = insert_(ivl.low(), ids); - evaluateBorder_(outputContainer, ids, ids); - highItr = insert_(ivl.high(), std::set<int>()); - return; - } - //ensure that highItr points to the end of the ivl - if(highItr == scanData_.end() || (*highItr).first > ivl.high()) { - //std::cout << "case1" << std::endl; - //std::cout << highItr->first << std::endl; - std::set<int> value = std::set<int>(); - if(highItr != scanData_.begin()) { - --highItr; - //std::cout << highItr->first << std::endl; - //std::cout << "high set size " << highItr->second.size() << std::endl; - value = highItr->second; - } - nextItr_ = highItr; - highItr = insert_(ivl.high(), value); - } else { - //evaluate border with next higher interval - //std::cout << "case1a" << std::endl; - if(leadingEdge)evaluateBorder_(outputContainer, highItr->second, ids); - } - //split the low interval if needed - if(lowItr->first > ivl.low()) { - //std::cout << "case2" << std::endl; - if(lowItr != scanData_.begin()) { - //std::cout << "case3" << std::endl; - --lowItr; - nextItr_ = lowItr; - //std::cout << lowItr->first << " " << lowItr->second.size() << std::endl; - lowItr = insert_(ivl.low(), lowItr->second); - } else { - //std::cout << "case4" << std::endl; - nextItr_ = lowItr; - lowItr = insert_(ivl.low(), std::set<int>()); - } - } else { - //evaluate border with next higher interval - //std::cout << "case2a" << std::endl; - typename ScanData::iterator nextLowerItr = lowItr; - if(leadingEdge && nextLowerItr != scanData_.begin()){ - --nextLowerItr; - evaluateBorder_(outputContainer, nextLowerItr->second, ids); - } - } - //std::cout << "low: " << lowItr->first << " high: " << highItr->first << std::endl; - //print(); - //process scan data intersecting interval - for(typename ScanData::iterator itr = lowItr; itr != highItr; ){ - //std::cout << "case5" << std::endl; - //std::cout << itr->first << std::endl; - std::set<int>& beforeIds = itr->second; - ++itr; - evaluateInterval_(outputContainer, beforeIds, ids, leadingEdge); - } - //print(); - //merge the bottom interval with the one below if they have the same count - if(lowItr != scanData_.begin()){ - //std::cout << "case6" << std::endl; - typename ScanData::iterator belowLowItr = lowItr; - --belowLowItr; - if(belowLowItr->second == lowItr->second) { - //std::cout << "case7" << std::endl; - scanData_.erase(lowItr); - } - } - //merge the top interval with the one above if they have the same count - if(highItr != scanData_.begin()) { - //std::cout << "case8" << std::endl; - typename ScanData::iterator beforeHighItr = highItr; - --beforeHighItr; - if(beforeHighItr->second == highItr->second) { - //std::cout << "case9" << std::endl; - scanData_.erase(highItr); - highItr = beforeHighItr; - ++highItr; - } - } - //print(); - nextItr_ = highItr; - } - -// inline void print() const { -// for(typename ScanData::const_iterator itr = scanData_.begin(); itr != scanData_.end(); ++itr) { -// std::cout << itr->first << ": "; -// for(std::set<int>::const_iterator sitr = itr->second.begin(); -// sitr != itr->second.end(); ++sitr){ -// std::cout << *sitr << " "; -// } -// std::cout << std::endl; -// } -// } - - private: - inline typename ScanData::iterator lookup_(Unit pos){ - if(nextItr_ != scanData_.end() && nextItr_->first >= pos) { - return nextItr_; - } - return nextItr_ = scanData_.lower_bound(pos); - } - - inline typename ScanData::iterator insert_(Unit pos, const std::set<int>& ids){ - //std::cout << "inserting " << ids.size() << " ids at: " << pos << std::endl; - return nextItr_ = scanData_.insert(nextItr_, std::pair<Unit, std::set<int> >(pos, ids)); - } - - template <typename graphT> - inline void evaluateInterval_(graphT& outputContainer, std::set<int>& ids, - const std::set<int>& changingIds, bool leadingEdge) { - for(std::set<int>::const_iterator ciditr = changingIds.begin(); ciditr != changingIds.end(); ++ciditr){ - //std::cout << "evaluateInterval " << (*ciditr) << std::endl; - evaluateId_(outputContainer, ids, *ciditr, leadingEdge); - } - } - template <typename graphT> - inline void evaluateBorder_(graphT& outputContainer, const std::set<int>& ids, const std::set<int>& changingIds) { - for(std::set<int>::const_iterator ciditr = changingIds.begin(); ciditr != changingIds.end(); ++ciditr){ - //std::cout << "evaluateBorder " << (*ciditr) << std::endl; - evaluateBorderId_(outputContainer, ids, *ciditr); - } - } - template <typename graphT> - inline void evaluateBorderId_(graphT& outputContainer, const std::set<int>& ids, int changingId) { - for(std::set<int>::const_iterator scanItr = ids.begin(); scanItr != ids.end(); ++scanItr) { - //std::cout << "create edge: " << changingId << " " << *scanItr << std::endl; - if(changingId != *scanItr){ - outputContainer[changingId].insert(*scanItr); - outputContainer[*scanItr].insert(changingId); - } - } - } - template <typename graphT> - inline void evaluateId_(graphT& outputContainer, std::set<int>& ids, int changingId, bool leadingEdge) { - //std::cout << "changingId: " << changingId << std::endl; - //for( std::set<int>::iterator itr = ids.begin(); itr != ids.end(); ++itr){ - // std::cout << *itr << " "; - //}std::cout << std::endl; - std::set<int>::iterator lb = ids.lower_bound(changingId); - if(lb == ids.end() || (*lb) != changingId) { - if(leadingEdge) { - //std::cout << "insert\n"; - //insert and add to output - for(std::set<int>::iterator scanItr = ids.begin(); scanItr != ids.end(); ++scanItr) { - //std::cout << "create edge: " << changingId << " " << *scanItr << std::endl; - if(changingId != *scanItr){ - outputContainer[changingId].insert(*scanItr); - outputContainer[*scanItr].insert(changingId); - } - } - ids.insert(changingId); - } - } else { - if(!leadingEdge){ - //std::cout << "erase\n"; - ids.erase(lb); - } - } - } - }; - - template <typename graphT> - static inline void processEvent(graphT& outputContainer, TouchOp& op, const TouchScanEvent& data, bool leadingEdge) { - for(typename TouchScanEvent::iterator itr = data.begin(); itr != data.end(); ++itr) { - //std::cout << "processInterval" << std::endl; - op.processInterval(outputContainer, (*itr).first, (*itr).second, leadingEdge); - } - } - - template <typename graphT> - static inline void performTouch(graphT& outputContainer, const TouchSetData& data) { - typename std::map<Unit, TouchScanEvent>::const_iterator leftItr = data.first.begin(); - typename std::map<Unit, TouchScanEvent>::const_iterator rightItr = data.second.begin(); - typename std::map<Unit, TouchScanEvent>::const_iterator leftEnd = data.first.end(); - typename std::map<Unit, TouchScanEvent>::const_iterator rightEnd = data.second.end(); - TouchOp op; - while(leftItr != leftEnd || rightItr != rightEnd) { - //std::cout << "loop" << std::endl; - op.advanceScan(); - //rightItr cannont be at end if leftItr is not at end - if(leftItr != leftEnd && rightItr != rightEnd && - leftItr->first <= rightItr->first) { - //std::cout << "case1" << std::endl; - //std::cout << leftItr ->first << std::endl; - processEvent(outputContainer, op, leftItr->second, true); - ++leftItr; - } else { - //std::cout << "case2" << std::endl; - //std::cout << rightItr ->first << std::endl; - processEvent(outputContainer, op, rightItr->second, false); - ++rightItr; - } - } - } - - template <class iT> - static inline void populateTouchSetData(TouchSetData& data, iT beginData, iT endData, int id) { - Unit prevPos = ((std::numeric_limits<Unit>::max)()); - Unit prevY = prevPos; - int count = 0; - for(iT itr = beginData; itr != endData; ++itr) { - Unit pos = (*itr).first; - if(pos != prevPos) { - prevPos = pos; - prevY = (*itr).second.first; - count = (*itr).second.second; - continue; - } - Unit y = (*itr).second.first; - if(count != 0 && y != prevY) { - std::pair<Interval, int> element(Interval(prevY, y), id); - if(count > 0) { - data.first[pos].insert(element); - } else { - data.second[pos].insert(element); - } - } - prevY = y; - count += (*itr).second.second; - } - } - - static inline void populateTouchSetData(TouchSetData& data, const std::vector<std::pair<Unit, std::pair<Unit, int> > >& inputData, int id) { - populateTouchSetData(data, inputData.begin(), inputData.end(), id); - } - - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_arbitrary_formation.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_arbitrary_formation.hpp deleted file mode 100644 index 5495897e91..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_arbitrary_formation.hpp +++ /dev/null @@ -1,2907 +0,0 @@ -/* - 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_POLYGON_ARBITRARY_FORMATION_HPP -#define BOOST_POLYGON_POLYGON_ARBITRARY_FORMATION_HPP -namespace boost { namespace polygon{ - template <typename T, typename T2> - struct PolyLineArbitraryByConcept {}; - - template <typename T> - class poly_line_arbitrary_polygon_data; - template <typename T> - class poly_line_arbitrary_hole_data; - - template <typename Unit> - struct scanline_base { - - typedef point_data<Unit> Point; - typedef std::pair<Point, Point> half_edge; - - class less_point { - public: - typedef Point first_argument_type; - typedef Point second_argument_type; - typedef bool result_type; - inline less_point() {} - inline bool operator () (const Point& pt1, const Point& pt2) const { - if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true; - if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) { - if(pt1.get(VERTICAL) < pt2.get(VERTICAL)) return true; - } - return false; - } - }; - - static inline bool between(Point pt, Point pt1, Point pt2) { - less_point lp; - if(lp(pt1, pt2)) - return lp(pt, pt2) && lp(pt1, pt); - return lp(pt, pt1) && lp(pt2, pt); - } - - template <typename area_type> - static inline Unit compute_intercept(const area_type& dy2, - const area_type& dx1, - const area_type& dx2) { - //intercept = dy2 * dx1 / dx2 - //return (Unit)(((area_type)dy2 * (area_type)dx1) / (area_type)dx2); - area_type dx1_q = dx1 / dx2; - area_type dx1_r = dx1 % dx2; - return dx1_q * dy2 + (dy2 * dx1_r)/dx2; - } - - template <typename area_type> - static inline bool equal_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) { - typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type; - unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1); - unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2); - int dx1_sign = dx1 < 0 ? -1 : 1; - int dx2_sign = dx2 < 0 ? -1 : 1; - int dy1_sign = dy1 < 0 ? -1 : 1; - int dy2_sign = dy2 < 0 ? -1 : 1; - int cross_1_sign = dx2_sign * dy1_sign; - int cross_2_sign = dx1_sign * dy2_sign; - return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0); - } - - template <typename T> - static inline bool equal_slope_hp(const T& dx1, const T& dy1, const T& dx2, const T& dy2) { - return dx1 * dy2 == dx2 * dy1; - } - - static inline bool equal_slope(const Unit& x, const Unit& y, - const Point& pt1, const Point& pt2) { - const Point* pts[2] = {&pt1, &pt2}; - typedef typename coordinate_traits<Unit>::manhattan_area_type at; - at dy2 = (at)pts[1]->get(VERTICAL) - (at)y; - at dy1 = (at)pts[0]->get(VERTICAL) - (at)y; - at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x; - at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x; - return equal_slope(dx1, dy1, dx2, dy2); - } - - template <typename area_type> - static inline bool less_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) { - //reflext x and y slopes to right hand side half plane - if(dx1 < 0) { - dy1 *= -1; - dx1 *= -1; - } else if(dx1 == 0) { - //if the first slope is vertical the first cannot be less - return false; - } - if(dx2 < 0) { - dy2 *= -1; - dx2 *= -1; - } else if(dx2 == 0) { - //if the second slope is vertical the first is always less unless it is also vertical, in which case they are equal - return dx1 != 0; - } - typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type; - unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1); - unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2); - int dx1_sign = dx1 < 0 ? -1 : 1; - int dx2_sign = dx2 < 0 ? -1 : 1; - int dy1_sign = dy1 < 0 ? -1 : 1; - int dy2_sign = dy2 < 0 ? -1 : 1; - int cross_1_sign = dx2_sign * dy1_sign; - int cross_2_sign = dx1_sign * dy2_sign; - if(cross_1_sign < cross_2_sign) return true; - if(cross_2_sign < cross_1_sign) return false; - if(cross_1_sign == -1) return cross_2 < cross_1; - return cross_1 < cross_2; - } - - static inline bool less_slope(const Unit& x, const Unit& y, - const Point& pt1, const Point& pt2) { - const Point* pts[2] = {&pt1, &pt2}; - //compute y value on edge from pt_ to pts[1] at the x value of pts[0] - typedef typename coordinate_traits<Unit>::manhattan_area_type at; - at dy2 = (at)pts[1]->get(VERTICAL) - (at)y; - at dy1 = (at)pts[0]->get(VERTICAL) - (at)y; - at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x; - at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x; - return less_slope(dx1, dy1, dx2, dy2); - } - - //return -1 below, 0 on and 1 above line - static inline int on_above_or_below(Point pt, const half_edge& he) { - if(pt == he.first || pt == he.second) return 0; - if(equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second)) return 0; - bool less_result = less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second); - int retval = less_result ? -1 : 1; - less_point lp; - if(lp(he.second, he.first)) retval *= -1; - if(!between(pt, he.first, he.second)) retval *= -1; - return retval; - } - - //returns true is the segment intersects the integer grid square with lower - //left corner at point - static inline bool intersects_grid(Point pt, const half_edge& he) { - if(pt == he.second) return true; - if(pt == he.first) return true; - rectangle_data<Unit> rect1; - set_points(rect1, he.first, he.second); - if(contains(rect1, pt, true)) { - if(is_vertical(he) || is_horizontal(he)) return true; - } else { - return false; //can't intersect a grid not within bounding box - } - Unit x = pt.get(HORIZONTAL); - Unit y = pt.get(VERTICAL); - if(equal_slope(x, y, he.first, he.second) && - between(pt, he.first, he.second)) return true; - Point pt01(pt.get(HORIZONTAL), pt.get(VERTICAL) + 1); - Point pt10(pt.get(HORIZONTAL) + 1, pt.get(VERTICAL)); - Point pt11(pt.get(HORIZONTAL) + 1, pt.get(VERTICAL) + 1); -// if(pt01 == he.first) return true; -// if(pt10 == he.first) return true; -// if(pt11 == he.first) return true; -// if(pt01 == he.second) return true; -// if(pt10 == he.second) return true; -// if(pt11 == he.second) return true; - //check non-integer intersections - half_edge widget1(pt, pt11); - //intersects but not just at pt11 - if(intersects(widget1, he) && on_above_or_below(pt11, he)) return true; - half_edge widget2(pt01, pt10); - //intersects but not just at pt01 or 10 - if(intersects(widget2, he) && on_above_or_below(pt01, he) && on_above_or_below(pt10, he)) return true; - return false; - } - - static inline Unit evalAtXforYlazy(Unit xIn, Point pt, Point other_pt) { - long double - evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx, - evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0; - //y = (x - x1)dy/dx + y1 - //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y - //assert pt.x != other_pt.x - if(pt.y() == other_pt.y()) - return pt.y(); - evalAtXforYxIn = xIn; - evalAtXforYx1 = pt.get(HORIZONTAL); - evalAtXforYy1 = pt.get(VERTICAL); - evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1; - evalAtXforY0 = 0; - if(evalAtXforYdx1 == evalAtXforY0) return (Unit)evalAtXforYy1; - evalAtXforYx2 = other_pt.get(HORIZONTAL); - evalAtXforYy2 = other_pt.get(VERTICAL); - - evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1; - evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1; - evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1); - return (Unit)evalAtXforYret; - } - - static inline typename high_precision_type<Unit>::type evalAtXforY(Unit xIn, Point pt, Point other_pt) { - typename high_precision_type<Unit>::type - evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx, - evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0; - //y = (x - x1)dy/dx + y1 - //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y - //assert pt.x != other_pt.x - typedef typename high_precision_type<Unit>::type high_precision; - if(pt.y() == other_pt.y()) - return (high_precision)pt.y(); - evalAtXforYxIn = (high_precision)xIn; - evalAtXforYx1 = pt.get(HORIZONTAL); - evalAtXforYy1 = pt.get(VERTICAL); - evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1; - evalAtXforY0 = high_precision(0); - if(evalAtXforYdx1 == evalAtXforY0) return evalAtXforYret = evalAtXforYy1; - evalAtXforYx2 = (high_precision)other_pt.get(HORIZONTAL); - evalAtXforYy2 = (high_precision)other_pt.get(VERTICAL); - - evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1; - evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1; - evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1); - return evalAtXforYret; - } - - struct evalAtXforYPack { - typename high_precision_type<Unit>::type - evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx, - evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0; - inline const typename high_precision_type<Unit>::type& evalAtXforY(Unit xIn, Point pt, Point other_pt) { - //y = (x - x1)dy/dx + y1 - //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y - //assert pt.x != other_pt.x - typedef typename high_precision_type<Unit>::type high_precision; - if(pt.y() == other_pt.y()) { - evalAtXforYret = (high_precision)pt.y(); - return evalAtXforYret; - } - evalAtXforYxIn = (high_precision)xIn; - evalAtXforYx1 = pt.get(HORIZONTAL); - evalAtXforYy1 = pt.get(VERTICAL); - evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1; - evalAtXforY0 = high_precision(0); - if(evalAtXforYdx1 == evalAtXforY0) return evalAtXforYret = evalAtXforYy1; - evalAtXforYx2 = (high_precision)other_pt.get(HORIZONTAL); - evalAtXforYy2 = (high_precision)other_pt.get(VERTICAL); - - evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1; - evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1; - evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1); - return evalAtXforYret; - } - }; - - static inline bool is_vertical(const half_edge& he) { - return he.first.get(HORIZONTAL) == he.second.get(HORIZONTAL); - } - - static inline bool is_horizontal(const half_edge& he) { - return he.first.get(VERTICAL) == he.second.get(VERTICAL); - } - - static inline bool is_45_degree(const half_edge& he) { - return euclidean_distance(he.first, he.second, HORIZONTAL) == euclidean_distance(he.first, he.second, VERTICAL); - } - - //scanline comparator functor - class less_half_edge { - private: - Unit *x_; //x value at which to apply comparison - int *justBefore_; - evalAtXforYPack * pack_; - public: - typedef half_edge first_argument_type; - typedef half_edge second_argument_type; - typedef bool result_type; - inline less_half_edge() : x_(0), justBefore_(0), pack_(0) {} - inline less_half_edge(Unit *x, int *justBefore, evalAtXforYPack * packIn) : x_(x), justBefore_(justBefore), pack_(packIn) {} - inline less_half_edge(const less_half_edge& that) : x_(that.x_), justBefore_(that.justBefore_), - pack_(that.pack_){} - inline less_half_edge& operator=(const less_half_edge& that) { - x_ = that.x_; - justBefore_ = that.justBefore_; - pack_ = that.pack_; - return *this; } - inline bool operator () (const half_edge& elm1, const half_edge& elm2) const { - if((std::max)(elm1.first.y(), elm1.second.y()) < (std::min)(elm2.first.y(), elm2.second.y())) - return true; - if((std::min)(elm1.first.y(), elm1.second.y()) > (std::max)(elm2.first.y(), elm2.second.y())) - return false; - - //check if either x of elem1 is equal to x_ - Unit localx = *x_; - Unit elm1y = 0; - bool elm1_at_x = false; - if(localx == elm1.first.get(HORIZONTAL)) { - elm1_at_x = true; - elm1y = elm1.first.get(VERTICAL); - } else if(localx == elm1.second.get(HORIZONTAL)) { - elm1_at_x = true; - elm1y = elm1.second.get(VERTICAL); - } - Unit elm2y = 0; - bool elm2_at_x = false; - if(localx == elm2.first.get(HORIZONTAL)) { - elm2_at_x = true; - elm2y = elm2.first.get(VERTICAL); - } else if(localx == elm2.second.get(HORIZONTAL)) { - elm2_at_x = true; - elm2y = elm2.second.get(VERTICAL); - } - bool retval = false; - if(!(elm1_at_x && elm2_at_x)) { - //at least one of the segments doesn't have an end point a the current x - //-1 below, 1 above - int pt1_oab = on_above_or_below(elm1.first, half_edge(elm2.first, elm2.second)); - int pt2_oab = on_above_or_below(elm1.second, half_edge(elm2.first, elm2.second)); - if(pt1_oab == pt2_oab) { - if(pt1_oab == -1) - retval = true; //pt1 is below elm2 so elm1 is below elm2 - } else { - //the segments can't cross so elm2 is on whatever side of elm1 that one of its ends is - int pt3_oab = on_above_or_below(elm2.first, half_edge(elm1.first, elm1.second)); - if(pt3_oab == 1) - retval = true; //elm1's point is above elm1 - } - } else { - if(elm1y < elm2y) { - retval = true; - } else if(elm1y == elm2y) { - if(elm1 == elm2) - return false; - retval = less_slope(elm1.second.get(HORIZONTAL) - elm1.first.get(HORIZONTAL), - elm1.second.get(VERTICAL) - elm1.first.get(VERTICAL), - elm2.second.get(HORIZONTAL) - elm2.first.get(HORIZONTAL), - elm2.second.get(VERTICAL) - elm2.first.get(VERTICAL)); - retval = ((*justBefore_) != 0) ^ retval; - } - } - return retval; - } - }; - - template <typename unsigned_product_type> - static inline void unsigned_add(unsigned_product_type& result, int& result_sign, unsigned_product_type a, int a_sign, unsigned_product_type b, int b_sign) { - int switcher = 0; - if(a_sign < 0) switcher += 1; - if(b_sign < 0) switcher += 2; - if(a < b) switcher += 4; - switch (switcher) { - case 0: //both positive - result = a + b; - result_sign = 1; - break; - case 1: //a is negative - result = a - b; - result_sign = -1; - break; - case 2: //b is negative - result = a - b; - result_sign = 1; - break; - case 3: //both negative - result = a + b; - result_sign = -1; - break; - case 4: //both positive - result = a + b; - result_sign = 1; - break; - case 5: //a is negative - result = b - a; - result_sign = 1; - break; - case 6: //b is negative - result = b - a; - result_sign = -1; - break; - case 7: //both negative - result = b + a; - result_sign = -1; - break; - }; - } - - struct compute_intersection_pack { - typedef typename high_precision_type<Unit>::type high_precision; - high_precision y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y; - static inline bool compute_lazy_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, - bool projected = false, bool round_closest = false) { - long double y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y; - typedef rectangle_data<Unit> Rectangle; - Rectangle rect1, rect2; - set_points(rect1, he1.first, he1.second); - set_points(rect2, he2.first, he2.second); - if(!projected && !::boost::polygon::intersects(rect1, rect2, true)) return false; - if(is_vertical(he1)) { - if(is_vertical(he2)) return false; - y_high = evalAtXforYlazy(he1.first.get(HORIZONTAL), he2.first, he2.second); - Unit y_local = (Unit)y_high; - if(y_high < y_local) --y_local; - if(projected || contains(rect1.get(VERTICAL), y_local, true)) { - intersection = Point(he1.first.get(HORIZONTAL), y_local); - return true; - } else { - return false; - } - } else if(is_vertical(he2)) { - y_high = evalAtXforYlazy(he2.first.get(HORIZONTAL), he1.first, he1.second); - Unit y_local = (Unit)y_high; - if(y_high < y_local) --y_local; - if(projected || contains(rect2.get(VERTICAL), y_local, true)) { - intersection = Point(he2.first.get(HORIZONTAL), y_local); - return true; - } else { - return false; - } - } - //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point - dy2 = (he2.second.get(VERTICAL)) - - (he2.first.get(VERTICAL)); - dy1 = (he1.second.get(VERTICAL)) - - (he1.first.get(VERTICAL)); - dx2 = (he2.second.get(HORIZONTAL)) - - (he2.first.get(HORIZONTAL)); - dx1 = (he1.second.get(HORIZONTAL)) - - (he1.first.get(HORIZONTAL)); - if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false; - //the line segments have different slopes - //we can assume that the line segments are not vertical because such an intersection is handled elsewhere - x11 = (he1.first.get(HORIZONTAL)); - x21 = (he2.first.get(HORIZONTAL)); - y11 = (he1.first.get(VERTICAL)); - y21 = (he2.first.get(VERTICAL)); - //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1); - //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1); - x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2); - x_den = (dy1 * dx2 - dy2 * dx1); - y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2); - y_den = (dx1 * dy2 - dx2 * dy1); - x = x_num / x_den; - y = y_num / y_den; - //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << "\n"; - //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << "\n"; - //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2); - //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2); - if(round_closest) { - x = x + 0.5; - y = y + 0.5; - } - Unit x_unit = (Unit)(x); - Unit y_unit = (Unit)(y); - //truncate downward if it went up due to negative number - if(x < x_unit) --x_unit; - if(y < y_unit) --y_unit; - if(is_horizontal(he1)) - y_unit = he1.first.y(); - if(is_horizontal(he2)) - y_unit = he2.first.y(); - //if(x != exp_x || y != exp_y) - // std::cout << exp_x << " " << exp_y << " " << x << " " << y << "\n"; - //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second); - //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second); - //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << "\n"; - Point result(x_unit, y_unit); - if(!projected && !contains(rect1, result, true)) return false; - if(!projected && !contains(rect2, result, true)) return false; - if(projected) { - rectangle_data<long double> inf_rect(-(long double)(std::numeric_limits<Unit>::max)(), - -(long double) (std::numeric_limits<Unit>::max)(), - (long double)(std::numeric_limits<Unit>::max)(), - (long double) (std::numeric_limits<Unit>::max)() ); - if(contains(inf_rect, point_data<long double>(x, y), true)) { - intersection = result; - return true; - } else - return false; - } - intersection = result; - return true; - } - - inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, - bool projected = false, bool round_closest = false) { - if(!projected && !intersects(he1, he2)) - return false; - bool lazy_success = compute_lazy_intersection(intersection, he1, he2, projected); - if(!projected) { - if(lazy_success) { - if(intersects_grid(intersection, he1) && - intersects_grid(intersection, he2)) - return true; - } - } else { - return lazy_success; - } - return compute_exact_intersection(intersection, he1, he2, projected, round_closest); - } - - inline bool compute_exact_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, - bool projected = false, bool round_closest = false) { - if(!projected && !intersects(he1, he2)) - return false; - typedef rectangle_data<Unit> Rectangle; - Rectangle rect1, rect2; - set_points(rect1, he1.first, he1.second); - set_points(rect2, he2.first, he2.second); - if(!::boost::polygon::intersects(rect1, rect2, true)) return false; - if(is_vertical(he1)) { - if(is_vertical(he2)) return false; - y_high = evalAtXforY(he1.first.get(HORIZONTAL), he2.first, he2.second); - Unit y = convert_high_precision_type<Unit>(y_high); - if(y_high < (high_precision)y) --y; - if(contains(rect1.get(VERTICAL), y, true)) { - intersection = Point(he1.first.get(HORIZONTAL), y); - return true; - } else { - return false; - } - } else if(is_vertical(he2)) { - y_high = evalAtXforY(he2.first.get(HORIZONTAL), he1.first, he1.second); - Unit y = convert_high_precision_type<Unit>(y_high); - if(y_high < (high_precision)y) --y; - if(contains(rect2.get(VERTICAL), y, true)) { - intersection = Point(he2.first.get(HORIZONTAL), y); - return true; - } else { - return false; - } - } - //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point - dy2 = (high_precision)(he2.second.get(VERTICAL)) - - (high_precision)(he2.first.get(VERTICAL)); - dy1 = (high_precision)(he1.second.get(VERTICAL)) - - (high_precision)(he1.first.get(VERTICAL)); - dx2 = (high_precision)(he2.second.get(HORIZONTAL)) - - (high_precision)(he2.first.get(HORIZONTAL)); - dx1 = (high_precision)(he1.second.get(HORIZONTAL)) - - (high_precision)(he1.first.get(HORIZONTAL)); - if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false; - //the line segments have different slopes - //we can assume that the line segments are not vertical because such an intersection is handled elsewhere - x11 = (high_precision)(he1.first.get(HORIZONTAL)); - x21 = (high_precision)(he2.first.get(HORIZONTAL)); - y11 = (high_precision)(he1.first.get(VERTICAL)); - y21 = (high_precision)(he2.first.get(VERTICAL)); - //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1); - //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1); - x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2); - x_den = (dy1 * dx2 - dy2 * dx1); - y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2); - y_den = (dx1 * dy2 - dx2 * dy1); - x = x_num / x_den; - y = y_num / y_den; - //std::cout << x << " " << y << "\n"; - //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << "\n"; - //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << "\n"; - //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2); - //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2); - if(round_closest) { - x = x + (high_precision)0.5; - y = y + (high_precision)0.5; - } - Unit x_unit = convert_high_precision_type<Unit>(x); - Unit y_unit = convert_high_precision_type<Unit>(y); - //truncate downward if it went up due to negative number - if(x < (high_precision)x_unit) --x_unit; - if(y < (high_precision)y_unit) --y_unit; - if(is_horizontal(he1)) - y_unit = he1.first.y(); - if(is_horizontal(he2)) - y_unit = he2.first.y(); - //if(x != exp_x || y != exp_y) - // std::cout << exp_x << " " << exp_y << " " << x << " " << y << "\n"; - //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second); - //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second); - //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << "\n"; - Point result(x_unit, y_unit); - if(!contains(rect1, result, true)) return false; - if(!contains(rect2, result, true)) return false; - if(projected) { - high_precision b1 = (high_precision) (std::numeric_limits<Unit>::min)(); - high_precision b2 = (high_precision) (std::numeric_limits<Unit>::max)(); - if(x > b2 || y > b2 || x < b1 || y < b1) - return false; - } - intersection = result; - return true; - } - }; - - static inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2) { - typedef typename high_precision_type<Unit>::type high_precision; - typedef rectangle_data<Unit> Rectangle; - Rectangle rect1, rect2; - set_points(rect1, he1.first, he1.second); - set_points(rect2, he2.first, he2.second); - if(!::boost::polygon::intersects(rect1, rect2, true)) return false; - if(is_vertical(he1)) { - if(is_vertical(he2)) return false; - high_precision y_high = evalAtXforY(he1.first.get(HORIZONTAL), he2.first, he2.second); - Unit y = convert_high_precision_type<Unit>(y_high); - if(y_high < (high_precision)y) --y; - if(contains(rect1.get(VERTICAL), y, true)) { - intersection = Point(he1.first.get(HORIZONTAL), y); - return true; - } else { - return false; - } - } else if(is_vertical(he2)) { - high_precision y_high = evalAtXforY(he2.first.get(HORIZONTAL), he1.first, he1.second); - Unit y = convert_high_precision_type<Unit>(y_high); - if(y_high < (high_precision)y) --y; - if(contains(rect2.get(VERTICAL), y, true)) { - intersection = Point(he2.first.get(HORIZONTAL), y); - return true; - } else { - return false; - } - } - //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point - high_precision dy2 = (high_precision)(he2.second.get(VERTICAL)) - - (high_precision)(he2.first.get(VERTICAL)); - high_precision dy1 = (high_precision)(he1.second.get(VERTICAL)) - - (high_precision)(he1.first.get(VERTICAL)); - high_precision dx2 = (high_precision)(he2.second.get(HORIZONTAL)) - - (high_precision)(he2.first.get(HORIZONTAL)); - high_precision dx1 = (high_precision)(he1.second.get(HORIZONTAL)) - - (high_precision)(he1.first.get(HORIZONTAL)); - if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false; - //the line segments have different slopes - //we can assume that the line segments are not vertical because such an intersection is handled elsewhere - high_precision x11 = (high_precision)(he1.first.get(HORIZONTAL)); - high_precision x21 = (high_precision)(he2.first.get(HORIZONTAL)); - high_precision y11 = (high_precision)(he1.first.get(VERTICAL)); - high_precision y21 = (high_precision)(he2.first.get(VERTICAL)); - //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1); - //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1); - high_precision x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2); - high_precision x_den = (dy1 * dx2 - dy2 * dx1); - high_precision y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2); - high_precision y_den = (dx1 * dy2 - dx2 * dy1); - high_precision x = x_num / x_den; - high_precision y = y_num / y_den; - //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << "\n"; - //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << "\n"; - //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2); - //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2); - Unit x_unit = convert_high_precision_type<Unit>(x); - Unit y_unit = convert_high_precision_type<Unit>(y); - //truncate downward if it went up due to negative number - if(x < (high_precision)x_unit) --x_unit; - if(y < (high_precision)y_unit) --y_unit; - if(is_horizontal(he1)) - y_unit = he1.first.y(); - if(is_horizontal(he2)) - y_unit = he2.first.y(); - //if(x != exp_x || y != exp_y) - // std::cout << exp_x << " " << exp_y << " " << x << " " << y << "\n"; - //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second); - //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second); - //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << "\n"; - Point result(x_unit, y_unit); - if(!contains(rect1, result, true)) return false; - if(!contains(rect2, result, true)) return false; - intersection = result; - return true; - } - - static inline bool intersects(const half_edge& he1, const half_edge& he2) { - typedef rectangle_data<Unit> Rectangle; - Rectangle rect1, rect2; - set_points(rect1, he1.first, he1.second); - set_points(rect2, he2.first, he2.second); - if(::boost::polygon::intersects(rect1, rect2, false)) { - if(he1.first == he2.first) { - if(he1.second != he2.second && equal_slope(he1.first.get(HORIZONTAL), he1.first.get(VERTICAL), - he1.second, he2.second)) { - return true; - } else { - return false; - } - } - if(he1.first == he2.second) { - if(he1.second != he2.first && equal_slope(he1.first.get(HORIZONTAL), he1.first.get(VERTICAL), - he1.second, he2.first)) { - return true; - } else { - return false; - } - } - if(he1.second == he2.first) { - if(he1.first != he2.second && equal_slope(he1.second.get(HORIZONTAL), he1.second.get(VERTICAL), - he1.first, he2.second)) { - return true; - } else { - return false; - } - } - if(he1.second == he2.second) { - if(he1.first != he2.first && equal_slope(he1.second.get(HORIZONTAL), he1.second.get(VERTICAL), - he1.first, he2.first)) { - return true; - } else { - return false; - } - } - int oab1 = on_above_or_below(he1.first, he2); - if(oab1 == 0 && between(he1.first, he2.first, he2.second)) return true; - int oab2 = on_above_or_below(he1.second, he2); - if(oab2 == 0 && between(he1.second, he2.first, he2.second)) return true; - if(oab1 == oab2 && oab1 != 0) return false; //both points of he1 are on same side of he2 - int oab3 = on_above_or_below(he2.first, he1); - if(oab3 == 0 && between(he2.first, he1.first, he1.second)) return true; - int oab4 = on_above_or_below(he2.second, he1); - if(oab4 == 0 && between(he2.second, he1.first, he1.second)) return true; - if(oab3 == oab4) return false; //both points of he2 are on same side of he1 - return true; //they must cross - } - if(is_vertical(he1) && is_vertical(he2) && he1.first.get(HORIZONTAL) == he2.first.get(HORIZONTAL)) - return ::boost::polygon::intersects(rect1.get(VERTICAL), rect2.get(VERTICAL), false) && - rect1.get(VERTICAL) != rect2.get(VERTICAL); - if(is_horizontal(he1) && is_horizontal(he2) && he1.first.get(VERTICAL) == he2.first.get(VERTICAL)) - return ::boost::polygon::intersects(rect1.get(HORIZONTAL), rect2.get(HORIZONTAL), false) && - rect1.get(HORIZONTAL) != rect2.get(HORIZONTAL); - return false; - } - - class vertex_half_edge { - public: - typedef typename high_precision_type<Unit>::type high_precision; - Point pt; - Point other_pt; // 1, 0 or -1 - int count; //dxdydTheta - inline vertex_half_edge() : pt(), other_pt(), count() {} - inline vertex_half_edge(const Point& point, const Point& other_point, int countIn) : pt(point), other_pt(other_point), count(countIn) {} - inline vertex_half_edge(const vertex_half_edge& vertex) : pt(vertex.pt), other_pt(vertex.other_pt), count(vertex.count) {} - inline vertex_half_edge& operator=(const vertex_half_edge& vertex){ - pt = vertex.pt; other_pt = vertex.other_pt; count = vertex.count; return *this; } - inline bool operator==(const vertex_half_edge& vertex) const { - return pt == vertex.pt && other_pt == vertex.other_pt && count == vertex.count; } - inline bool operator!=(const vertex_half_edge& vertex) const { return !((*this) == vertex); } - inline bool operator<(const vertex_half_edge& vertex) const { - if(pt.get(HORIZONTAL) < vertex.pt.get(HORIZONTAL)) return true; - if(pt.get(HORIZONTAL) == vertex.pt.get(HORIZONTAL)) { - if(pt.get(VERTICAL) < vertex.pt.get(VERTICAL)) return true; - if(pt.get(VERTICAL) == vertex.pt.get(VERTICAL)) { return less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), - other_pt, vertex.other_pt); - } - } - return false; - } - inline bool operator>(const vertex_half_edge& vertex) const { return vertex < (*this); } - inline bool operator<=(const vertex_half_edge& vertex) const { return !((*this) > vertex); } - inline bool operator>=(const vertex_half_edge& vertex) const { return !((*this) < vertex); } - inline high_precision evalAtX(Unit xIn) const { return evalAtXforYlazy(xIn, pt, other_pt); } - inline bool is_vertical() const { - return pt.get(HORIZONTAL) == other_pt.get(HORIZONTAL); - } - inline bool is_begin() const { - return pt.get(HORIZONTAL) < other_pt.get(HORIZONTAL) || - (pt.get(HORIZONTAL) == other_pt.get(HORIZONTAL) && - (pt.get(VERTICAL) < other_pt.get(VERTICAL))); - } - }; - - //when scanning Vertex45 for polygon formation we need a scanline comparator functor - class less_vertex_half_edge { - private: - Unit *x_; //x value at which to apply comparison - int *justBefore_; - public: - typedef vertex_half_edge first_argument_type; - typedef vertex_half_edge second_argument_type; - typedef bool result_type; - inline less_vertex_half_edge() : x_(0), justBefore_(0) {} - inline less_vertex_half_edge(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {} - inline less_vertex_half_edge(const less_vertex_half_edge& that) : x_(that.x_), justBefore_(that.justBefore_) {} - inline less_vertex_half_edge& operator=(const less_vertex_half_edge& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; } - inline bool operator () (const vertex_half_edge& elm1, const vertex_half_edge& elm2) const { - if((std::max)(elm1.pt.y(), elm1.other_pt.y()) < (std::min)(elm2.pt.y(), elm2.other_pt.y())) - return true; - if((std::min)(elm1.pt.y(), elm1.other_pt.y()) > (std::max)(elm2.pt.y(), elm2.other_pt.y())) - return false; - //check if either x of elem1 is equal to x_ - Unit localx = *x_; - Unit elm1y = 0; - bool elm1_at_x = false; - if(localx == elm1.pt.get(HORIZONTAL)) { - elm1_at_x = true; - elm1y = elm1.pt.get(VERTICAL); - } else if(localx == elm1.other_pt.get(HORIZONTAL)) { - elm1_at_x = true; - elm1y = elm1.other_pt.get(VERTICAL); - } - Unit elm2y = 0; - bool elm2_at_x = false; - if(localx == elm2.pt.get(HORIZONTAL)) { - elm2_at_x = true; - elm2y = elm2.pt.get(VERTICAL); - } else if(localx == elm2.other_pt.get(HORIZONTAL)) { - elm2_at_x = true; - elm2y = elm2.other_pt.get(VERTICAL); - } - bool retval = false; - if(!(elm1_at_x && elm2_at_x)) { - //at least one of the segments doesn't have an end point a the current x - //-1 below, 1 above - int pt1_oab = on_above_or_below(elm1.pt, half_edge(elm2.pt, elm2.other_pt)); - int pt2_oab = on_above_or_below(elm1.other_pt, half_edge(elm2.pt, elm2.other_pt)); - if(pt1_oab == pt2_oab) { - if(pt1_oab == -1) - retval = true; //pt1 is below elm2 so elm1 is below elm2 - } else { - //the segments can't cross so elm2 is on whatever side of elm1 that one of its ends is - int pt3_oab = on_above_or_below(elm2.pt, half_edge(elm1.pt, elm1.other_pt)); - if(pt3_oab == 1) - retval = true; //elm1's point is above elm1 - } - } else { - if(elm1y < elm2y) { - retval = true; - } else if(elm1y == elm2y) { - if(elm1.pt == elm2.pt && elm1.other_pt == elm2.other_pt) - return false; - retval = less_slope(elm1.other_pt.get(HORIZONTAL) - elm1.pt.get(HORIZONTAL), - elm1.other_pt.get(VERTICAL) - elm1.pt.get(VERTICAL), - elm2.other_pt.get(HORIZONTAL) - elm2.pt.get(HORIZONTAL), - elm2.other_pt.get(VERTICAL) - elm2.pt.get(VERTICAL)); - retval = ((*justBefore_) != 0) ^ retval; - } - } - return retval; - } - }; - - }; - - template <typename Unit> - class polygon_arbitrary_formation : public scanline_base<Unit> { - public: - typedef typename scanline_base<Unit>::Point Point; - typedef typename scanline_base<Unit>::half_edge half_edge; - typedef typename scanline_base<Unit>::vertex_half_edge vertex_half_edge; - typedef typename scanline_base<Unit>::less_vertex_half_edge less_vertex_half_edge; - - class poly_line_arbitrary { - public: - typedef typename std::list<Point>::const_iterator iterator; - - // default constructor of point does not initialize x and y - inline poly_line_arbitrary() : points() {} //do nothing default constructor - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline poly_line_arbitrary& set(iT inputBegin, iT inputEnd) { - points.clear(); //just in case there was some old data there - while(inputBegin != inputEnd) { - points.insert(points.end(), *inputBegin); - ++inputBegin; - } - return *this; - } - - // copy constructor (since we have dynamic memory) - inline poly_line_arbitrary(const poly_line_arbitrary& that) : points(that.points) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline poly_line_arbitrary& operator=(const poly_line_arbitrary& that) { - points = that.points; - return *this; - } - - // get begin iterator, returns a pointer to a const Unit - inline iterator begin() const { return points.begin(); } - - // get end iterator, returns a pointer to a const Unit - inline iterator end() const { return points.end(); } - - inline std::size_t size() const { return points.size(); } - - //public data member - std::list<Point> points; - }; - - class active_tail_arbitrary { - protected: - //data - poly_line_arbitrary* tailp_; - active_tail_arbitrary *otherTailp_; - std::list<active_tail_arbitrary*> holesList_; - bool head_; - public: - - /** - * @brief iterator over coordinates of the figure - */ - typedef typename poly_line_arbitrary::iterator iterator; - - /** - * @brief iterator over holes contained within the figure - */ - typedef typename std::list<active_tail_arbitrary*>::const_iterator iteratorHoles; - - //default constructor - inline active_tail_arbitrary() : tailp_(), otherTailp_(), holesList_(), head_() {} - - //constructor - inline active_tail_arbitrary(const vertex_half_edge& vertex, active_tail_arbitrary* otherTailp = 0) : tailp_(), otherTailp_(), holesList_(), head_() { - tailp_ = new poly_line_arbitrary; - tailp_->points.push_back(vertex.pt); - //bool headArray[4] = {false, true, true, true}; - bool inverted = vertex.count == -1; - head_ = (!vertex.is_vertical) ^ inverted; - otherTailp_ = otherTailp; - } - - inline active_tail_arbitrary(Point point, active_tail_arbitrary* otherTailp, bool head = true) : - tailp_(), otherTailp_(), holesList_(), head_() { - tailp_ = new poly_line_arbitrary; - tailp_->points.push_back(point); - head_ = head; - otherTailp_ = otherTailp; - - } - inline active_tail_arbitrary(active_tail_arbitrary* otherTailp) : - tailp_(), otherTailp_(), holesList_(), head_() { - tailp_ = otherTailp->tailp_; - otherTailp_ = otherTailp; - } - - //copy constructor - inline active_tail_arbitrary(const active_tail_arbitrary& that) : - tailp_(), otherTailp_(), holesList_(), head_() { (*this) = that; } - - //destructor - inline ~active_tail_arbitrary() { - destroyContents(); - } - - //assignment operator - inline active_tail_arbitrary& operator=(const active_tail_arbitrary& that) { - tailp_ = new poly_line_arbitrary(*(that.tailp_)); - head_ = that.head_; - otherTailp_ = that.otherTailp_; - holesList_ = that.holesList_; - return *this; - } - - //equivalence operator - inline bool operator==(const active_tail_arbitrary& b) const { - return tailp_ == b.tailp_ && head_ == b.head_; - } - - /** - * @brief get the pointer to the polyline that this is an active tail of - */ - inline poly_line_arbitrary* getTail() const { return tailp_; } - - /** - * @brief get the pointer to the polyline at the other end of the chain - */ - inline poly_line_arbitrary* getOtherTail() const { return otherTailp_->tailp_; } - - /** - * @brief get the pointer to the activetail at the other end of the chain - */ - inline active_tail_arbitrary* getOtherActiveTail() const { return otherTailp_; } - - /** - * @brief test if another active tail is the other end of the chain - */ - inline bool isOtherTail(const active_tail_arbitrary& b) const { return &b == otherTailp_; } - - /** - * @brief update this end of chain pointer to new polyline - */ - inline active_tail_arbitrary& updateTail(poly_line_arbitrary* newTail) { tailp_ = newTail; return *this; } - - inline bool join(active_tail_arbitrary* tail) { - if(tail == otherTailp_) { - //std::cout << "joining to other tail!\n"; - return false; - } - if(tail->head_ == head_) { - //std::cout << "joining head to head!\n"; - return false; - } - if(!tailp_) { - //std::cout << "joining empty tail!\n"; - return false; - } - if(!(otherTailp_->head_)) { - otherTailp_->copyHoles(*tail); - otherTailp_->copyHoles(*this); - } else { - tail->otherTailp_->copyHoles(*this); - tail->otherTailp_->copyHoles(*tail); - } - poly_line_arbitrary* tail1 = tailp_; - poly_line_arbitrary* tail2 = tail->tailp_; - if(head_) std::swap(tail1, tail2); - typename std::list<point_data<Unit> >::reverse_iterator riter = tail1->points.rbegin(); - typename std::list<point_data<Unit> >::iterator iter = tail2->points.begin(); - if(*riter == *iter) { - tail1->points.pop_back(); //remove duplicate point - } - tail1->points.splice(tail1->points.end(), tail2->points); - delete tail2; - otherTailp_->tailp_ = tail1; - tail->otherTailp_->tailp_ = tail1; - otherTailp_->otherTailp_ = tail->otherTailp_; - tail->otherTailp_->otherTailp_ = otherTailp_; - tailp_ = 0; - tail->tailp_ = 0; - tail->otherTailp_ = 0; - otherTailp_ = 0; - return true; - } - - /** - * @brief associate a hole to this active tail by the specified policy - */ - inline active_tail_arbitrary* addHole(active_tail_arbitrary* hole) { - holesList_.push_back(hole); - copyHoles(*hole); - copyHoles(*(hole->otherTailp_)); - return this; - } - - /** - * @brief get the list of holes - */ - inline const std::list<active_tail_arbitrary*>& getHoles() const { return holesList_; } - - /** - * @brief copy holes from that to this - */ - inline void copyHoles(active_tail_arbitrary& that) { holesList_.splice(holesList_.end(), that.holesList_); } - - /** - * @brief find out if solid to right - */ - inline bool solidToRight() const { return !head_; } - inline bool solidToLeft() const { return head_; } - - /** - * @brief get vertex - */ - inline Point getPoint() const { - if(head_) return tailp_->points.front(); - return tailp_->points.back(); - } - - /** - * @brief add a coordinate to the polygon at this active tail end, properly handle degenerate edges by removing redundant coordinate - */ - inline void pushPoint(Point point) { - if(head_) { - //if(tailp_->points.size() < 2) { - // tailp_->points.push_front(point); - // return; - //} - typename std::list<Point>::iterator iter = tailp_->points.begin(); - if(iter == tailp_->points.end()) { - tailp_->points.push_front(point); - return; - } - ++iter; - if(iter == tailp_->points.end()) { - tailp_->points.push_front(point); - return; - } - --iter; - if(*iter != point) { - tailp_->points.push_front(point); - } - return; - } - //if(tailp_->points.size() < 2) { - // tailp_->points.push_back(point); - // return; - //} - typename std::list<Point>::reverse_iterator iter = tailp_->points.rbegin(); - if(iter == tailp_->points.rend()) { - tailp_->points.push_back(point); - return; - } - ++iter; - if(iter == tailp_->points.rend()) { - tailp_->points.push_back(point); - return; - } - --iter; - if(*iter != point) { - tailp_->points.push_back(point); - } - } - - /** - * @brief joins the two chains that the two active tail tails are ends of - * checks for closure of figure and writes out polygons appropriately - * returns a handle to a hole if one is closed - */ - template <class cT> - static inline active_tail_arbitrary* joinChains(Point point, active_tail_arbitrary* at1, active_tail_arbitrary* at2, bool solid, - cT& output) { - if(at1->otherTailp_ == at2) { - //if(at2->otherTailp_ != at1) std::cout << "half closed error\n"; - //we are closing a figure - at1->pushPoint(point); - at2->pushPoint(point); - if(solid) { - //we are closing a solid figure, write to output - //std::cout << "test1\n"; - at1->copyHoles(*(at1->otherTailp_)); - typename PolyLineArbitraryByConcept<Unit, typename geometry_concept<typename cT::value_type>::type>::type polyData(at1); - //poly_line_arbitrary_polygon_data polyData(at1); - //std::cout << "test2\n"; - //std::cout << poly << "\n"; - //std::cout << "test3\n"; - typedef typename cT::value_type result_type; - output.push_back(result_type()); - assign(output.back(), polyData); - //std::cout << "test4\n"; - //std::cout << "delete " << at1->otherTailp_ << "\n"; - //at1->print(); - //at1->otherTailp_->print(); - delete at1->otherTailp_; - //at1->print(); - //at1->otherTailp_->print(); - //std::cout << "test5\n"; - //std::cout << "delete " << at1 << "\n"; - delete at1; - //std::cout << "test6\n"; - return 0; - } else { - //we are closing a hole, return the tail end active tail of the figure - return at1; - } - } - //we are not closing a figure - at1->pushPoint(point); - at1->join(at2); - delete at1; - delete at2; - return 0; - } - - inline void destroyContents() { - if(otherTailp_) { - //std::cout << "delete p " << tailp_ << "\n"; - if(tailp_) delete tailp_; - tailp_ = 0; - otherTailp_->otherTailp_ = 0; - otherTailp_->tailp_ = 0; - otherTailp_ = 0; - } - for(typename std::list<active_tail_arbitrary*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) { - //std::cout << "delete p " << (*itr) << "\n"; - if(*itr) { - if((*itr)->otherTailp_) { - delete (*itr)->otherTailp_; - (*itr)->otherTailp_ = 0; - } - delete (*itr); - } - (*itr) = 0; - } - holesList_.clear(); - } - - inline void print() { - //std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n"; - } - - static inline std::pair<active_tail_arbitrary*, active_tail_arbitrary*> createActiveTailsAsPair(Point point, bool solid, - active_tail_arbitrary* phole, bool fractureHoles) { - active_tail_arbitrary* at1 = 0; - active_tail_arbitrary* at2 = 0; - if(phole && fractureHoles) { - //std::cout << "adding hole\n"; - at1 = phole; - //assert solid == false, we should be creating a corner with solid below and to the left if there was a hole - at2 = at1->getOtherActiveTail(); - at2->pushPoint(point); - at1->pushPoint(point); - } else { - at1 = new active_tail_arbitrary(point, at2, solid); - at2 = new active_tail_arbitrary(at1); - at1->otherTailp_ = at2; - at2->head_ = !solid; - if(phole) - at2->addHole(phole); //assert fractureHoles == false - } - return std::pair<active_tail_arbitrary*, active_tail_arbitrary*>(at1, at2); - } - - }; - - - typedef std::vector<std::pair<Point, int> > vertex_arbitrary_count; - - class less_half_edge_count { - private: - Point pt_; - public: - typedef vertex_half_edge first_argument_type; - typedef vertex_half_edge second_argument_type; - typedef bool result_type; - inline less_half_edge_count() : pt_() {} - inline less_half_edge_count(Point point) : pt_(point) {} - inline bool operator () (const std::pair<Point, int>& elm1, const std::pair<Point, int>& elm2) const { - return scanline_base<Unit>::less_slope(pt_.get(HORIZONTAL), pt_.get(VERTICAL), elm1.first, elm2.first); - } - }; - - static inline void sort_vertex_arbitrary_count(vertex_arbitrary_count& count, const Point& pt) { - less_half_edge_count lfec(pt); - polygon_sort(count.begin(), count.end(), lfec); - } - - typedef std::vector<std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> > incoming_count; - - class less_incoming_count { - private: - Point pt_; - public: - typedef std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> first_argument_type; - typedef std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> second_argument_type; - typedef bool result_type; - inline less_incoming_count() : pt_() {} - inline less_incoming_count(Point point) : pt_(point) {} - inline bool operator () (const std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>& elm1, - const std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>& elm2) const { - Unit dx1 = elm1.first.first.first.get(HORIZONTAL) - elm1.first.first.second.get(HORIZONTAL); - Unit dx2 = elm2.first.first.first.get(HORIZONTAL) - elm2.first.first.second.get(HORIZONTAL); - Unit dy1 = elm1.first.first.first.get(VERTICAL) - elm1.first.first.second.get(VERTICAL); - Unit dy2 = elm2.first.first.first.get(VERTICAL) - elm2.first.first.second.get(VERTICAL); - return scanline_base<Unit>::less_slope(dx1, dy1, dx2, dy2); - } - }; - - static inline void sort_incoming_count(incoming_count& count, const Point& pt) { - less_incoming_count lfec(pt); - polygon_sort(count.begin(), count.end(), lfec); - } - - static inline void compact_vertex_arbitrary_count(const Point& pt, vertex_arbitrary_count &count) { - if(count.empty()) return; - vertex_arbitrary_count tmp; - tmp.reserve(count.size()); - tmp.push_back(count[0]); - //merge duplicates - for(std::size_t i = 1; i < count.size(); ++i) { - if(!equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), tmp[i-1].first, count[i].first)) { - tmp.push_back(count[i]); - } else { - tmp.back().second += count[i].second; - } - } - count.clear(); - count.swap(tmp); - } - - // inline std::ostream& operator<< (std::ostream& o, const vertex_arbitrary_count& c) { -// for(unsinged int i = 0; i < c.size(); ++i) { -// o << c[i].first << " " << c[i].second << " "; -// } -// return o; -// } - - class vertex_arbitrary_compact { - public: - Point pt; - vertex_arbitrary_count count; - inline vertex_arbitrary_compact() : pt(), count() {} - inline vertex_arbitrary_compact(const Point& point, const Point& other_point, int countIn) : pt(point), count() { - count.push_back(std::pair<Point, int>(other_point, countIn)); - } - inline vertex_arbitrary_compact(const vertex_half_edge& vertex) : pt(vertex.pt), count() { - count.push_back(std::pair<Point, int>(vertex.other_pt, vertex.count)); - } - inline vertex_arbitrary_compact(const vertex_arbitrary_compact& vertex) : pt(vertex.pt), count(vertex.count) {} - inline vertex_arbitrary_compact& operator=(const vertex_arbitrary_compact& vertex){ - pt = vertex.pt; count = vertex.count; return *this; } - inline bool operator==(const vertex_arbitrary_compact& vertex) const { - return pt == vertex.pt && count == vertex.count; } - inline bool operator!=(const vertex_arbitrary_compact& vertex) const { return !((*this) == vertex); } - inline bool operator<(const vertex_arbitrary_compact& vertex) const { - if(pt.get(HORIZONTAL) < vertex.pt.get(HORIZONTAL)) return true; - if(pt.get(HORIZONTAL) == vertex.pt.get(HORIZONTAL)) { - return pt.get(VERTICAL) < vertex.pt.get(VERTICAL); - } - return false; - } - inline bool operator>(const vertex_arbitrary_compact& vertex) const { return vertex < (*this); } - inline bool operator<=(const vertex_arbitrary_compact& vertex) const { return !((*this) > vertex); } - inline bool operator>=(const vertex_arbitrary_compact& vertex) const { return !((*this) < vertex); } - inline bool have_vertex_half_edge(int index) const { return count[index]; } - inline vertex_half_edge operator[](int index) const { return vertex_half_edge(pt, count[index]); } - }; - -// inline std::ostream& operator<< (std::ostream& o, const vertex_arbitrary_compact& c) { -// o << c.pt << ", " << c.count; -// return o; -// } - - protected: - //definitions - typedef std::map<vertex_half_edge, active_tail_arbitrary*, less_vertex_half_edge> scanline_data; - typedef typename scanline_data::iterator iterator; - typedef typename scanline_data::const_iterator const_iterator; - - //data - scanline_data scanData_; - Unit x_; - int justBefore_; - int fractureHoles_; - public: - inline polygon_arbitrary_formation() : - scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { - less_vertex_half_edge lessElm(&x_, &justBefore_); - scanData_ = scanline_data(lessElm); - } - inline polygon_arbitrary_formation(bool fractureHoles) : - scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(fractureHoles) { - less_vertex_half_edge lessElm(&x_, &justBefore_); - scanData_ = scanline_data(lessElm); - } - inline polygon_arbitrary_formation(const polygon_arbitrary_formation& that) : - scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { (*this) = that; } - inline polygon_arbitrary_formation& operator=(const polygon_arbitrary_formation& that) { - x_ = that.x_; - justBefore_ = that.justBefore_; - fractureHoles_ = that.fractureHoles_; - less_vertex_half_edge lessElm(&x_, &justBefore_); - scanData_ = scanline_data(lessElm); - for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){ - scanData_.insert(scanData_.end(), *itr); - } - return *this; - } - - //cT is an output container of Polygon45 or Polygon45WithHoles - //iT is an iterator over vertex_half_edge elements - //inputBegin - inputEnd is a range of sorted iT that represents - //one or more scanline stops worth of data - template <class cT, class iT> - void scan(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "1\n"; - while(inputBegin != inputEnd) { - //std::cout << "2\n"; - x_ = (*inputBegin).pt.get(HORIZONTAL); - //std::cout << "SCAN FORMATION " << x_ << "\n"; - //std::cout << "x_ = " << x_ << "\n"; - //std::cout << "scan line size: " << scanData_.size() << "\n"; - inputBegin = processEvent_(output, inputBegin, inputEnd); - } - //std::cout << "scan line size: " << scanData_.size() << "\n"; - } - - protected: - //functions - template <class cT, class cT2> - inline std::pair<std::pair<Point, int>, active_tail_arbitrary*> processPoint_(cT& output, cT2& elements, Point point, - incoming_count& counts_from_scanline, vertex_arbitrary_count& incoming_count) { - //std::cout << "\nAT POINT: " << point << "\n"; - //join any closing solid corners - std::vector<int> counts; - std::vector<int> incoming; - std::vector<active_tail_arbitrary*> tails; - counts.reserve(counts_from_scanline.size()); - tails.reserve(counts_from_scanline.size()); - incoming.reserve(incoming_count.size()); - for(std::size_t i = 0; i < counts_from_scanline.size(); ++i) { - counts.push_back(counts_from_scanline[i].first.second); - tails.push_back(counts_from_scanline[i].second); - } - for(std::size_t i = 0; i < incoming_count.size(); ++i) { - incoming.push_back(incoming_count[i].second); - if(incoming_count[i].first < point) { - incoming.back() = 0; - } - } - - active_tail_arbitrary* returnValue = 0; - std::pair<Point, int> returnCount(Point(0, 0), 0); - int i_size_less_1 = (int)(incoming.size()) -1; - int c_size_less_1 = (int)(counts.size()) -1; - int i_size = incoming.size(); - int c_size = counts.size(); - - bool have_vertical_tail_from_below = false; - if(c_size && - scanline_base<Unit>::is_vertical(counts_from_scanline.back().first.first)) { - have_vertical_tail_from_below = true; - } - //assert size = size_less_1 + 1 - //std::cout << tails.size() << " " << incoming.size() << " " << counts_from_scanline.size() << " " << incoming_count.size() << "\n"; - // for(std::size_t i = 0; i < counts.size(); ++i) { - // std::cout << counts_from_scanline[i].first.first.first.get(HORIZONTAL) << ","; - // std::cout << counts_from_scanline[i].first.first.first.get(VERTICAL) << " "; - // std::cout << counts_from_scanline[i].first.first.second.get(HORIZONTAL) << ","; - // std::cout << counts_from_scanline[i].first.first.second.get(VERTICAL) << ":"; - // std::cout << counts_from_scanline[i].first.second << " "; - // } std::cout << "\n"; - // print(incoming_count); - { - for(int i = 0; i < c_size_less_1; ++i) { - //std::cout << i << "\n"; - if(counts[i] == -1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < c_size; ++j) { - //std::cout << j << "\n"; - if(counts[j]) { - if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << "\n"; - //if a figure is closed it will be written out by this function to output - active_tail_arbitrary::joinChains(point, tails[i], tails[j], true, output); - counts[i] = 0; - counts[j] = 0; - tails[i] = 0; - tails[j] = 0; - } - break; - } - } - } - } - } - //find any pairs of incoming edges that need to create pair for leading solid - //std::cout << "checking case2\n"; - { - for(int i = 0; i < i_size_less_1; ++i) { - //std::cout << i << "\n"; - if(incoming[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < i_size; ++j) { - //std::cout << j << "\n"; - if(incoming[j]) { - //std::cout << incoming[j] << "\n"; - if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << "\n"; - //std::cout << "creating active tail pair\n"; - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = - active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, fractureHoles_ != 0); - //tailPair.first->print(); - //tailPair.second->print(); - if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - //vertical active tail becomes return value - returnValue = tailPair.first; - returnCount.first = point; - returnCount.second = 1; - } else { - //std::cout << "new element " << j-1 << " " << -1 << "\n"; - //std::cout << point << " " << incoming_count[j].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, -1), tailPair.first)); - } - //std::cout << "new element " << i-1 << " " << 1 << "\n"; - //std::cout << point << " " << incoming_count[i].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[i].first, 1), tailPair.second)); - incoming[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - } - } - //find any active tail that needs to pass through to an incoming edge - //we expect to find no more than two pass through - - //find pass through with solid on top - { - //std::cout << "checking case 3\n"; - for(int i = 0; i < c_size; ++i) { - //std::cout << i << "\n"; - if(counts[i] != 0) { - if(counts[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = i_size_less_1; j >= 0; --j) { - if(incoming[j] != 0) { - if(incoming[j] == 1) { - //std::cout << "case3: " << i << " " << j << "\n"; - //tails[i]->print(); - //pass through solid on top - tails[i]->pushPoint(point); - //std::cout << "after push\n"; - if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - returnValue = tails[i]; - returnCount.first = point; - returnCount.second = -1; - } else { - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), tails[i])); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - } - //std::cout << "checking case 4\n"; - //find pass through with solid on bottom - { - for(int i = c_size_less_1; i >= 0; --i) { - //std::cout << "i = " << i << " with count " << counts[i] << "\n"; - if(counts[i] != 0) { - if(counts[i] == -1) { - for(int j = 0; j < i_size; ++j) { - if(incoming[j] != 0) { - if(incoming[j] == -1) { - //std::cout << "case4: " << i << " " << j << "\n"; - //pass through solid on bottom - tails[i]->pushPoint(point); - if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - returnValue = tails[i]; - returnCount.first = point; - returnCount.second = 1; - } else { - //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; - //std::cout << point << " " << incoming_count[j].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), tails[i])); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - } - //find the end of a hole or the beginning of a hole - - //find end of a hole - { - for(int i = 0; i < c_size_less_1; ++i) { - if(counts[i] != 0) { - for(int j = i+1; j < c_size; ++j) { - if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << "\n"; - //we are ending a hole and may potentially close a figure and have to handle the hole - returnValue = active_tail_arbitrary::joinChains(point, tails[i], tails[j], false, output); - if(returnValue) returnCount.first = point; - //std::cout << returnValue << "\n"; - tails[i] = 0; - tails[j] = 0; - counts[i] = 0; - counts[j] = 0; - break; - } - } - break; - } - } - } - //find beginning of a hole - { - for(int i = 0; i < i_size_less_1; ++i) { - if(incoming[i] != 0) { - for(int j = i+1; j < i_size; ++j) { - if(incoming[j] != 0) { - //std::cout << "case6: " << i << " " << j << "\n"; - //we are beginning a empty space - active_tail_arbitrary* holep = 0; - //if(c_size && counts[c_size_less_1] == 0 && - // counts_from_scanline[c_size_less_1].first.first.first.get(HORIZONTAL) == point.get(HORIZONTAL)) - if(have_vertical_tail_from_below) { - holep = tails[c_size_less_1]; - tails[c_size_less_1] = 0; - have_vertical_tail_from_below = false; - } - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = - active_tail_arbitrary::createActiveTailsAsPair(point, false, holep, fractureHoles_ != 0); - if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - //std::cout << "vertical element " << point << "\n"; - returnValue = tailPair.first; - returnCount.first = point; - //returnCount = incoming_count[j]; - returnCount.second = -1; - } else { - //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; - //std::cout << point << " " << incoming_count[j].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), tailPair.first)); - } - //std::cout << "new element " << i-1 << " " << incoming[i] << "\n"; - //std::cout << point << " " << incoming_count[i].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[i].first, incoming[i]), tailPair.second)); - incoming[i] = 0; - incoming[j] = 0; - break; - } - } - break; - } - } - } - if(have_vertical_tail_from_below) { - if(tails.back()) { - tails.back()->pushPoint(point); - returnValue = tails.back(); - returnCount.first = point; - returnCount.second = counts.back(); - } - } - //assert that tails, counts and incoming are all null - return std::pair<std::pair<Point, int>, active_tail_arbitrary*>(returnCount, returnValue); - } - - static inline void print(const vertex_arbitrary_count& count) { - for(unsigned i = 0; i < count.size(); ++i) { - //std::cout << count[i].first.get(HORIZONTAL) << ","; - //std::cout << count[i].first.get(VERTICAL) << ":"; - //std::cout << count[i].second << " "; - } //std::cout << "\n"; - } - - static inline void print(const scanline_data& data) { - for(typename scanline_data::const_iterator itr = data.begin(); itr != data.end(); ++itr){ - //std::cout << itr->first.pt << ", " << itr->first.other_pt << "; "; - } //std::cout << "\n"; - } - - template <class cT, class iT> - inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) { - typedef typename high_precision_type<Unit>::type high_precision; - //std::cout << "processEvent_\n"; - justBefore_ = true; - //collect up all elements from the tree that are at the y - //values of events in the input queue - //create vector of new elements to add into tree - active_tail_arbitrary* verticalTail = 0; - std::pair<Point, int> verticalCount(Point(0, 0), 0); - iT currentIter = inputBegin; - std::vector<iterator> elementIters; - std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> > elements; - while(currentIter != inputEnd && currentIter->pt.get(HORIZONTAL) == x_) { - //std::cout << "loop\n"; - Unit currentY = (*currentIter).pt.get(VERTICAL); - //std::cout << "current Y " << currentY << "\n"; - //std::cout << "scanline size " << scanData_.size() << "\n"; - //print(scanData_); - iterator iter = lookUp_(currentY); - //std::cout << "found element in scanline " << (iter != scanData_.end()) << "\n"; - //int counts[4] = {0, 0, 0, 0}; - incoming_count counts_from_scanline; - //std::cout << "finding elements in tree\n"; - //if(iter != scanData_.end()) - // std::cout << "first iter y is " << iter->first.evalAtX(x_) << "\n"; - while(iter != scanData_.end() && - ((iter->first.pt.x() == x_ && iter->first.pt.y() == currentY) || - (iter->first.other_pt.x() == x_ && iter->first.other_pt.y() == currentY))) { - //iter->first.evalAtX(x_) == (high_precision)currentY) { - //std::cout << "loop2\n"; - elementIters.push_back(iter); - counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> - (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(iter->first.pt, - iter->first.other_pt), - iter->first.count), - iter->second)); - ++iter; - } - Point currentPoint(x_, currentY); - //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << "\n"; - sort_incoming_count(counts_from_scanline, currentPoint); - - vertex_arbitrary_count incoming; - //std::cout << "aggregating\n"; - do { - //std::cout << "loop3\n"; - const vertex_half_edge& elem = *currentIter; - incoming.push_back(std::pair<Point, int>(elem.other_pt, elem.count)); - ++currentIter; - } while(currentIter != inputEnd && currentIter->pt.get(VERTICAL) == currentY && - currentIter->pt.get(HORIZONTAL) == x_); - //print(incoming); - sort_vertex_arbitrary_count(incoming, currentPoint); - //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << "\n"; - //print(incoming); - //std::cout << "incoming counts from input size " << incoming.size() << "\n"; - //compact_vertex_arbitrary_count(currentPoint, incoming); - vertex_arbitrary_count tmp; - tmp.reserve(incoming.size()); - for(std::size_t i = 0; i < incoming.size(); ++i) { - if(currentPoint < incoming[i].first) { - tmp.push_back(incoming[i]); - } - } - incoming.swap(tmp); - //std::cout << "incoming counts from input size " << incoming.size() << "\n"; - //now counts_from_scanline has the data from the left and - //incoming has the data from the right at this point - //cancel out any end points - if(verticalTail) { - //std::cout << "adding vertical tail to counts from scanline\n"; - //std::cout << -verticalCount.second << "\n"; - counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> - (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(verticalCount.first, - currentPoint), - -verticalCount.second), - verticalTail)); - } - if(!incoming.empty() && incoming.back().first.get(HORIZONTAL) == x_) { - //std::cout << "inverted vertical event\n"; - incoming.back().second *= -1; - } - //std::cout << "calling processPoint_\n"; - std::pair<std::pair<Point, int>, active_tail_arbitrary*> result = processPoint_(output, elements, Point(x_, currentY), counts_from_scanline, incoming); - verticalCount = result.first; - verticalTail = result.second; - //if(verticalTail) { - // std::cout << "have vertical tail\n"; - // std::cout << verticalCount.second << "\n"; - //} - if(verticalTail && !(verticalCount.second)) { - //we got a hole out of the point we just processed - //iter is still at the next y element above the current y value in the tree - //std::cout << "checking whether ot handle hole\n"; - if(currentIter == inputEnd || - currentIter->pt.get(HORIZONTAL) != x_ || - scanline_base<Unit>::on_above_or_below(currentIter->pt, half_edge(iter->first.pt, iter->first.other_pt)) != -1) { - //(high_precision)(currentIter->pt.get(VERTICAL)) >= iter->first.evalAtX(x_)) { - - //std::cout << "handle hole here\n"; - if(fractureHoles_) { - //std::cout << "fracture hole here\n"; - //we need to handle the hole now and not at the next input vertex - active_tail_arbitrary* at = iter->second; - high_precision precise_y = iter->first.evalAtX(x_); - Unit fracture_y = convert_high_precision_type<Unit>(precise_y); - if(precise_y < fracture_y) --fracture_y; - Point point(x_, fracture_y); - verticalTail->getOtherActiveTail()->pushPoint(point); - iter->second = verticalTail->getOtherActiveTail(); - at->pushPoint(point); - verticalTail->join(at); - delete at; - delete verticalTail; - verticalTail = 0; - } else { - //std::cout << "push hole onto list\n"; - iter->second->addHole(verticalTail); - verticalTail = 0; - } - } - } - } - //std::cout << "erasing\n"; - //erase all elements from the tree - for(typename std::vector<iterator>::iterator iter = elementIters.begin(); - iter != elementIters.end(); ++iter) { - //std::cout << "erasing loop\n"; - scanData_.erase(*iter); - } - //switch comparison tie breaking policy - justBefore_ = false; - //add new elements into tree - //std::cout << "inserting\n"; - for(typename std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> >::iterator iter = elements.begin(); - iter != elements.end(); ++iter) { - //std::cout << "inserting loop\n"; - scanData_.insert(scanData_.end(), *iter); - } - //std::cout << "end processEvent\n"; - return currentIter; - } - - inline iterator lookUp_(Unit y){ - //if just before then we need to look from 1 not -1 - //std::cout << "just before " << justBefore_ << "\n"; - return scanData_.lower_bound(vertex_half_edge(Point(x_, y), Point(x_, y+1), 0)); - } - - public: //test functions - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationRect(stream_type& stdcout) { - stdcout << "testing polygon formation\n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(10, 10), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(10, 10), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(0, 10), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationP1(stream_type& stdcout) { - stdcout << "testing polygon formation P1\n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(10, 20), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(10, 20), -1)); - data.push_back(vertex_half_edge(Point(10, 20), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(10, 20), Point(0, 10), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationP2(stream_type& stdcout) { - stdcout << "testing polygon formation P2\n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(-3, 1), Point(2, -4), 1)); - data.push_back(vertex_half_edge(Point(-3, 1), Point(-2, 2), -1)); - data.push_back(vertex_half_edge(Point(-2, 2), Point(2, 4), -1)); - data.push_back(vertex_half_edge(Point(-2, 2), Point(-3, 1), 1)); - data.push_back(vertex_half_edge(Point(2, -4), Point(-3, 1), -1)); - data.push_back(vertex_half_edge(Point(2, -4), Point(2, 4), -1)); - data.push_back(vertex_half_edge(Point(2, 4), Point(-2, 2), 1)); - data.push_back(vertex_half_edge(Point(2, 4), Point(2, -4), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationPolys(stream_type& stdcout) { - stdcout << "testing polygon formation polys\n"; - polygon_arbitrary_formation pf(false); - std::vector<polygon_with_holes_data<Unit> > polys; - polygon_arbitrary_formation pf2(true); - std::vector<polygon_with_holes_data<Unit> > polys2; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(100, 1), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(1, 100), -1)); - data.push_back(vertex_half_edge(Point(1, 100), Point(0, 0), 1)); - data.push_back(vertex_half_edge(Point(1, 100), Point(101, 101), -1)); - data.push_back(vertex_half_edge(Point(100, 1), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(100, 1), Point(101, 101), 1)); - data.push_back(vertex_half_edge(Point(101, 101), Point(100, 1), -1)); - data.push_back(vertex_half_edge(Point(101, 101), Point(1, 100), 1)); - - data.push_back(vertex_half_edge(Point(2, 2), Point(10, 2), -1)); - data.push_back(vertex_half_edge(Point(2, 2), Point(2, 10), -1)); - data.push_back(vertex_half_edge(Point(2, 10), Point(2, 2), 1)); - data.push_back(vertex_half_edge(Point(2, 10), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(10, 2), Point(2, 2), 1)); - data.push_back(vertex_half_edge(Point(10, 2), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(10, 2), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(2, 10), -1)); - - data.push_back(vertex_half_edge(Point(2, 12), Point(10, 12), -1)); - data.push_back(vertex_half_edge(Point(2, 12), Point(2, 22), -1)); - data.push_back(vertex_half_edge(Point(2, 22), Point(2, 12), 1)); - data.push_back(vertex_half_edge(Point(2, 22), Point(10, 22), 1)); - data.push_back(vertex_half_edge(Point(10, 12), Point(2, 12), 1)); - data.push_back(vertex_half_edge(Point(10, 12), Point(10, 22), 1)); - data.push_back(vertex_half_edge(Point(10, 22), Point(10, 12), -1)); - data.push_back(vertex_half_edge(Point(10, 22), Point(2, 22), -1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - pf2.scan(polys2, data.begin(), data.end()); - stdcout << "result size: " << polys2.size() << "\n"; - for(std::size_t i = 0; i < polys2.size(); ++i) { - stdcout << polys2[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationSelfTouch1(stream_type& stdcout) { - stdcout << "testing polygon formation self touch 1\n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(5, 10), -1)); - - data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1)); - - data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1)); - - data.push_back(vertex_half_edge(Point(5, 10), Point(5, 5), 1)); - data.push_back(vertex_half_edge(Point(5, 10), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(5, 2), Point(5, 5), -1)); - data.push_back(vertex_half_edge(Point(5, 2), Point(7, 2), -1)); - - data.push_back(vertex_half_edge(Point(5, 5), Point(5, 10), -1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(5, 2), 1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1)); - - data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1)); - data.push_back(vertex_half_edge(Point(7, 2), Point(5, 2), 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationSelfTouch2(stream_type& stdcout) { - stdcout << "testing polygon formation self touch 2\n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(5, 10), -1)); - - data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1)); - - data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1)); - - data.push_back(vertex_half_edge(Point(5, 10), Point(4, 1), -1)); - data.push_back(vertex_half_edge(Point(5, 10), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(4, 1), Point(5, 10), 1)); - data.push_back(vertex_half_edge(Point(4, 1), Point(7, 2), -1)); - - data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1)); - - data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1)); - data.push_back(vertex_half_edge(Point(7, 2), Point(4, 1), 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationSelfTouch3(stream_type& stdcout) { - stdcout << "testing polygon formation self touch 3\n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(6, 10), -1)); - - data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1)); - - data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1)); - - data.push_back(vertex_half_edge(Point(6, 10), Point(4, 1), -1)); - data.push_back(vertex_half_edge(Point(6, 10), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(4, 1), Point(6, 10), 1)); - data.push_back(vertex_half_edge(Point(4, 1), Point(7, 2), -1)); - - data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1)); - - data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1)); - data.push_back(vertex_half_edge(Point(7, 2), Point(4, 1), 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testPolygonArbitraryFormationColinear(stream_type& stdcout) { - stdcout << "testing polygon formation colinear 3\n"; - stdcout << "Polygon Set Data { <-3 2, -2 2>:1 <-3 2, -1 4>:-1 <-2 2, 0 2>:1 <-1 4, 0 2>:-1 } \n"; - polygon_arbitrary_formation pf(true); - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(-3, 2), Point(-2, 2), 1)); - data.push_back(vertex_half_edge(Point(-2, 2), Point(-3, 2), -1)); - - data.push_back(vertex_half_edge(Point(-3, 2), Point(-1, 4), -1)); - data.push_back(vertex_half_edge(Point(-1, 4), Point(-3, 2), 1)); - - data.push_back(vertex_half_edge(Point(-2, 2), Point(0, 2), 1)); - data.push_back(vertex_half_edge(Point(0, 2), Point(-2, 2), -1)); - - data.push_back(vertex_half_edge(Point(-1, 4), Point(0, 2), -1)); - data.push_back(vertex_half_edge(Point(0, 2), Point(-1, 4), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing polygon formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testSegmentIntersection(stream_type& stdcout) { - stdcout << "testing segment intersection\n"; - half_edge he1, he2; - he1.first = Point(0, 0); - he1.second = Point(10, 10); - he2.first = Point(0, 0); - he2.second = Point(10, 20); - Point result; - bool b = scanline_base<Unit>::compute_intersection(result, he1, he2); - if(!b || result != Point(0, 0)) return false; - he1.first = Point(0, 10); - b = scanline_base<Unit>::compute_intersection(result, he1, he2); - if(!b || result != Point(5, 10)) return false; - he1.first = Point(0, 11); - b = scanline_base<Unit>::compute_intersection(result, he1, he2); - if(!b || result != Point(5, 10)) return false; - he1.first = Point(0, 0); - he1.second = Point(1, 9); - he2.first = Point(0, 9); - he2.second = Point(1, 0); - b = scanline_base<Unit>::compute_intersection(result, he1, he2); - if(!b || result != Point(0, 4)) return false; - - he1.first = Point(0, -10); - he1.second = Point(1, -1); - he2.first = Point(0, -1); - he2.second = Point(1, -10); - b = scanline_base<Unit>::compute_intersection(result, he1, he2); - if(!b || result != Point(0, -5)) return false; - he1.first = Point((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::max)()-1); - he1.second = Point((std::numeric_limits<int>::min)(), (std::numeric_limits<int>::max)()); - //he1.second = Point(0, (std::numeric_limits<int>::max)()); - he2.first = Point((std::numeric_limits<int>::max)()-1, (std::numeric_limits<int>::max)()); - he2.second = Point((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::min)()); - //he2.second = Point((std::numeric_limits<int>::max)(), 0); - b = scanline_base<Unit>::compute_intersection(result, he1, he2); - //b is false because of overflow error - he1.first = Point(1000, 2000); - he1.second = Point(1010, 2010); - he2.first = Point(1000, 2000); - he2.second = Point(1010, 2020); - b = scanline_base<Unit>::compute_intersection(result, he1, he2); - if(!b || result != Point(1000, 2000)) return false; - - return b; - } - - }; - - template <typename Unit> - class poly_line_arbitrary_hole_data { - private: - typedef typename polygon_arbitrary_formation<Unit>::active_tail_arbitrary active_tail_arbitrary; - active_tail_arbitrary* p_; - public: - typedef point_data<Unit> Point; - typedef Point point_type; - typedef Unit coordinate_type; - typedef typename active_tail_arbitrary::iterator iterator_type; - //typedef iterator_points_to_compact<iterator_type, Point> compact_iterator_type; - - typedef iterator_type iterator; - inline poly_line_arbitrary_hole_data() : p_(0) {} - inline poly_line_arbitrary_hole_data(active_tail_arbitrary* p) : p_(p) {} - //use default copy and assign - inline iterator begin() const { return p_->getTail()->begin(); } - inline iterator end() const { return p_->getTail()->end(); } - inline std::size_t size() const { return 0; } - }; - - template <typename Unit> - class poly_line_arbitrary_polygon_data { - private: - typedef typename polygon_arbitrary_formation<Unit>::active_tail_arbitrary active_tail_arbitrary; - active_tail_arbitrary* p_; - public: - typedef point_data<Unit> Point; - typedef Point point_type; - typedef Unit coordinate_type; - typedef typename active_tail_arbitrary::iterator iterator_type; - //typedef iterator_points_to_compact<iterator_type, Point> compact_iterator_type; - typedef typename coordinate_traits<Unit>::coordinate_distance area_type; - - class iterator_holes_type { - private: - typedef poly_line_arbitrary_hole_data<Unit> holeType; - mutable holeType hole_; - typename active_tail_arbitrary::iteratorHoles itr_; - - public: - typedef std::forward_iterator_tag iterator_category; - typedef holeType value_type; - typedef std::ptrdiff_t difference_type; - typedef const holeType* pointer; //immutable - typedef const holeType& reference; //immutable - inline iterator_holes_type() : hole_(), itr_() {} - inline iterator_holes_type(typename active_tail_arbitrary::iteratorHoles itr) : hole_(), itr_(itr) {} - inline iterator_holes_type(const iterator_holes_type& that) : hole_(that.hole_), itr_(that.itr_) {} - inline iterator_holes_type& operator=(const iterator_holes_type& that) { - itr_ = that.itr_; - return *this; - } - inline bool operator==(const iterator_holes_type& that) { return itr_ == that.itr_; } - inline bool operator!=(const iterator_holes_type& that) { return itr_ != that.itr_; } - inline iterator_holes_type& operator++() { - ++itr_; - return *this; - } - inline const iterator_holes_type operator++(int) { - iterator_holes_type tmp = *this; - ++(*this); - return tmp; - } - inline reference operator*() { - hole_ = holeType(*itr_); - return hole_; - } - }; - - typedef poly_line_arbitrary_hole_data<Unit> hole_type; - - inline poly_line_arbitrary_polygon_data() : p_(0) {} - inline poly_line_arbitrary_polygon_data(active_tail_arbitrary* p) : p_(p) {} - //use default copy and assign - inline iterator_type begin() const { return p_->getTail()->begin(); } - inline iterator_type end() const { return p_->getTail()->end(); } - //inline compact_iterator_type begin_compact() const { return p_->getTail()->begin(); } - //inline compact_iterator_type end_compact() const { return p_->getTail()->end(); } - inline iterator_holes_type begin_holes() const { return iterator_holes_type(p_->getHoles().begin()); } - inline iterator_holes_type end_holes() const { return iterator_holes_type(p_->getHoles().end()); } - inline active_tail_arbitrary* yield() { return p_; } - //stub out these four required functions that will not be used but are needed for the interface - inline std::size_t size_holes() const { return 0; } - inline std::size_t size() const { return 0; } - }; - - template <typename Unit> - class trapezoid_arbitrary_formation : public polygon_arbitrary_formation<Unit> { - private: - typedef typename scanline_base<Unit>::Point Point; - typedef typename scanline_base<Unit>::half_edge half_edge; - typedef typename scanline_base<Unit>::vertex_half_edge vertex_half_edge; - typedef typename scanline_base<Unit>::less_vertex_half_edge less_vertex_half_edge; - - typedef typename polygon_arbitrary_formation<Unit>::poly_line_arbitrary poly_line_arbitrary; - - typedef typename polygon_arbitrary_formation<Unit>::active_tail_arbitrary active_tail_arbitrary; - - typedef std::vector<std::pair<Point, int> > vertex_arbitrary_count; - - typedef typename polygon_arbitrary_formation<Unit>::less_half_edge_count less_half_edge_count; - - typedef std::vector<std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> > incoming_count; - - typedef typename polygon_arbitrary_formation<Unit>::less_incoming_count less_incoming_count; - - typedef typename polygon_arbitrary_formation<Unit>::vertex_arbitrary_compact vertex_arbitrary_compact; - - private: - //definitions - typedef std::map<vertex_half_edge, active_tail_arbitrary*, less_vertex_half_edge> scanline_data; - typedef typename scanline_data::iterator iterator; - typedef typename scanline_data::const_iterator const_iterator; - - //data - public: - inline trapezoid_arbitrary_formation() : polygon_arbitrary_formation<Unit>() {} - inline trapezoid_arbitrary_formation(const trapezoid_arbitrary_formation& that) : polygon_arbitrary_formation<Unit>(that) {} - inline trapezoid_arbitrary_formation& operator=(const trapezoid_arbitrary_formation& that) { - * static_cast<polygon_arbitrary_formation<Unit>*>(this) = * static_cast<polygon_arbitrary_formation<Unit>*>(&that); - return *this; - } - - //cT is an output container of Polygon45 or Polygon45WithHoles - //iT is an iterator over vertex_half_edge elements - //inputBegin - inputEnd is a range of sorted iT that represents - //one or more scanline stops worth of data - template <class cT, class iT> - void scan(cT& output, iT inputBegin, iT inputEnd) { - //std::cout << "1\n"; - while(inputBegin != inputEnd) { - //std::cout << "2\n"; - polygon_arbitrary_formation<Unit>::x_ = (*inputBegin).pt.get(HORIZONTAL); - //std::cout << "SCAN FORMATION " << x_ << "\n"; - //std::cout << "x_ = " << x_ << "\n"; - //std::cout << "scan line size: " << scanData_.size() << "\n"; - inputBegin = processEvent_(output, inputBegin, inputEnd); - } - //std::cout << "scan line size: " << scanData_.size() << "\n"; - } - - private: - //functions - inline void getVerticalPair_(std::pair<active_tail_arbitrary*, - active_tail_arbitrary*>& verticalPair, - iterator previter) { - active_tail_arbitrary* iterTail = (*previter).second; - Point prevPoint(polygon_arbitrary_formation<Unit>::x_, - convert_high_precision_type<Unit>(previter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_))); - iterTail->pushPoint(prevPoint); - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = - active_tail_arbitrary::createActiveTailsAsPair(prevPoint, true, 0, false); - verticalPair.first = iterTail; - verticalPair.second = tailPair.first; - (*previter).second = tailPair.second; - } - - template <class cT, class cT2> - inline std::pair<std::pair<Point, int>, active_tail_arbitrary*> - processPoint_(cT& output, cT2& elements, - std::pair<active_tail_arbitrary*, active_tail_arbitrary*>& verticalPair, - iterator previter, Point point, incoming_count& counts_from_scanline, - vertex_arbitrary_count& incoming_count) { - //std::cout << "\nAT POINT: " << point << "\n"; - //join any closing solid corners - std::vector<int> counts; - std::vector<int> incoming; - std::vector<active_tail_arbitrary*> tails; - counts.reserve(counts_from_scanline.size()); - tails.reserve(counts_from_scanline.size()); - incoming.reserve(incoming_count.size()); - for(std::size_t i = 0; i < counts_from_scanline.size(); ++i) { - counts.push_back(counts_from_scanline[i].first.second); - tails.push_back(counts_from_scanline[i].second); - } - for(std::size_t i = 0; i < incoming_count.size(); ++i) { - incoming.push_back(incoming_count[i].second); - if(incoming_count[i].first < point) { - incoming.back() = 0; - } - } - - active_tail_arbitrary* returnValue = 0; - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> verticalPairOut; - verticalPairOut.first = 0; - verticalPairOut.second = 0; - std::pair<Point, int> returnCount(Point(0, 0), 0); - int i_size_less_1 = (int)(incoming.size()) -1; - int c_size_less_1 = (int)(counts.size()) -1; - int i_size = incoming.size(); - int c_size = counts.size(); - - bool have_vertical_tail_from_below = false; - if(c_size && - scanline_base<Unit>::is_vertical(counts_from_scanline.back().first.first)) { - have_vertical_tail_from_below = true; - } - //assert size = size_less_1 + 1 - //std::cout << tails.size() << " " << incoming.size() << " " << counts_from_scanline.size() << " " << incoming_count.size() << "\n"; - // for(std::size_t i = 0; i < counts.size(); ++i) { - // std::cout << counts_from_scanline[i].first.first.first.get(HORIZONTAL) << ","; - // std::cout << counts_from_scanline[i].first.first.first.get(VERTICAL) << " "; - // std::cout << counts_from_scanline[i].first.first.second.get(HORIZONTAL) << ","; - // std::cout << counts_from_scanline[i].first.first.second.get(VERTICAL) << ":"; - // std::cout << counts_from_scanline[i].first.second << " "; - // } std::cout << "\n"; - // print(incoming_count); - { - for(int i = 0; i < c_size_less_1; ++i) { - //std::cout << i << "\n"; - if(counts[i] == -1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < c_size; ++j) { - //std::cout << j << "\n"; - if(counts[j]) { - if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << "\n"; - //if a figure is closed it will be written out by this function to output - active_tail_arbitrary::joinChains(point, tails[i], tails[j], true, output); - counts[i] = 0; - counts[j] = 0; - tails[i] = 0; - tails[j] = 0; - } - break; - } - } - } - } - } - //find any pairs of incoming edges that need to create pair for leading solid - //std::cout << "checking case2\n"; - { - for(int i = 0; i < i_size_less_1; ++i) { - //std::cout << i << "\n"; - if(incoming[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = i + 1; j < i_size; ++j) { - //std::cout << j << "\n"; - if(incoming[j]) { - //std::cout << incoming[j] << "\n"; - if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << "\n"; - //std::cout << "creating active tail pair\n"; - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = - active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, polygon_arbitrary_formation<Unit>::fractureHoles_ != 0); - //tailPair.first->print(); - //tailPair.second->print(); - if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - //vertical active tail becomes return value - returnValue = tailPair.first; - returnCount.first = point; - returnCount.second = 1; - } else { - //std::cout << "new element " << j-1 << " " << -1 << "\n"; - //std::cout << point << " " << incoming_count[j].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, -1), tailPair.first)); - } - //std::cout << "new element " << i-1 << " " << 1 << "\n"; - //std::cout << point << " " << incoming_count[i].first << "\n"; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[i].first, 1), tailPair.second)); - incoming[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - } - } - //find any active tail that needs to pass through to an incoming edge - //we expect to find no more than two pass through - - //find pass through with solid on top - { - //std::cout << "checking case 3\n"; - for(int i = 0; i < c_size; ++i) { - //std::cout << i << "\n"; - if(counts[i] != 0) { - if(counts[i] == 1) { - //std::cout << "fixed i\n"; - for(int j = i_size_less_1; j >= 0; --j) { - if(incoming[j] != 0) { - if(incoming[j] == 1) { - //std::cout << "case3: " << i << " " << j << "\n"; - //tails[i]->print(); - //pass through solid on top - tails[i]->pushPoint(point); - //std::cout << "after push\n"; - if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - returnValue = tails[i]; - returnCount.first = point; - returnCount.second = -1; - } else { - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = - active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, false); - verticalPairOut.first = tails[i]; - verticalPairOut.second = tailPair.first; - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), tailPair.second)); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - } - //std::cout << "checking case 4\n"; - //find pass through with solid on bottom - { - for(int i = c_size_less_1; i >= 0; --i) { - //std::cout << "i = " << i << " with count " << counts[i] << "\n"; - if(counts[i] != 0) { - if(counts[i] == -1) { - for(int j = 0; j < i_size; ++j) { - if(incoming[j] != 0) { - if(incoming[j] == -1) { - //std::cout << "case4: " << i << " " << j << "\n"; - //pass through solid on bottom - - //if count from scanline is vertical - if(i == c_size_less_1 && - counts_from_scanline[i].first.first.first.get(HORIZONTAL) == - point.get(HORIZONTAL)) { - //if incoming count is vertical - if(j == i_size_less_1 && - incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - returnValue = tails[i]; - returnCount.first = point; - returnCount.second = 1; - } else { - tails[i]->pushPoint(point); - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), tails[i])); - } - } else if(j == i_size_less_1 && - incoming_count[j].first.get(HORIZONTAL) == - point.get(HORIZONTAL)) { - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - active_tail_arbitrary::joinChains(point, tails[i], verticalPair.first, true, output); - returnValue = verticalPair.second; - returnCount.first = point; - returnCount.second = 1; - } else { - //neither is vertical - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - active_tail_arbitrary::joinChains(point, tails[i], verticalPair.first, true, output); - verticalPair.second->pushPoint(point); - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), verticalPair.second)); - } - tails[i] = 0; - counts[i] = 0; - incoming[j] = 0; - } - break; - } - } - } - break; - } - } - } - //find the end of a hole or the beginning of a hole - - //find end of a hole - { - for(int i = 0; i < c_size_less_1; ++i) { - if(counts[i] != 0) { - for(int j = i+1; j < c_size; ++j) { - if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << "\n"; - //we are ending a hole and may potentially close a figure and have to handle the hole - tails[i]->pushPoint(point); - verticalPairOut.first = tails[i]; - if(j == c_size_less_1 && - counts_from_scanline[j].first.first.first.get(HORIZONTAL) == - point.get(HORIZONTAL)) { - verticalPairOut.second = tails[j]; - } else { - //need to close a trapezoid below - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - active_tail_arbitrary::joinChains(point, tails[j], verticalPair.first, true, output); - verticalPairOut.second = verticalPair.second; - } - tails[i] = 0; - tails[j] = 0; - counts[i] = 0; - counts[j] = 0; - break; - } - } - break; - } - } - } - //find beginning of a hole - { - for(int i = 0; i < i_size_less_1; ++i) { - if(incoming[i] != 0) { - for(int j = i+1; j < i_size; ++j) { - if(incoming[j] != 0) { - //std::cout << "case6: " << i << " " << j << "\n"; - //we are beginning a empty space - if(verticalPair.first == 0) { - getVerticalPair_(verticalPair, previter); - } - verticalPair.second->pushPoint(point); - if(j == i_size_less_1 && - incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { - returnValue = verticalPair.first; - returnCount.first = point; - returnCount.second = -1; - } else { - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = - active_tail_arbitrary::createActiveTailsAsPair(point, false, 0, false); - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[j].first, incoming[j]), tailPair.second)); - verticalPairOut.second = tailPair.first; - verticalPairOut.first = verticalPair.first; - } - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, - incoming_count[i].first, incoming[i]), verticalPair.second)); - incoming[i] = 0; - incoming[j] = 0; - break; - } - } - break; - } - } - } - if(have_vertical_tail_from_below) { - if(tails.back()) { - tails.back()->pushPoint(point); - returnValue = tails.back(); - returnCount.first = point; - returnCount.second = counts.back(); - } - } - verticalPair = verticalPairOut; - //assert that tails, counts and incoming are all null - return std::pair<std::pair<Point, int>, active_tail_arbitrary*>(returnCount, returnValue); - } - - static inline void print(const vertex_arbitrary_count& count) { - for(unsigned i = 0; i < count.size(); ++i) { - //std::cout << count[i].first.get(HORIZONTAL) << ","; - //std::cout << count[i].first.get(VERTICAL) << ":"; - //std::cout << count[i].second << " "; - } //std::cout << "\n"; - } - - static inline void print(const scanline_data& data) { - for(typename scanline_data::const_iterator itr = data.begin(); itr != data.end(); ++itr){ - //std::cout << itr->first.pt << ", " << itr->first.other_pt << "; "; - } //std::cout << "\n"; - } - - template <class cT, class iT> - inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) { - //typedef typename high_precision_type<Unit>::type high_precision; - //std::cout << "processEvent_\n"; - polygon_arbitrary_formation<Unit>::justBefore_ = true; - //collect up all elements from the tree that are at the y - //values of events in the input queue - //create vector of new elements to add into tree - active_tail_arbitrary* verticalTail = 0; - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> verticalPair; - std::pair<Point, int> verticalCount(Point(0, 0), 0); - iT currentIter = inputBegin; - std::vector<iterator> elementIters; - std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> > elements; - while(currentIter != inputEnd && currentIter->pt.get(HORIZONTAL) == polygon_arbitrary_formation<Unit>::x_) { - //std::cout << "loop\n"; - Unit currentY = (*currentIter).pt.get(VERTICAL); - //std::cout << "current Y " << currentY << "\n"; - //std::cout << "scanline size " << scanData_.size() << "\n"; - //print(scanData_); - iterator iter = this->lookUp_(currentY); - //std::cout << "found element in scanline " << (iter != scanData_.end()) << "\n"; - //int counts[4] = {0, 0, 0, 0}; - incoming_count counts_from_scanline; - //std::cout << "finding elements in tree\n"; - //if(iter != scanData_.end()) - // std::cout << "first iter y is " << iter->first.evalAtX(x_) << "\n"; - iterator previter = iter; - if(previter != polygon_arbitrary_formation<Unit>::scanData_.end() && - previter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_) >= currentY && - previter != polygon_arbitrary_formation<Unit>::scanData_.begin()) - --previter; - while(iter != polygon_arbitrary_formation<Unit>::scanData_.end() && - ((iter->first.pt.x() == polygon_arbitrary_formation<Unit>::x_ && iter->first.pt.y() == currentY) || - (iter->first.other_pt.x() == polygon_arbitrary_formation<Unit>::x_ && iter->first.other_pt.y() == currentY))) { - //iter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_) == (high_precision)currentY) { - //std::cout << "loop2\n"; - elementIters.push_back(iter); - counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> - (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(iter->first.pt, - iter->first.other_pt), - iter->first.count), - iter->second)); - ++iter; - } - Point currentPoint(polygon_arbitrary_formation<Unit>::x_, currentY); - //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << "\n"; - this->sort_incoming_count(counts_from_scanline, currentPoint); - - vertex_arbitrary_count incoming; - //std::cout << "aggregating\n"; - do { - //std::cout << "loop3\n"; - const vertex_half_edge& elem = *currentIter; - incoming.push_back(std::pair<Point, int>(elem.other_pt, elem.count)); - ++currentIter; - } while(currentIter != inputEnd && currentIter->pt.get(VERTICAL) == currentY && - currentIter->pt.get(HORIZONTAL) == polygon_arbitrary_formation<Unit>::x_); - //print(incoming); - this->sort_vertex_arbitrary_count(incoming, currentPoint); - //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << "\n"; - //print(incoming); - //std::cout << "incoming counts from input size " << incoming.size() << "\n"; - //compact_vertex_arbitrary_count(currentPoint, incoming); - vertex_arbitrary_count tmp; - tmp.reserve(incoming.size()); - for(std::size_t i = 0; i < incoming.size(); ++i) { - if(currentPoint < incoming[i].first) { - tmp.push_back(incoming[i]); - } - } - incoming.swap(tmp); - //std::cout << "incoming counts from input size " << incoming.size() << "\n"; - //now counts_from_scanline has the data from the left and - //incoming has the data from the right at this point - //cancel out any end points - if(verticalTail) { - //std::cout << "adding vertical tail to counts from scanline\n"; - //std::cout << -verticalCount.second << "\n"; - counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> - (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(verticalCount.first, - currentPoint), - -verticalCount.second), - verticalTail)); - } - if(!incoming.empty() && incoming.back().first.get(HORIZONTAL) == polygon_arbitrary_formation<Unit>::x_) { - //std::cout << "inverted vertical event\n"; - incoming.back().second *= -1; - } - //std::cout << "calling processPoint_\n"; - std::pair<std::pair<Point, int>, active_tail_arbitrary*> result = processPoint_(output, elements, verticalPair, previter, Point(polygon_arbitrary_formation<Unit>::x_, currentY), counts_from_scanline, incoming); - verticalCount = result.first; - verticalTail = result.second; - if(verticalPair.first != 0 && iter != polygon_arbitrary_formation<Unit>::scanData_.end() && - (currentIter == inputEnd || currentIter->pt.x() != polygon_arbitrary_formation<Unit>::x_ || - currentIter->pt.y() > (*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_))) { - //splice vertical pair into edge above - active_tail_arbitrary* tailabove = (*iter).second; - Point point(polygon_arbitrary_formation<Unit>::x_, - convert_high_precision_type<Unit>((*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_))); - verticalPair.second->pushPoint(point); - active_tail_arbitrary::joinChains(point, tailabove, verticalPair.first, true, output); - (*iter).second = verticalPair.second; - verticalPair.first = 0; - verticalPair.second = 0; - } - } - //std::cout << "erasing\n"; - //erase all elements from the tree - for(typename std::vector<iterator>::iterator iter = elementIters.begin(); - iter != elementIters.end(); ++iter) { - //std::cout << "erasing loop\n"; - polygon_arbitrary_formation<Unit>::scanData_.erase(*iter); - } - //switch comparison tie breaking policy - polygon_arbitrary_formation<Unit>::justBefore_ = false; - //add new elements into tree - //std::cout << "inserting\n"; - for(typename std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> >::iterator iter = elements.begin(); - iter != elements.end(); ++iter) { - //std::cout << "inserting loop\n"; - polygon_arbitrary_formation<Unit>::scanData_.insert(polygon_arbitrary_formation<Unit>::scanData_.end(), *iter); - } - //std::cout << "end processEvent\n"; - return currentIter; - } - public: - template <typename stream_type> - static inline bool testTrapezoidArbitraryFormationRect(stream_type& stdcout) { - stdcout << "testing trapezoid formation\n"; - trapezoid_arbitrary_formation pf; - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(10, 10), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(10, 10), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(0, 10), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing trapezoid formation\n"; - return true; - } - template <typename stream_type> - static inline bool testTrapezoidArbitraryFormationP1(stream_type& stdcout) { - stdcout << "testing trapezoid formation P1\n"; - trapezoid_arbitrary_formation pf; - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(10, 20), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(10, 20), -1)); - data.push_back(vertex_half_edge(Point(10, 20), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(10, 20), Point(0, 10), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing trapezoid formation\n"; - return true; - } - template <typename stream_type> - static inline bool testTrapezoidArbitraryFormationP2(stream_type& stdcout) { - stdcout << "testing trapezoid formation P2\n"; - trapezoid_arbitrary_formation pf; - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(-3, 1), Point(2, -4), 1)); - data.push_back(vertex_half_edge(Point(-3, 1), Point(-2, 2), -1)); - data.push_back(vertex_half_edge(Point(-2, 2), Point(2, 4), -1)); - data.push_back(vertex_half_edge(Point(-2, 2), Point(-3, 1), 1)); - data.push_back(vertex_half_edge(Point(2, -4), Point(-3, 1), -1)); - data.push_back(vertex_half_edge(Point(2, -4), Point(2, 4), -1)); - data.push_back(vertex_half_edge(Point(2, 4), Point(-2, 2), 1)); - data.push_back(vertex_half_edge(Point(2, 4), Point(2, -4), 1)); - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing trapezoid formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testTrapezoidArbitraryFormationPolys(stream_type& stdcout) { - stdcout << "testing trapezoid formation polys\n"; - trapezoid_arbitrary_formation pf; - std::vector<polygon_with_holes_data<Unit> > polys; - //trapezoid_arbitrary_formation pf2(true); - //std::vector<polygon_with_holes_data<Unit> > polys2; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(100, 1), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(1, 100), -1)); - data.push_back(vertex_half_edge(Point(1, 100), Point(0, 0), 1)); - data.push_back(vertex_half_edge(Point(1, 100), Point(101, 101), -1)); - data.push_back(vertex_half_edge(Point(100, 1), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(100, 1), Point(101, 101), 1)); - data.push_back(vertex_half_edge(Point(101, 101), Point(100, 1), -1)); - data.push_back(vertex_half_edge(Point(101, 101), Point(1, 100), 1)); - - data.push_back(vertex_half_edge(Point(2, 2), Point(10, 2), -1)); - data.push_back(vertex_half_edge(Point(2, 2), Point(2, 10), -1)); - data.push_back(vertex_half_edge(Point(2, 10), Point(2, 2), 1)); - data.push_back(vertex_half_edge(Point(2, 10), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(10, 2), Point(2, 2), 1)); - data.push_back(vertex_half_edge(Point(10, 2), Point(10, 10), 1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(10, 2), -1)); - data.push_back(vertex_half_edge(Point(10, 10), Point(2, 10), -1)); - - data.push_back(vertex_half_edge(Point(2, 12), Point(10, 12), -1)); - data.push_back(vertex_half_edge(Point(2, 12), Point(2, 22), -1)); - data.push_back(vertex_half_edge(Point(2, 22), Point(2, 12), 1)); - data.push_back(vertex_half_edge(Point(2, 22), Point(10, 22), 1)); - data.push_back(vertex_half_edge(Point(10, 12), Point(2, 12), 1)); - data.push_back(vertex_half_edge(Point(10, 12), Point(10, 22), 1)); - data.push_back(vertex_half_edge(Point(10, 22), Point(10, 12), -1)); - data.push_back(vertex_half_edge(Point(10, 22), Point(2, 22), -1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - //pf2.scan(polys2, data.begin(), data.end()); - //stdcout << "result size: " << polys2.size() << "\n"; - //for(std::size_t i = 0; i < polys2.size(); ++i) { - // stdcout << polys2[i] << "\n"; - //} - stdcout << "done testing trapezoid formation\n"; - return true; - } - - template <typename stream_type> - static inline bool testTrapezoidArbitraryFormationSelfTouch1(stream_type& stdcout) { - stdcout << "testing trapezoid formation self touch 1\n"; - trapezoid_arbitrary_formation pf; - std::vector<polygon_data<Unit> > polys; - std::vector<vertex_half_edge> data; - data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(0, 10), Point(5, 10), -1)); - - data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1)); - data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1)); - - data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1)); - data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1)); - - data.push_back(vertex_half_edge(Point(5, 10), Point(5, 5), 1)); - data.push_back(vertex_half_edge(Point(5, 10), Point(0, 10), 1)); - - data.push_back(vertex_half_edge(Point(5, 2), Point(5, 5), -1)); - data.push_back(vertex_half_edge(Point(5, 2), Point(7, 2), -1)); - - data.push_back(vertex_half_edge(Point(5, 5), Point(5, 10), -1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(5, 2), 1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1)); - data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1)); - - data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1)); - data.push_back(vertex_half_edge(Point(7, 2), Point(5, 2), 1)); - - polygon_sort(data.begin(), data.end()); - pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << "\n"; - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - stdcout << "done testing trapezoid formation\n"; - return true; - } - }; - - template <typename T> - struct PolyLineArbitraryByConcept<T, polygon_with_holes_concept> { typedef poly_line_arbitrary_polygon_data<T> type; }; - template <typename T> - struct PolyLineArbitraryByConcept<T, polygon_concept> { typedef poly_line_arbitrary_hole_data<T> type; }; - - template <typename T> - struct geometry_concept<poly_line_arbitrary_polygon_data<T> > { typedef polygon_45_with_holes_concept type; }; - template <typename T> - struct geometry_concept<poly_line_arbitrary_hole_data<T> > { typedef polygon_45_concept type; }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_formation.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_formation.hpp deleted file mode 100644 index f4c0d70d9c..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_formation.hpp +++ /dev/null @@ -1,2287 +0,0 @@ -/* - 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). -*/ -#include<iostream> -#include<cassert> -#ifndef BOOST_POLYGON_POLYGON_FORMATION_HPP -#define BOOST_POLYGON_POLYGON_FORMATION_HPP -namespace boost { namespace polygon{ - -namespace polygon_formation { - - /* - * End has two states, HEAD and TAIL as is represented by a bool - */ - typedef bool End; - - /* - * HEAD End is represented as false because it is the lesser state - */ - const End HEAD = false; - - /* - * TAIL End is represented by true because TAIL comes after head and 1 after 0 - */ - const End TAIL = true; - - /* - * 2D turning direction, left and right sides (is a boolean value since it has two states.) - */ - typedef bool Side; - - /* - * LEFT Side is 0 because we inuitively think left to right; left < right - */ - const Side LEFT = false; - - /* - * RIGHT Side is 1 so that right > left - */ - const Side RIGHT = true; - - /* - * The PolyLine class is data storage and services for building and representing partial polygons. - * As the polyline is added to it extends its storage to accomodate the data. - * PolyLines can be joined head-to-head/head-to-tail when it is determined that two polylines are - * part of the same polygon. - * PolyLines keep state information about what orientation their incomplete head and tail geometry have, - * which side of the polyline is solid and whether the polyline is joined head-to-head and tail-to-head. - * PolyLines have nothing whatsoever to do with holes. - * It may be valuable to collect a histogram of PolyLine lengths used by an algorithm on its typical data - * sets and tune the allocation of the initial vector of coordinate data to be greater than or equal to - * the mean, median, mode, or mean plus some number of standard deviation, or just generally large enough - * to prevent too much unnecesary reallocations, but not too big that it wastes a lot of memory and degrades cache - * performance. - */ - template <typename Unit> - class PolyLine { - private: - //data - - /* - * ptdata_ a vector of coordiantes - * if VERTICAL_HEAD, first coordiante is an X - * else first coordinate is a Y - */ - std::vector<Unit> ptdata_; - - /* - * head and tail points to other polylines before and after this in a chain - */ - PolyLine* headp_; - PolyLine* tailp_; - - /* - * state bitmask - * bit zero is orientation, 0 H, 1 V - * bit 1 is head connectivity, 0 for head, 1 for tail - * bit 2 is tail connectivity, 0 for head, 1 for tail - * bit 3 is solid to left of PolyLine when 1, right when 0 - */ - int state_; - - public: - /* - * default constructor (for preallocation) - */ - PolyLine(); - - /* - * constructor that takes the orientation, coordiante and side to which there is solid - */ - PolyLine(orientation_2d orient, Unit coord, Side side); - - //copy constructor - PolyLine(const PolyLine& pline); - - //destructor - ~PolyLine(); - - //assignment operator - PolyLine& operator=(const PolyLine& that); - - //equivalence operator - bool operator==(const PolyLine& b) const; - - /* - * valid PolyLine (only default constructed polylines are invalid.) - */ - bool isValid() const; - - /* - * Orientation of Head - */ - orientation_2d headOrient() const; - - /* - * returns true if first coordinate is an X value (first segment is vertical) - */ - bool verticalHead() const; - - /* - * returns the orientation_2d fo the tail - */ - orientation_2d tailOrient() const; - - /* - * returns true if last coordinate is an X value (last segment is vertical) - */ - bool verticalTail() const; - - /* - * retrun true if PolyLine has odd number of coordiantes - */ - bool oddLength() const; - - /* - * retrun the End of the other polyline that the specified end of this polyline is connected to - */ - End endConnectivity(End end) const; - - /* - * retrun true if the head of this polyline is connect to the tail of a polyline - */ - bool headToTail() const; - /* - * retrun true if the head of this polyline is connect to the head of a polyline - */ - bool headToHead() const; - - /* - * retrun true if the tail of this polyline is connect to the tail of a polyline - */ - bool tailToTail() const; - /* - * retrun true if the tail of this polyline is connect to the head of a polyline - */ - bool tailToHead() const; - - /* - * retrun the side on which there is solid for this polyline - */ - Side solidSide() const; - - /* - * retrun true if there is solid to the right of this polyline - */ - bool solidToRight() const; - - /* - * returns true if the polyline tail is not connected - */ - bool active() const; - - /* - * adds a coordinate value to the end of the polyline changing the tail orientation - */ - PolyLine& pushCoordinate(Unit coord); - - /* - * removes a coordinate value at the end of the polyline changing the tail orientation - */ - PolyLine& popCoordinate(); - - /* - * extends the tail of the polyline to include the point, changing orientation if needed - */ - PolyLine& pushPoint(const point_data<Unit>& point); - - /* - * changes the last coordinate of the tail of the polyline by the amount of the delta - */ - PolyLine& extendTail(Unit delta); - - /* - * join thisEnd of this polyline to that polyline's end - */ - PolyLine& joinTo(End thisEnd, PolyLine& that, End end); - - /* - * join an end of this polyline to the tail of that polyline - */ - PolyLine& joinToTail(PolyLine& that, End end); - - /* - * join an end of this polyline to the head of that polyline - */ - PolyLine& joinToHead(PolyLine& that, End end); - - /* - * join the head of this polyline to the head of that polyline - */ - //join this to that in the given way - PolyLine& joinHeadToHead(PolyLine& that); - - /* - * join the head of this polyline to the tail of that polyline - */ - PolyLine& joinHeadToTail(PolyLine& that); - - /* - * join the tail of this polyline to the head of that polyline - */ - PolyLine& joinTailToHead(PolyLine& that); - - /* - * join the tail of this polyline to the tail of that polyline - */ - PolyLine& joinTailToTail(PolyLine& that); - - /* - * dissconnect the tail at the end of the polygon - */ - PolyLine& disconnectTails(); - - /* - * get the coordinate at one end of this polyline, by default the tail end - */ - Unit getEndCoord(End end = TAIL) const; - - /* - * get the point on the polyline at the given index (polylines have the same number of coordinates as points - */ - point_data<Unit> getPoint(unsigned int index) const; - - /* - * get the point on one end of the polyline, by default the tail - */ - point_data<Unit> getEndPoint(End end = TAIL) const; - - /* - * get the orientation of a segment by index - */ - orientation_2d segmentOrient(unsigned int index = 0) const; - - /* - * get a coordinate by index using the square bracket operator - */ - Unit operator[] (unsigned int index) const; - - /* - * get the number of segments/points/coordinates in the polyline - */ - unsigned int numSegments() const; - - /* - * get the pointer to the next polyline at one end of this - */ - PolyLine* next(End end) const; - - /* - * write out coordinates of this and all attached polylines to a single vector - */ - PolyLine* writeOut(std::vector<Unit>& outVec, End startEnd = TAIL) const; - - private: - //methods - PolyLine& joinTo_(End thisEnd, PolyLine& that, End end); - }; - - //forward declaration - template<bool orientT, typename Unit> - class PolyLinePolygonData; - - //forward declaration - template<bool orientT, typename Unit> - class PolyLinePolygonWithHolesData; - - /* - * ActiveTail represents an edge of an incomplete polygon. - * - * An ActiveTail object is the active tail end of a polyline object, which may (should) be the attached to - * a chain of polyline objects through a pointer. The ActiveTail class provides an abstraction between - * and algorithm that builds polygons and the PolyLine data representation of incomplete polygons that are - * being built. It does this by providing an iterface to access the information about the last edge at the - * tail of the PolyLine it is associated with. To a polygon constructing algorithm, an ActiveTail is a floating - * edge of an incomplete polygon and has an orientation and coordinate value, as well as knowing which side of - * that edge is supposed to be solid or space. Any incomplete polygon will have two active tails. Active tails - * may be joined together to merge two incomplete polygons into a larger incomplete polygon. If two active tails - * that are to be merged are the oppositve ends of the same incomplete polygon that indicates that the polygon - * has been closed and is complete. The active tail keeps a pointer to the other active tail of its incomplete - * polygon so that it is easy to check this condition. These pointers are updated when active tails are joined. - * The active tail also keeps a list of pointers to active tail objects that serve as handles to closed holes. In - * this way a hole can be associated to another incomplete polygon, which will eventually be its enclosing shell, - * or reassociate the hole to another incomplete polygon in the case that it become a hole itself. Alternately, - * the active tail may add a filiment to stitch a hole into a shell and "fracture" the hole out of the interior - * of a polygon. The active tail maintains a static output buffer to temporarily write polygon data to when - * it outputs a figure so that outputting a polygon does not require the allocation of a temporary buffer. This - * static buffer should be destroyed whenever the program determines that it won't need it anymore and would prefer to - * release the memory it has allocated back to the system. - */ - template <typename Unit> - class ActiveTail { - private: - //data - PolyLine<Unit>* tailp_; - ActiveTail *otherTailp_; - std::list<ActiveTail*> holesList_; - //Sum of all the polylines which constitute the active tail (including holes)// - size_t polyLineSize_; - public: - - inline size_t getPolyLineSize(){ - return polyLineSize_; - } - - inline void setPolyLineSize(int delta){ - polyLineSize_ = delta; - } - - inline void addPolyLineSize(int delta){ - polyLineSize_ += delta; - } - - /* - * iterator over coordinates of the figure - */ - class iterator { - private: - const PolyLine<Unit>* pLine_; - const PolyLine<Unit>* pLineEnd_; - unsigned int index_; - unsigned int indexEnd_; - End startEnd_; - public: - inline iterator() : pLine_(), pLineEnd_(), index_(), indexEnd_(), startEnd_() {} - inline iterator(const ActiveTail* at, bool isHole, orientation_2d orient) : - pLine_(), pLineEnd_(), index_(), indexEnd_(), startEnd_() { - //if it is a hole and orientation is vertical or it is not a hole and orientation is horizontal - //we want to use this active tail, otherwise we want to use the other active tail - startEnd_ = TAIL; - if(!isHole ^ (orient == HORIZONTAL)) { - //switch winding direction - at = at->getOtherActiveTail(); - } - //now we have the right winding direction - //if it is horizontal we need to skip the first element - pLine_ = at->getTail(); - - if(at->getTail()->numSegments() > 0) - index_ = at->getTail()->numSegments() - 1; - - if((at->getOrient() == HORIZONTAL) ^ (orient == HORIZONTAL)) { - pLineEnd_ = at->getTail(); - indexEnd_ = pLineEnd_->numSegments() - 1; - if(index_ == 0) { - pLine_ = at->getTail()->next(HEAD); - if(at->getTail()->endConnectivity(HEAD) == TAIL) { - index_ = pLine_->numSegments() -1; - } else { - startEnd_ = HEAD; - index_ = 0; - } - } else { --index_; } - } else { - pLineEnd_ = at->getOtherActiveTail()->getTail(); - if(pLineEnd_->numSegments() > 0) - indexEnd_ = pLineEnd_->numSegments() - 1; - } - at->getTail()->joinTailToTail(*(at->getOtherActiveTail()->getTail())); - } - - inline size_t size(void){ - size_t count = 0; - End dir = startEnd_; - PolyLine<Unit> const * currLine = pLine_; - size_t ops = 0; - while(currLine != pLineEnd_){ - ops++; - count += currLine->numSegments(); - currLine = currLine->next(dir == HEAD ? TAIL : HEAD); - dir = currLine->endConnectivity(dir == HEAD ? TAIL : HEAD); - } - count += pLineEnd_->numSegments(); - return count; //no. of vertices - } - - //use bitwise copy and assign provided by the compiler - inline iterator& operator++() { - if(pLine_ == pLineEnd_ && index_ == indexEnd_) { - pLine_ = 0; - index_ = 0; - return *this; - } - if(startEnd_ == HEAD) { - ++index_; - if(index_ == pLine_->numSegments()) { - End end = pLine_->endConnectivity(TAIL); - pLine_ = pLine_->next(TAIL); - if(end == TAIL) { - startEnd_ = TAIL; - index_ = pLine_->numSegments() -1; - } else { - index_ = 0; - } - } - } else { - if(index_ == 0) { - End end = pLine_->endConnectivity(HEAD); - pLine_ = pLine_->next(HEAD); - if(end == TAIL) { - index_ = pLine_->numSegments() -1; - } else { - startEnd_ = HEAD; - index_ = 0; - } - } else { - --index_; - } - } - return *this; - } - inline const iterator operator++(int) { - iterator tmp(*this); - ++(*this); - return tmp; - } - inline bool operator==(const iterator& that) const { - return pLine_ == that.pLine_ && index_ == that.index_; - } - inline bool operator!=(const iterator& that) const { - return pLine_ != that.pLine_ || index_ != that.index_; - } - inline Unit operator*() { return (*pLine_)[index_]; } - }; - - /* - * iterator over holes contained within the figure - */ - typedef typename std::list<ActiveTail*>::const_iterator iteratorHoles; - - //default constructor - ActiveTail(); - - //constructor - ActiveTail(orientation_2d orient, Unit coord, Side solidToRight, ActiveTail* otherTailp); - - //constructor - ActiveTail(PolyLine<Unit>* active, ActiveTail* otherTailp); - - //copy constructor - ActiveTail(const ActiveTail& that); - - //destructor - ~ActiveTail(); - - //assignment operator - ActiveTail& operator=(const ActiveTail& that); - - //equivalence operator - bool operator==(const ActiveTail& b) const; - - /* - * comparison operators, ActiveTail objects are sortable by geometry - */ - bool operator<(const ActiveTail& b) const; - bool operator<=(const ActiveTail& b) const; - bool operator>(const ActiveTail& b) const; - bool operator>=(const ActiveTail& b) const; - - /* - * get the pointer to the polyline that this is an active tail of - */ - PolyLine<Unit>* getTail() const; - - /* - * get the pointer to the polyline at the other end of the chain - */ - PolyLine<Unit>* getOtherTail() const; - - /* - * get the pointer to the activetail at the other end of the chain - */ - ActiveTail* getOtherActiveTail() const; - - /* - * test if another active tail is the other end of the chain - */ - bool isOtherTail(const ActiveTail& b); - - /* - * update this end of chain pointer to new polyline - */ - ActiveTail& updateTail(PolyLine<Unit>* newTail); - - /* - * associate a hole to this active tail by the specified policy - */ - ActiveTail* addHole(ActiveTail* hole, bool fractureHoles); - - /* - * get the list of holes - */ - const std::list<ActiveTail*>& getHoles() const; - - /* - * copy holes from that to this - */ - void copyHoles(ActiveTail& that); - - /* - * find out if solid to right - */ - bool solidToRight() const; - - /* - * get coordinate (getCoord and getCoordinate are aliases for eachother) - */ - Unit getCoord() const; - Unit getCoordinate() const; - - /* - * get the tail orientation - */ - orientation_2d getOrient() const; - - /* - * add a coordinate to the polygon at this active tail end, properly handle degenerate edges by removing redundant coordinate - */ - void pushCoordinate(Unit coord); - - /* - * write the figure that this active tail points to out to the temp buffer - */ - void writeOutFigure(std::vector<Unit>& outVec, bool isHole = false) const; - - /* - * write the figure that this active tail points to out through iterators - */ - void writeOutFigureItrs(iterator& beginOut, iterator& endOut, bool isHole = false, orientation_2d orient = VERTICAL) const; - iterator begin(bool isHole, orientation_2d orient) const; - iterator end() const; - - /* - * write the holes that this active tail points to out through iterators - */ - void writeOutFigureHoleItrs(iteratorHoles& beginOut, iteratorHoles& endOut) const; - iteratorHoles beginHoles() const; - iteratorHoles endHoles() const; - - /* - * joins the two chains that the two active tail tails are ends of - * checks for closure of figure and writes out polygons appropriately - * returns a handle to a hole if one is closed - */ - static ActiveTail* joinChains(ActiveTail* at1, ActiveTail* at2, bool solid, std::vector<Unit>& outBufferTmp); - template <typename PolygonT> - static ActiveTail* joinChains(ActiveTail* at1, ActiveTail* at2, bool solid, typename std::vector<PolygonT>& outBufferTmp); - - /* - * deallocate temp buffer - */ - static void destroyOutBuffer(); - - /* - * deallocate all polygon data this active tail points to (deep delete, call only from one of a pair of active tails) - */ - void destroyContents(); - }; - - /* allocate a polyline object */ - template <typename Unit> - PolyLine<Unit>* createPolyLine(orientation_2d orient, Unit coord, Side side); - - /* deallocate a polyline object */ - template <typename Unit> - void destroyPolyLine(PolyLine<Unit>* pLine); - - /* allocate an activetail object */ - template <typename Unit> - ActiveTail<Unit>* createActiveTail(); - - /* deallocate an activetail object */ - template <typename Unit> - void destroyActiveTail(ActiveTail<Unit>* aTail); - - template<bool orientT, typename Unit> - class PolyLineHoleData { - private: - ActiveTail<Unit>* p_; - public: - typedef Unit coordinate_type; - typedef typename ActiveTail<Unit>::iterator compact_iterator_type; - typedef iterator_compact_to_points<compact_iterator_type, point_data<coordinate_type> > iterator_type; - inline PolyLineHoleData() : p_(0) {} - inline PolyLineHoleData(ActiveTail<Unit>* p) : p_(p) {} - //use default copy and assign - inline compact_iterator_type begin_compact() const { return p_->begin(true, (orientT ? VERTICAL : HORIZONTAL)); } - inline compact_iterator_type end_compact() const { return p_->end(); } - inline iterator_type begin() const { return iterator_type(begin_compact(), end_compact()); } - inline iterator_type end() const { return iterator_type(end_compact(), end_compact()); } - inline std::size_t size() const { - return p_->getPolyLineSize(); - } - inline ActiveTail<Unit>* yield() { return p_; } - }; - - template<bool orientT, typename Unit> - class PolyLinePolygonWithHolesData { - private: - ActiveTail<Unit>* p_; - public: - typedef Unit coordinate_type; - typedef typename ActiveTail<Unit>::iterator compact_iterator_type; - typedef iterator_compact_to_points<compact_iterator_type, point_data<coordinate_type> > iterator_type; - typedef PolyLineHoleData<orientT, Unit> hole_type; - typedef typename coordinate_traits<Unit>::area_type area_type; - class iteratorHoles { - private: - typename ActiveTail<Unit>::iteratorHoles itr_; - public: - inline iteratorHoles() : itr_() {} - inline iteratorHoles(typename ActiveTail<Unit>::iteratorHoles itr) : itr_(itr) {} - //use bitwise copy and assign provided by the compiler - inline iteratorHoles& operator++() { - ++itr_; - return *this; - } - inline const iteratorHoles operator++(int) { - iteratorHoles tmp(*this); - ++(*this); - return tmp; - } - inline bool operator==(const iteratorHoles& that) const { - return itr_ == that.itr_; - } - inline bool operator!=(const iteratorHoles& that) const { - return itr_ != that.itr_; - } - inline PolyLineHoleData<orientT, Unit> operator*() { return PolyLineHoleData<orientT, Unit>(*itr_);} - }; - typedef iteratorHoles iterator_holes_type; - - inline PolyLinePolygonWithHolesData() : p_(0) {} - inline PolyLinePolygonWithHolesData(ActiveTail<Unit>* p) : p_(p) {} - //use default copy and assign - inline compact_iterator_type begin_compact() const { return p_->begin(false, (orientT ? VERTICAL : HORIZONTAL)); } - inline compact_iterator_type end_compact() const { return p_->end(); } - inline iterator_type begin() const { return iterator_type(begin_compact(), end_compact()); } - inline iterator_type end() const { return iterator_type(end_compact(), end_compact()); } - inline iteratorHoles begin_holes() const { return iteratorHoles(p_->beginHoles()); } - inline iteratorHoles end_holes() const { return iteratorHoles(p_->endHoles()); } - inline ActiveTail<Unit>* yield() { return p_; } - //stub out these four required functions that will not be used but are needed for the interface - inline std::size_t size_holes() const { return 0; } - inline std::size_t size() const { return 0; } - }; - - - template <bool orientT, typename Unit, typename polygon_concept_type> - struct PolyLineType { }; - template <bool orientT, typename Unit> - struct PolyLineType<orientT, Unit, polygon_90_with_holes_concept> { typedef PolyLinePolygonWithHolesData<orientT, Unit> type; }; - template <bool orientT, typename Unit> - struct PolyLineType<orientT, Unit, polygon_45_with_holes_concept> { typedef PolyLinePolygonWithHolesData<orientT, Unit> type; }; - template <bool orientT, typename Unit> - struct PolyLineType<orientT, Unit, polygon_with_holes_concept> { typedef PolyLinePolygonWithHolesData<orientT, Unit> type; }; - template <bool orientT, typename Unit> - struct PolyLineType<orientT, Unit, polygon_90_concept> { typedef PolyLineHoleData<orientT, Unit> type; }; - template <bool orientT, typename Unit> - struct PolyLineType<orientT, Unit, polygon_45_concept> { typedef PolyLineHoleData<orientT, Unit> type; }; - template <bool orientT, typename Unit> - struct PolyLineType<orientT, Unit, polygon_concept> { typedef PolyLineHoleData<orientT, Unit> type; }; - - template <bool orientT, typename Unit, typename polygon_concept_type> - class ScanLineToPolygonItrs { - private: - std::map<Unit, ActiveTail<Unit>*> tailMap_; - typedef typename PolyLineType<orientT, Unit, polygon_concept_type>::type PolyLinePolygonData; - std::vector<PolyLinePolygonData> outputPolygons_; - bool fractureHoles_; - public: - typedef typename std::vector<PolyLinePolygonData>::iterator iterator; - inline ScanLineToPolygonItrs() : tailMap_(), outputPolygons_(), fractureHoles_(false) {} - /* construct a scanline with the proper offsets, protocol and options */ - inline ScanLineToPolygonItrs(bool fractureHoles) : tailMap_(), outputPolygons_(), fractureHoles_(fractureHoles) {} - - ~ScanLineToPolygonItrs() { clearOutput_(); } - - /* process all vertical edges, left and right, at a unique x coordinate, edges must be sorted low to high */ - void processEdges(iterator& beginOutput, iterator& endOutput, - Unit currentX, std::vector<interval_data<Unit> >& leftEdges, - std::vector<interval_data<Unit> >& rightEdges, - size_t vertexThreshold=(std::numeric_limits<size_t>::max)() ); - - /********************************************************************** - *methods implementing new polygon formation code - * - **********************************************************************/ - void updatePartialSimplePolygonsWithRightEdges(Unit currentX, - const std::vector<interval_data<Unit> >& leftEdges, size_t threshold); - - void updatePartialSimplePolygonsWithLeftEdges(Unit currentX, - const std::vector<interval_data<Unit> >& leftEdges, size_t threshold); - - void closePartialSimplePolygon(Unit, ActiveTail<Unit>*, ActiveTail<Unit>*); - - void maintainPartialSimplePolygonInvariant(iterator& ,iterator& ,Unit, - const std::vector<interval_data<Unit> >&, - const std::vector<interval_data<Unit> >&, - size_t vertexThreshold=(std::numeric_limits<size_t>::max)()); - - void insertNewLeftEdgeIntoTailMap(Unit, Unit, Unit, - typename std::map<Unit, ActiveTail<Unit>*>::iterator &); - /**********************************************************************/ - - inline size_t getTailMapSize(){ - typename std::map<Unit, ActiveTail<Unit>* >::const_iterator itr; - size_t tsize = 0; - for(itr=tailMap_.begin(); itr!=tailMap_.end(); ++itr){ - tsize += (itr->second)->getPolyLineSize(); - } - return tsize; - } - /*print the active tails in this map:*/ - inline void print(){ - typename std::map<Unit, ActiveTail<Unit>* >::const_iterator itr; - printf("=========TailMap[%lu]=========\n", tailMap_.size()); - for(itr=tailMap_.begin(); itr!=tailMap_.end(); ++itr){ - std::cout<< "[" << itr->first << "] : " << std::endl; - //print active tail// - ActiveTail<Unit> const *t = (itr->second); - PolyLine<Unit> const *pBegin = t->getTail(); - PolyLine<Unit> const *pEnd = t->getOtherActiveTail()->getTail(); - std::string sorient = pBegin->solidToRight() ? "RIGHT" : "LEFT"; - std::cout<< " ActiveTail.tailp_ (solid= " << sorient ; - End dir = TAIL; - while(pBegin!=pEnd){ - std::cout << pBegin << "={ "; - for(size_t i=0; i<pBegin->numSegments(); i++){ - point_data<Unit> u = pBegin->getPoint(i); - std::cout << "(" << u.x() << "," << u.y() << ") "; - } - std::cout << "} "; - pBegin = pBegin->next(dir == HEAD ? TAIL : HEAD); - dir = pBegin->endConnectivity(dir == HEAD ? TAIL : HEAD); - } - if(pEnd){ - std::cout << pEnd << "={ "; - for(size_t i=0; i<pEnd->numSegments(); i++){ - point_data<Unit> u = pEnd->getPoint(i); - std::cout << "(" << u.x() << "," << u.y() << ") "; - } - std::cout << "} "; - } - std::cout << " end= " << pEnd << std::endl; - } - } - - private: - void clearOutput_(); - }; - - /* - * ScanLine does all the work of stitching together polygons from incoming vertical edges - */ -// template <typename Unit, typename polygon_concept_type> -// class ScanLineToPolygons { -// private: -// ScanLineToPolygonItrs<true, Unit> scanline_; -// public: -// inline ScanLineToPolygons() : scanline_() {} -// /* construct a scanline with the proper offsets, protocol and options */ -// inline ScanLineToPolygons(bool fractureHoles) : scanline_(fractureHoles) {} - -// /* process all vertical edges, left and right, at a unique x coordinate, edges must be sorted low to high */ -// inline void processEdges(std::vector<Unit>& outBufferTmp, Unit currentX, std::vector<interval_data<Unit> >& leftEdges, -// std::vector<interval_data<Unit> >& rightEdges) { -// typename ScanLineToPolygonItrs<true, Unit>::iterator itr, endItr; -// scanline_.processEdges(itr, endItr, currentX, leftEdges, rightEdges); -// //copy data into outBufferTmp -// while(itr != endItr) { -// typename PolyLinePolygonData<true, Unit>::iterator pditr; -// outBufferTmp.push_back(0); -// unsigned int sizeIndex = outBufferTmp.size() - 1; -// int count = 0; -// for(pditr = (*itr).begin(); pditr != (*itr).end(); ++pditr) { -// outBufferTmp.push_back(*pditr); -// ++count; -// } -// outBufferTmp[sizeIndex] = count; -// typename PolyLinePolygonData<true, Unit>::iteratorHoles pdHoleItr; -// for(pdHoleItr = (*itr).beginHoles(); pdHoleItr != (*itr).endHoles(); ++pdHoleItr) { -// outBufferTmp.push_back(0); -// unsigned int sizeIndex2 = outBufferTmp.size() - 1; -// int count2 = 0; -// for(pditr = (*pdHoleItr).begin(); pditr != (*pdHoleItr).end(); ++pditr) { -// outBufferTmp.push_back(*pditr); -// ++count2; -// } -// outBufferTmp[sizeIndex2] = -count; -// } -// ++itr; -// } -// } -// }; - - const int VERTICAL_HEAD = 1, HEAD_TO_TAIL = 2, TAIL_TO_TAIL = 4, SOLID_TO_RIGHT = 8; - - //EVERY FUNCTION in this DEF file should be explicitly defined as inline - - //microsoft compiler improperly warns whenever you cast an integer to bool - //call this function on an integer to convert it to bool without a warning - template <class T> - inline bool to_bool(const T& val) { return val != 0; } - - //default constructor (for preallocation) - template <typename Unit> - inline PolyLine<Unit>::PolyLine() : ptdata_() ,headp_(0), tailp_(0), state_(-1) {} - - //constructor - template <typename Unit> - inline PolyLine<Unit>::PolyLine(orientation_2d orient, Unit coord, Side side) : - ptdata_(1, coord), - headp_(0), - tailp_(0), - state_(orient.to_int() + - (side << 3)){} - - //copy constructor - template <typename Unit> - inline PolyLine<Unit>::PolyLine(const PolyLine<Unit>& pline) : ptdata_(pline.ptdata_), - headp_(pline.headp_), - tailp_(pline.tailp_), - state_(pline.state_) {} - - //destructor - template <typename Unit> - inline PolyLine<Unit>::~PolyLine() { - //clear out data just in case it is read later - headp_ = tailp_ = 0; - state_ = 0; - } - - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::operator=(const PolyLine<Unit>& that) { - if(!(this == &that)) { - headp_ = that.headp_; - tailp_ = that.tailp_; - ptdata_ = that.ptdata_; - state_ = that.state_; - } - return *this; - } - - template <typename Unit> - inline bool PolyLine<Unit>::operator==(const PolyLine<Unit>& b) const { - return this == &b || (state_ == b.state_ && - headp_ == b.headp_ && - tailp_ == b.tailp_); - } - - //valid PolyLine - template <typename Unit> - inline bool PolyLine<Unit>::isValid() const { - return state_ > -1; } - - //first coordinate is an X value - //first segment is vertical - template <typename Unit> - inline bool PolyLine<Unit>::verticalHead() const { - return state_ & VERTICAL_HEAD; - } - - //retrun true is PolyLine has odd number of coordiantes - template <typename Unit> - inline bool PolyLine<Unit>::oddLength() const { - return to_bool((ptdata_.size()-1) % 2); - } - - //last coordiante is an X value - //last segment is vertical - template <typename Unit> - inline bool PolyLine<Unit>::verticalTail() const { - return to_bool(verticalHead() ^ oddLength()); - } - - template <typename Unit> - inline orientation_2d PolyLine<Unit>::tailOrient() const { - return (verticalTail() ? VERTICAL : HORIZONTAL); - } - - template <typename Unit> - inline orientation_2d PolyLine<Unit>::headOrient() const { - return (verticalHead() ? VERTICAL : HORIZONTAL); - } - - template <typename Unit> - inline End PolyLine<Unit>::endConnectivity(End end) const { - //Tail should be defined as true - if(end) { return tailToTail(); } - return headToTail(); - } - - template <typename Unit> - inline bool PolyLine<Unit>::headToTail() const { - return to_bool(state_ & HEAD_TO_TAIL); - } - - template <typename Unit> - inline bool PolyLine<Unit>::headToHead() const { - return to_bool(!headToTail()); - } - - template <typename Unit> - inline bool PolyLine<Unit>::tailToHead() const { - return to_bool(!tailToTail()); - } - - template <typename Unit> - inline bool PolyLine<Unit>::tailToTail() const { - return to_bool(state_ & TAIL_TO_TAIL); - } - - template <typename Unit> - inline Side PolyLine<Unit>::solidSide() const { - return solidToRight(); } - - template <typename Unit> - inline bool PolyLine<Unit>::solidToRight() const { - return to_bool(state_ & SOLID_TO_RIGHT) != 0; - } - - template <typename Unit> - inline bool PolyLine<Unit>::active() const { - return !to_bool(tailp_); - } - - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::pushCoordinate(Unit coord) { - ptdata_.push_back(coord); - return *this; - } - - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::popCoordinate() { - ptdata_.pop_back(); - return *this; - } - - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::pushPoint(const point_data<Unit>& point) { - if(numSegments()){ - point_data<Unit> endPt = getEndPoint(); - //vertical is true, horizontal is false - if((tailOrient().to_int() ? point.get(VERTICAL) == endPt.get(VERTICAL) : point.get(HORIZONTAL) == endPt.get(HORIZONTAL))) { - //we were pushing a colinear segment - return popCoordinate(); - } - } - return pushCoordinate(tailOrient().to_int() ? point.get(VERTICAL) : point.get(HORIZONTAL)); - } - - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::extendTail(Unit delta) { - ptdata_.back() += delta; - return *this; - } - - //private member function that creates a link from this PolyLine to that - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinTo_(End thisEnd, PolyLine<Unit>& that, End end) { - if(thisEnd){ - tailp_ = &that; - state_ &= ~TAIL_TO_TAIL; //clear any previous state_ of bit (for safety) - state_ |= (end << 2); //place bit into mask - } else { - headp_ = &that; - state_ &= ~HEAD_TO_TAIL; //clear any previous state_ of bit (for safety) - state_ |= (end << 1); //place bit into mask - } - return *this; - } - - //join two PolyLines (both ways of the association) - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinTo(End thisEnd, PolyLine<Unit>& that, End end) { - joinTo_(thisEnd, that, end); - that.joinTo_(end, *this, thisEnd); - return *this; - } - - //convenience functions for joining PolyLines - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinToTail(PolyLine<Unit>& that, End end) { - return joinTo(TAIL, that, end); - } - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinToHead(PolyLine<Unit>& that, End end) { - return joinTo(HEAD, that, end); - } - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinHeadToHead(PolyLine<Unit>& that) { - return joinToHead(that, HEAD); - } - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinHeadToTail(PolyLine<Unit>& that) { - return joinToHead(that, TAIL); - } - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinTailToHead(PolyLine<Unit>& that) { - return joinToTail(that, HEAD); - } - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::joinTailToTail(PolyLine<Unit>& that) { - return joinToTail(that, TAIL); - } - - template <typename Unit> - inline PolyLine<Unit>& PolyLine<Unit>::disconnectTails() { - next(TAIL)->state_ &= !TAIL_TO_TAIL; - next(TAIL)->tailp_ = 0; - state_ &= !TAIL_TO_TAIL; - tailp_ = 0; - return *this; - } - - template <typename Unit> - inline Unit PolyLine<Unit>::getEndCoord(End end) const { - if(end) - return ptdata_.back(); - return ptdata_.front(); - } - - template <typename Unit> - inline orientation_2d PolyLine<Unit>::segmentOrient(unsigned int index) const { - return (to_bool((unsigned int)verticalHead() ^ (index % 2)) ? VERTICAL : HORIZONTAL); - } - - template <typename Unit> - inline point_data<Unit> PolyLine<Unit>::getPoint(unsigned int index) const { - //assert(isValid() && headp_->isValid()) ("PolyLine: headp_ must be valid"); - point_data<Unit> pt; - pt.set(HORIZONTAL, ptdata_[index]); - pt.set(VERTICAL, ptdata_[index]); - Unit prevCoord; - if(index == 0) { - prevCoord = headp_->getEndCoord(headToTail()); - } else { - prevCoord = ptdata_[index-1]; - } - pt.set(segmentOrient(index), prevCoord); - return pt; - } - - template <typename Unit> - inline point_data<Unit> PolyLine<Unit>::getEndPoint(End end) const { - return getPoint((end ? numSegments() - 1 : (unsigned int)0)); - } - - template <typename Unit> - inline Unit PolyLine<Unit>::operator[] (unsigned int index) const { - //assert(ptdata_.size() > index) ("PolyLine: out of bounds index"); - return ptdata_[index]; - } - - template <typename Unit> - inline unsigned int PolyLine<Unit>::numSegments() const { - return ptdata_.size(); - } - - template <typename Unit> - inline PolyLine<Unit>* PolyLine<Unit>::next(End end) const { - return (end ? tailp_ : headp_); - } - - template <typename Unit> - inline ActiveTail<Unit>::ActiveTail() : tailp_(0), otherTailp_(0), holesList_(), - polyLineSize_(0) {} - - template <typename Unit> - inline ActiveTail<Unit>::ActiveTail(orientation_2d orient, Unit coord, Side solidToRight, ActiveTail* otherTailp) : - tailp_(0), otherTailp_(0), holesList_(), polyLineSize_(0) { - tailp_ = createPolyLine(orient, coord, solidToRight); - otherTailp_ = otherTailp; - polyLineSize_ = tailp_->numSegments(); - } - - template <typename Unit> - inline ActiveTail<Unit>::ActiveTail(PolyLine<Unit>* active, ActiveTail<Unit>* otherTailp) : - tailp_(active), otherTailp_(otherTailp), holesList_(), - polyLineSize_(0) {} - - //copy constructor - template <typename Unit> - inline ActiveTail<Unit>::ActiveTail(const ActiveTail<Unit>& that) : tailp_(that.tailp_), otherTailp_(that.otherTailp_), holesList_(), polyLineSize_(that.polyLineSize_) {} - - //destructor - template <typename Unit> - inline ActiveTail<Unit>::~ActiveTail() { - //clear them in case the memory is read later - tailp_ = 0; otherTailp_ = 0; - } - - template <typename Unit> - inline ActiveTail<Unit>& ActiveTail<Unit>::operator=(const ActiveTail<Unit>& that) { - //self assignment is safe in this case - tailp_ = that.tailp_; - otherTailp_ = that.otherTailp_; - polyLineSize_ = that.polyLineSize_; - return *this; - } - - template <typename Unit> - inline bool ActiveTail<Unit>::operator==(const ActiveTail<Unit>& b) const { - return tailp_ == b.tailp_ && otherTailp_ == b.otherTailp_; - } - - template <typename Unit> - inline bool ActiveTail<Unit>::operator<(const ActiveTail<Unit>& b) const { - return tailp_->getEndPoint().get(VERTICAL) < b.tailp_->getEndPoint().get(VERTICAL); - } - - template <typename Unit> - inline bool ActiveTail<Unit>::operator<=(const ActiveTail<Unit>& b) const { - return !(*this > b); } - - template <typename Unit> - inline bool ActiveTail<Unit>::operator>(const ActiveTail<Unit>& b) const { - return b < (*this); } - - template <typename Unit> - inline bool ActiveTail<Unit>::operator>=(const ActiveTail<Unit>& b) const { - return !(*this < b); } - - template <typename Unit> - inline PolyLine<Unit>* ActiveTail<Unit>::getTail() const { - return tailp_; } - - template <typename Unit> - inline PolyLine<Unit>* ActiveTail<Unit>::getOtherTail() const { - return otherTailp_->tailp_; } - - template <typename Unit> - inline ActiveTail<Unit>* ActiveTail<Unit>::getOtherActiveTail() const { - return otherTailp_; } - - template <typename Unit> - inline bool ActiveTail<Unit>::isOtherTail(const ActiveTail<Unit>& b) { - // assert( (tailp_ == b.getOtherTail() && getOtherTail() == b.tailp_) || - // (tailp_ != b.getOtherTail() && getOtherTail() != b.tailp_)) - // ("ActiveTail: Active tails out of sync"); - return otherTailp_ == &b; - } - - template <typename Unit> - inline ActiveTail<Unit>& ActiveTail<Unit>::updateTail(PolyLine<Unit>* newTail) { - //subtract the old size and add new size// - int delta = newTail->numSegments() - tailp_->numSegments(); - addPolyLineSize(delta); - otherTailp_->addPolyLineSize(delta); - tailp_ = newTail; - return *this; - } - - template <typename Unit> - inline ActiveTail<Unit>* ActiveTail<Unit>::addHole(ActiveTail<Unit>* hole, bool fractureHoles) { - - if(!fractureHoles){ - holesList_.push_back(hole); - copyHoles(*hole); - copyHoles(*(hole->getOtherActiveTail())); - return this; - } - ActiveTail<Unit>* h, *v; - ActiveTail<Unit>* other = hole->getOtherActiveTail(); - if(other->getOrient() == VERTICAL) { - //assert that hole.getOrient() == HORIZONTAL - //this case should never happen - h = hole; - v = other; - } else { - //assert that hole.getOrient() == VERTICAL - h = other; - v = hole; - } - h->pushCoordinate(v->getCoordinate()); - //assert that h->getOrient() == VERTICAL - //v->pushCoordinate(getCoordinate()); - //assert that v->getOrient() == VERTICAL - //I can't close a figure by adding a hole, so pass zero for xMin and yMin - std::vector<Unit> tmpVec; - ActiveTail<Unit>::joinChains(this, h, false, tmpVec); - return v; - } - - template <typename Unit> - inline const std::list<ActiveTail<Unit>*>& ActiveTail<Unit>::getHoles() const { - return holesList_; - } - - template <typename Unit> - inline void ActiveTail<Unit>::copyHoles(ActiveTail<Unit>& that) { - holesList_.splice(holesList_.end(), that.holesList_); //splice the two lists together - } - - template <typename Unit> - inline bool ActiveTail<Unit>::solidToRight() const { - return getTail()->solidToRight(); } - - template <typename Unit> - inline Unit ActiveTail<Unit>::getCoord() const { - return getTail()->getEndCoord(); } - - template <typename Unit> - inline Unit ActiveTail<Unit>::getCoordinate() const { - return getCoord(); } - - template <typename Unit> - inline orientation_2d ActiveTail<Unit>::getOrient() const { - return getTail()->tailOrient(); } - - template <typename Unit> - inline void ActiveTail<Unit>::pushCoordinate(Unit coord) { - //appropriately handle any co-linear polyline segments by calling push point internally - point_data<Unit> p; - p.set(HORIZONTAL, coord); - p.set(VERTICAL, coord); - //if we are vertical assign the last coordinate (an X) to p.x, else to p.y - p.set(getOrient().get_perpendicular(), getCoordinate()); - int oldSegments = tailp_->numSegments(); - tailp_->pushPoint(p); - int delta = tailp_->numSegments() - oldSegments; - addPolyLineSize(delta); - otherTailp_->addPolyLineSize(delta); - } - - - //global utility functions - template <typename Unit> - inline PolyLine<Unit>* createPolyLine(orientation_2d orient, Unit coord, Side side) { - return new PolyLine<Unit>(orient, coord, side); - } - - template <typename Unit> - inline void destroyPolyLine(PolyLine<Unit>* pLine) { - delete pLine; - } - - template <typename Unit> - inline ActiveTail<Unit>* createActiveTail() { - //consider replacing system allocator with ActiveTail memory pool - return new ActiveTail<Unit>(); - } - - template <typename Unit> - inline void destroyActiveTail(ActiveTail<Unit>* aTail) { - delete aTail; - } - - - //no recursion, to prevent max recursion depth errors - template <typename Unit> - inline void ActiveTail<Unit>::destroyContents() { - tailp_->disconnectTails(); - PolyLine<Unit>* nextPolyLinep = tailp_->next(HEAD); - End end = tailp_->endConnectivity(HEAD); - destroyPolyLine(tailp_); - while(nextPolyLinep) { - End nextEnd = nextPolyLinep->endConnectivity(!end); //get the direction of next polyLine - PolyLine<Unit>* nextNextPolyLinep = nextPolyLinep->next(!end); //get the next polyline - destroyPolyLine(nextPolyLinep); //destroy the current polyline - end = nextEnd; - nextPolyLinep = nextNextPolyLinep; - } - } - - template <typename Unit> - inline typename ActiveTail<Unit>::iterator ActiveTail<Unit>::begin(bool isHole, orientation_2d orient) const { - return iterator(this, isHole, orient); - } - - template <typename Unit> - inline typename ActiveTail<Unit>::iterator ActiveTail<Unit>::end() const { - return iterator(); - } - - template <typename Unit> - inline typename ActiveTail<Unit>::iteratorHoles ActiveTail<Unit>::beginHoles() const { - return holesList_.begin(); - } - - template <typename Unit> - inline typename ActiveTail<Unit>::iteratorHoles ActiveTail<Unit>::endHoles() const { - return holesList_.end(); - } - - template <typename Unit> - inline void ActiveTail<Unit>::writeOutFigureItrs(iterator& beginOut, iterator& endOut, bool isHole, orientation_2d orient) const { - beginOut = begin(isHole, orient); - endOut = end(); - } - - template <typename Unit> - inline void ActiveTail<Unit>::writeOutFigureHoleItrs(iteratorHoles& beginOut, iteratorHoles& endOut) const { - beginOut = beginHoles(); - endOut = endHoles(); - } - - template <typename Unit> - inline void ActiveTail<Unit>::writeOutFigure(std::vector<Unit>& outVec, bool isHole) const { - //we start writing out the polyLine that this active tail points to at its tail - std::size_t size = outVec.size(); - outVec.push_back(0); //place holder for size - PolyLine<Unit>* nextPolyLinep = 0; - if(!isHole){ - nextPolyLinep = otherTailp_->tailp_->writeOut(outVec); - } else { - nextPolyLinep = tailp_->writeOut(outVec); - } - Unit firsty = outVec[size + 1]; - if((getOrient() == HORIZONTAL) ^ !isHole) { - //our first coordinate is a y value, so we need to rotate it to the end - typename std::vector<Unit>::iterator tmpItr = outVec.begin(); - tmpItr += size; - outVec.erase(++tmpItr); //erase the 2nd element - } - End startEnd = tailp_->endConnectivity(HEAD); - if(isHole) startEnd = otherTailp_->tailp_->endConnectivity(HEAD); - while(nextPolyLinep) { - bool nextStartEnd = nextPolyLinep->endConnectivity(!startEnd); - nextPolyLinep = nextPolyLinep->writeOut(outVec, startEnd); - startEnd = nextStartEnd; - } - if((getOrient() == HORIZONTAL) ^ !isHole) { - //we want to push the y value onto the end since we ought to have ended with an x - outVec.push_back(firsty); //should never be executed because we want first value to be an x - } - //the vector contains the coordinates of the linked list of PolyLines in the correct order - //first element is supposed to be the size - outVec[size] = outVec.size() - 1 - size; //number of coordinates in vector - //assert outVec[size] % 2 == 0 //it should be even - //make the size negative for holes - outVec[size] *= (isHole ? -1 : 1); - } - - //no recursion to prevent max recursion depth errors - template <typename Unit> - inline PolyLine<Unit>* PolyLine<Unit>::writeOut(std::vector<Unit>& outVec, End startEnd) const { - if(startEnd == HEAD){ - //forward order - outVec.insert(outVec.end(), ptdata_.begin(), ptdata_.end()); - return tailp_; - }else{ - //reverse order - //do not reserve because we expect outVec to be large enough already - for(int i = ptdata_.size() - 1; i >= 0; --i){ - outVec.push_back(ptdata_[i]); - } - //NT didn't know about this version of the API.... - //outVec.insert(outVec.end(), ptdata_.rbegin(), ptdata_.rend()); - return headp_; - } - } - - //solid indicates if it was joined by a solit or a space - template <typename Unit> - inline ActiveTail<Unit>* ActiveTail<Unit>::joinChains(ActiveTail<Unit>* at1, ActiveTail<Unit>* at2, bool solid, std::vector<Unit>& outBufferTmp) - { - //checks to see if we closed a figure - if(at1->isOtherTail(*at2)){ - //value of solid tells us if we closed solid or hole - //and output the solid or handle the hole appropriately - //if the hole needs to fracture across horizontal partition boundary we need to notify - //the calling context to do so - if(solid) { - //the chains are being joined because there is solid to the right - //this means that if the figure is closed at this point it must be a hole - //because otherwise it would have to have another vertex to the right of this one - //and would not be closed at this point - return at1; - } else { - //assert pG != 0 - //the figure that was closed is a shell - at1->writeOutFigure(outBufferTmp); - //process holes of the polygon - at1->copyHoles(*at2); //there should not be holes on at2, but if there are, copy them over - const std::list<ActiveTail<Unit>*>& holes = at1->getHoles(); - for(typename std::list<ActiveTail<Unit>*>::const_iterator litr = holes.begin(); litr != holes.end(); ++litr) { - (*litr)->writeOutFigure(outBufferTmp, true); - //delete the hole - (*litr)->destroyContents(); - destroyActiveTail((*litr)->getOtherActiveTail()); - destroyActiveTail((*litr)); - } - //delete the polygon - at1->destroyContents(); - //at2 contents are the same as at1, so it should not destroy them - destroyActiveTail(at1); - destroyActiveTail(at2); - } - return 0; - } - //join the two partial polygons into one large partial polygon - at1->getTail()->joinTailToTail(*(at2->getTail())); - *(at1->getOtherActiveTail()) = ActiveTail(at1->getOtherTail(), at2->getOtherActiveTail()); - *(at2->getOtherActiveTail()) = ActiveTail(at2->getOtherTail(), at1->getOtherActiveTail()); - - int accumulate = at2->getPolyLineSize() + at1->getPolyLineSize(); - (at1->getOtherActiveTail())->setPolyLineSize(accumulate); - (at2->getOtherActiveTail())->setPolyLineSize(accumulate); - - at1->getOtherActiveTail()->copyHoles(*at1); - at1->getOtherActiveTail()->copyHoles(*at2); - destroyActiveTail(at1); - destroyActiveTail(at2); - return 0; - } - - //solid indicates if it was joined by a solit or a space - template <typename Unit> - template <typename PolygonT> - inline ActiveTail<Unit>* ActiveTail<Unit>::joinChains(ActiveTail<Unit>* at1, ActiveTail<Unit>* at2, bool solid, - std::vector<PolygonT>& outBufferTmp) { - //checks to see if we closed a figure - if(at1->isOtherTail(*at2)){ - //value of solid tells us if we closed solid or hole - //and output the solid or handle the hole appropriately - //if the hole needs to fracture across horizontal partition boundary we need to notify - //the calling context to do so - if(solid) { - //the chains are being joined because there is solid to the right - //this means that if the figure is closed at this point it must be a hole - //because otherwise it would have to have another vertex to the right of this one - //and would not be closed at this point - return at1; - } else { - //assert pG != 0 - //the figure that was closed is a shell - outBufferTmp.push_back(at1); - at1->copyHoles(*at2); //there should not be holes on at2, but if there are, copy them over - } - return 0; - } - //join the two partial polygons into one large partial polygon - at1->getTail()->joinTailToTail(*(at2->getTail())); - *(at1->getOtherActiveTail()) = ActiveTail<Unit>(at1->getOtherTail(), at2->getOtherActiveTail()); - *(at2->getOtherActiveTail()) = ActiveTail<Unit>(at2->getOtherTail(), at1->getOtherActiveTail()); - - int accumulate = at2->getPolyLineSize() + at1->getPolyLineSize(); - (at1->getOtherActiveTail())->setPolyLineSize(accumulate); - (at2->getOtherActiveTail())->setPolyLineSize(accumulate); - - at1->getOtherActiveTail()->copyHoles(*at1); - at1->getOtherActiveTail()->copyHoles(*at2); - destroyActiveTail(at1); - destroyActiveTail(at2); - return 0; - } - - template <class TKey, class T> inline typename std::map<TKey, T>::iterator findAtNext(std::map<TKey, T>& theMap, - typename std::map<TKey, T>::iterator pos, const TKey& key) - { - if(pos == theMap.end()) return theMap.find(key); - //if they match the mapItr is pointing to the correct position - if(pos->first < key) { - return theMap.find(key); - } - if(pos->first > key) { - return theMap.end(); - } - //else they are equal and no need to do anything to the iterator - return pos; - } - - // createActiveTailsAsPair is called in these two end cases of geometry - // 1. lower left concave corner - // ###| - // ###| - // ###|### - // ###|### - // 2. lower left convex corner - // |### - // |### - // | - // | - // In case 1 there may be a hole propigated up from the bottom. If the fracture option is enabled - // the two active tails that form the filament fracture line edges can become the new active tail pair - // by pushing x and y onto them. Otherwise the hole simply needs to be associated to one of the new active tails - // with add hole - template <typename Unit> - inline std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> createActiveTailsAsPair(Unit x, Unit y, bool solid, ActiveTail<Unit>* phole, bool fractureHoles) { - ActiveTail<Unit>* at1 = 0; - ActiveTail<Unit>* at2 = 0; - if(!phole || !fractureHoles){ - at1 = createActiveTail<Unit>(); - at2 = createActiveTail<Unit>(); - (*at1) = ActiveTail<Unit>(VERTICAL, x, solid, at2); - (*at2) = ActiveTail<Unit>(HORIZONTAL, y, !solid, at1); - //provide a function through activeTail class to provide this - at1->getTail()->joinHeadToHead(*(at2->getTail())); - - at1->addPolyLineSize(1); - at2->addPolyLineSize(1); - - if(phole) - at1->addHole(phole, fractureHoles); //assert fractureHoles == false - return std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*>(at1, at2); - } - //assert phole is not null - //assert fractureHoles is true - if(phole->getOrient() == VERTICAL) { - at2 = phole; - } else { - at2 = phole->getOtherActiveTail(); //should never be executed since orientation is expected to be vertical - } - //assert solid == false, we should be creating a corner with solid below and to the left if there was a hole - at1 = at2->getOtherActiveTail(); - //assert at1 is horizontal - at1->pushCoordinate(x); - //assert at2 is vertical - at2->pushCoordinate(y); - - return std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*>(at1, at2); - } - - /* - * | - * | - * = - * |######## - * |######## (add a new ActiveTail in the tailMap_). - * |######## - * |######## - * |######## - * = - * | - * | - * - * NOTE: Call this only if you are sure that the $ledege$ is not in the tailMap_ - */ - template<bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>:: - insertNewLeftEdgeIntoTailMap(Unit currentX, Unit yBegin, Unit yEnd, - typename std::map<Unit, ActiveTail<Unit> *>::iterator &hint){ - ActiveTail<Unit> *currentTail = NULL; - std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> tailPair = - createActiveTailsAsPair(currentX, yBegin, true, currentTail, - fractureHoles_); - currentTail = tailPair.first; - if(!tailMap_.empty()){ - ++hint; - } - hint = tailMap_.insert(hint, std::make_pair(yBegin, tailPair.second)); - currentTail->pushCoordinate(yEnd); ++hint; - hint = tailMap_.insert(hint, std::make_pair(yEnd, currentTail)); - } - - template<bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>:: - closePartialSimplePolygon(Unit currentX, ActiveTail<Unit>*pfig, - ActiveTail<Unit>*ppfig){ - pfig->pushCoordinate(currentX); - ActiveTail<Unit>::joinChains(pfig, ppfig, false, outputPolygons_); - } - /* - * If the invariant is maintained correctly then left edges can do the - * following. - * - * =### - * ####### - * ####### - * ####### - * ####### - * =### - * |### (input left edge) - * |### - * =### - * ####### - * ####### - * =### - */ - template<bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>:: - updatePartialSimplePolygonsWithLeftEdges(Unit currentX, - const std::vector<interval_data<Unit> > &leftEdges, size_t vertexThreshold){ - typename std::map<Unit, ActiveTail<Unit>* >::iterator succ, succ1; - typename std::map<Unit, ActiveTail<Unit>* >::iterator pred, pred1, hint; - Unit begin, end; - ActiveTail<Unit> *pfig, *ppfig; - std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> tailPair; - size_t pfig_size = 0; - - hint = tailMap_.begin(); - for(size_t i=0; i < leftEdges.size(); i++){ - begin = leftEdges[i].get(LOW); end = leftEdges[i].get(HIGH); - succ = findAtNext(tailMap_, hint, begin); - pred = findAtNext(tailMap_, hint, end); - - if(succ != tailMap_.end() && pred != tailMap_.end()){ //CASE-1// - //join the corresponding active tails// - pfig = succ->second; ppfig = pred->second; - pfig_size = pfig->getPolyLineSize() + ppfig->getPolyLineSize(); - - if(pfig_size >= vertexThreshold){ - size_t bsize = pfig->getPolyLineSize(); - size_t usize = ppfig->getPolyLineSize(); - - if(usize+2 < vertexThreshold){ - //cut-off the lower piece (succ1, succ) join (succ1, pred)// - succ1 = succ; --succ1; - assert((succ1 != tailMap_.end()) && - ((succ->second)->getOtherActiveTail() == succ1->second)); - closePartialSimplePolygon(currentX, succ1->second, succ->second); - tailPair = createActiveTailsAsPair<Unit>(currentX, succ1->first, - true, NULL, fractureHoles_); - - //just update the succ1 with new ActiveTail<Unit>*// - succ1->second = tailPair.second; - ActiveTail<Unit>::joinChains(tailPair.first, pred->second, true, - outputPolygons_); - }else if(bsize+2 < vertexThreshold){ - //cut-off the upper piece () join ()// - pred1 = pred; ++pred1; - assert(pred1 != tailMap_.end() && - ((pred1->second)->getOtherActiveTail() == pred->second)); - closePartialSimplePolygon(currentX, pred->second, pred1->second); - - //just update the pred1 with ActiveTail<Unit>* = pfig// - pred1->second = pfig; - pfig->pushCoordinate(currentX); - pfig->pushCoordinate(pred1->first); - }else{ - //cut both and create an left edge between (pred->first, succ1)// - succ1 = succ; --succ1; - pred1 = pred; ++pred1; - assert(pred1 != tailMap_.end() && succ1 != tailMap_.end()); - assert((pred1->second)->getOtherActiveTail() == pred->second); - assert((succ1->second)->getOtherActiveTail() == succ->second); - - closePartialSimplePolygon(currentX, succ1->second, succ->second); - closePartialSimplePolygon(currentX, pred->second, pred1->second); - - tailPair = createActiveTailsAsPair<Unit>(currentX, succ1->first, - true, NULL, fractureHoles_); - succ1->second = tailPair.second; - pred1->second = tailPair.first; - (tailPair.first)->pushCoordinate(pred1->first); - } - }else{ - //just join them with closing// - pfig->pushCoordinate(currentX); - ActiveTail<Unit>::joinChains(pfig, ppfig, true, outputPolygons_); - } - hint = pred; ++hint; - tailMap_.erase(succ); tailMap_.erase(pred); - }else if(succ == tailMap_.end() && pred != tailMap_.end()){ //CASE-2// - //succ is missing in the map, first insert it into the map// - tailPair = createActiveTailsAsPair<Unit>(currentX, begin, true, NULL, - fractureHoles_); - hint = pred; ++hint; - hint = tailMap_.insert(hint, std::make_pair(begin, tailPair.second)); - - pfig = pred->second; - pfig_size = pfig->getPolyLineSize() + 2; - if(pfig_size >= vertexThreshold){ - //cut-off piece from [pred, pred1] , add [begin, pred1]// - pred1 = pred; ++pred1; - assert((pred1 != tailMap_.end()) && - ((pred1->second)->getOtherActiveTail() == pred->second)); - closePartialSimplePolygon(currentX, pred->second, pred1->second); - - //update: we need left edge between (begin, pred1->first)// - pred1->second = tailPair.first; - (tailPair.first)->pushCoordinate(pred1->first); - }else{ - //just join// - ActiveTail<Unit>::joinChains(tailPair.first, pfig, - true, outputPolygons_); - } - tailMap_.erase(pred); - }else if(succ != tailMap_.end() && pred == tailMap_.end()){ //CASE-3// - //pred is missing in the map, first insert it into the map// - hint = succ; ++hint; - hint = tailMap_.insert(hint, std::make_pair(end, (ActiveTail<Unit> *) NULL)); - pfig = succ->second; - pfig_size = pfig->getPolyLineSize() + 2; - if(pfig_size >= vertexThreshold){ - //this figure needs cutting here// - succ1 = succ; --succ1; - assert((succ1 != tailMap_.end()) && - (succ1->second == pfig->getOtherActiveTail())); - ppfig = succ1->second; - closePartialSimplePolygon(currentX, ppfig, pfig); - - //update: we need a left edge between (succ1->first, end)// - tailPair = createActiveTailsAsPair<Unit>(currentX, succ1->first, - true, NULL, fractureHoles_); - succ1->second = tailPair.second; - hint->second = tailPair.first; - (tailPair.first)->pushCoordinate(end); - }else{ - //no cutting needed// - hint->second = pfig; - pfig->pushCoordinate(currentX); - pfig->pushCoordinate(end); - } - tailMap_.erase(succ); - }else{ - //insert both pred and succ// - insertNewLeftEdgeIntoTailMap(currentX, begin, end, hint); - } - } - } - - template<bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>:: - updatePartialSimplePolygonsWithRightEdges(Unit currentX, - const std::vector<interval_data<Unit> > &rightEdges, size_t vertexThreshold) - { - - typename std::map<Unit, ActiveTail<Unit>* >::iterator succ, pred, hint; - std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> tailPair; - Unit begin, end; - size_t i = 0; - //If rightEdges is non-empty Then tailMap_ is non-empty // - assert(rightEdges.empty() || !tailMap_.empty() ); - - while( i < rightEdges.size() ){ - //find the interval in the tailMap which contains this interval// - pred = tailMap_.lower_bound(rightEdges[i].get(HIGH)); - assert(pred != tailMap_.end()); - succ = pred; --succ; - assert(pred != succ); - end = pred->first; begin = succ->first; - - //we now have a [begin, end] // - bool found_solid_opening = false; - bool erase_succ = true, erase_pred = true; - Unit solid_opening_begin = 0; - Unit solid_opening_end = 0; - size_t j = i+1; - ActiveTail<Unit> *pfig = succ->second; - ActiveTail<Unit> *ppfig = pred->second; - size_t partial_fig_size = pfig->getPolyLineSize(); - //Invariant:// - assert(succ->second && (pfig)->getOtherActiveTail() == ppfig); - - hint = succ; - Unit key = rightEdges[i].get(LOW); - if(begin != key){ - found_solid_opening = true; - solid_opening_begin = begin; solid_opening_end = key; - } - - while(j < rightEdges.size() && rightEdges[j].get(HIGH) <= end){ - if(rightEdges[j-1].get(HIGH) != rightEdges[j].get(LOW)){ - if(!found_solid_opening){ - found_solid_opening = true; - solid_opening_begin = rightEdges[j-1].get(HIGH); - solid_opening_end = rightEdges[j].get(LOW); - }else{ - ++hint; - insertNewLeftEdgeIntoTailMap(currentX, - rightEdges[j-1].get(HIGH), rightEdges[j].get(LOW), hint); - } - } - j++; - } - - //trailing edge// - if(end != rightEdges[j-1].get(HIGH)){ - if(!found_solid_opening){ - found_solid_opening = true; - solid_opening_begin = rightEdges[j-1].get(HIGH); solid_opening_end = end; - }else{ - // a solid opening has been found already, we need to insert a new left - // between [rightEdges[j-1].get(HIGH), end] - Unit lbegin = rightEdges[j-1].get(HIGH); - tailPair = createActiveTailsAsPair<Unit>(currentX, lbegin, true, NULL, - fractureHoles_); - hint = tailMap_.insert(pred, std::make_pair(lbegin, tailPair.second)); - pred->second = tailPair.first; - (tailPair.first)->pushCoordinate(end); - erase_pred = false; - } - } - - size_t vertex_delta = ((begin != solid_opening_begin) && - (end != solid_opening_end)) ? 4 : 2; - - if(!found_solid_opening){ - //just close the figure, TODO: call closePartialPolygon// - pfig->pushCoordinate(currentX); - ActiveTail<Unit>::joinChains(pfig, ppfig, false, outputPolygons_); - hint = pred; ++hint; - }else if(partial_fig_size+vertex_delta >= vertexThreshold){ - //close the figure and add a pseudo left-edge// - closePartialSimplePolygon(currentX, pfig, ppfig); - assert(begin != solid_opening_begin || end != solid_opening_end); - - if(begin != solid_opening_begin && end != solid_opening_end){ - insertNewLeftEdgeIntoTailMap(currentX, solid_opening_begin, - solid_opening_end, hint); - }else if(begin == solid_opening_begin){ - //we just need to update the succ in the tailMap_// - tailPair = createActiveTailsAsPair<Unit>(currentX, solid_opening_begin, - true, NULL, fractureHoles_); - succ->second = tailPair.second; - hint = succ; ++hint; - hint = tailMap_.insert(pred, std::make_pair(solid_opening_end, - tailPair.first)); - (tailPair.first)->pushCoordinate(solid_opening_end); - erase_succ = false; - }else{ - //we just need to update the pred in the tailMap_// - tailPair = createActiveTailsAsPair<Unit>(currentX, solid_opening_begin, - true, NULL, fractureHoles_); - hint = tailMap_.insert(pred, std::make_pair(solid_opening_begin, - tailPair.second)); - pred->second = tailPair.first; - (tailPair.first)->pushCoordinate(solid_opening_end); - erase_pred = false; - } - }else{ - //continue the figure (by adding at-most two new vertices)// - if(begin != solid_opening_begin){ - pfig->pushCoordinate(currentX); - pfig->pushCoordinate(solid_opening_begin); - //insert solid_opening_begin// - hint = succ; ++hint; - hint = tailMap_.insert(hint, std::make_pair(solid_opening_begin, pfig)); - }else{ - erase_succ = false; - } - - if(end != solid_opening_end){ - std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> tailPair = - createActiveTailsAsPair<Unit>(currentX, solid_opening_end, false, - NULL, fractureHoles_); - hint = pred; ++hint; - hint = tailMap_.insert(hint, std::make_pair(solid_opening_end, - tailPair.second)); - ActiveTail<Unit>::joinChains(tailPair.first, ppfig, false, - outputPolygons_); - }else{ - erase_pred = false; - } - } - - //Remove the pred and succ if necessary// - if(erase_succ){ - tailMap_.erase(succ); - } - if(erase_pred){ - tailMap_.erase(pred); - } - i = j; - } - } - - // Maintains the following invariant: - // a. All the partial polygons formed at any state can be closed - // by a single edge. - template<bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>:: - maintainPartialSimplePolygonInvariant(iterator& beginOutput, - iterator& endOutput, Unit currentX, const std::vector<interval_data<Unit> >& l, - const std::vector<interval_data<Unit> >& r, size_t vertexThreshold) { - - clearOutput_(); - if(!l.empty()){ - updatePartialSimplePolygonsWithLeftEdges(currentX, l, vertexThreshold); - } - - if(!r.empty()){ - updatePartialSimplePolygonsWithRightEdges(currentX, r, vertexThreshold); - } - beginOutput = outputPolygons_.begin(); - endOutput = outputPolygons_.end(); - - } - - //Process edges connects vertical input edges (right or left edges of figures) to horizontal edges stored as member - //data of the scanline object. It also creates now horizontal edges as needed to construct figures from edge data. - // - //There are only 12 geometric end cases where the scanline intersects a horizontal edge and even fewer unique - //actions to take: - // 1. Solid on both sides of the vertical partition after the current position and space on both sides before - // ###|### - // ###|### - // | - // | - // This case does not need to be handled because there is no vertical edge at the current x coordinate. - // - // 2. Solid on both sides of the vertical partition before the current position and space on both sides after - // | - // | - // ###|### - // ###|### - // This case does not need to be handled because there is no vertical edge at the current x coordinate. - // - // 3. Solid on the left of the vertical partition after the current position and space elsewhere - // ###| - // ###| - // | - // | - // The horizontal edge from the left is found and turns upward because of the vertical right edge to become - // the currently active vertical edge. - // - // 4. Solid on the left of the vertical partion before the current position and space elsewhere - // | - // | - // ###| - // ###| - // The horizontal edge from the left is found and joined to the currently active vertical edge. - // - // 5. Solid to the right above and below and solid to the left above current position. - // ###|### - // ###|### - // |### - // |### - // The horizontal edge from the left is found and joined to the currently active vertical edge, - // potentially closing a hole. - // - // 6. Solid on the left of the vertical partion before the current position and solid to the right above and below - // |### - // |### - // ###|### - // ###|### - // The horizontal edge from the left is found and turns upward because of the vertical right edge to become - // the currently active vertical edge. - // - // 7. Solid on the right of the vertical partition after the current position and space elsewhere - // |### - // |### - // | - // | - // Create two new ActiveTails, one is added to the horizontal edges and the other becomes the vertical currentTail - // - // 8. Solid on the right of the vertical partion before the current position and space elsewhere - // | - // | - // |### - // |### - // The currentTail vertical edge turns right and is added to the horizontal edges data - // - // 9. Solid to the right above and solid to the left above and below current position. - // ###|### - // ###|### - // ###| - // ###| - // The currentTail vertical edge turns right and is added to the horizontal edges data - // - // 10. Solid on the left of the vertical partion above and below the current position and solid to the right below - // ###| - // ###| - // ###|### - // ###|### - // Create two new ActiveTails, one is added to the horizontal edges data and the other becomes the vertical currentTail - // - // 11. Solid to the right above and solid to the left below current position. - // |### - // |### - // ###| - // ###| - // The currentTail vertical edge joins the horizontal edge from the left (may close a polygon) - // Create two new ActiveTails, one is added to the horizontal edges data and the other becomes the vertical currentTail - // - // 12. Solid on the left of the vertical partion above the current position and solid to the right below - // ###| - // ###| - // |### - // |### - // The currentTail vertical edge turns right and is added to the horizontal edges data. - // The horizontal edge from the left turns upward and becomes the currentTail vertical edge - // - template <bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>:: - processEdges(iterator& beginOutput, iterator& endOutput, - Unit currentX, std::vector<interval_data<Unit> >& leftEdges, - std::vector<interval_data<Unit> >& rightEdges, - size_t vertexThreshold) { - clearOutput_(); - typename std::map<Unit, ActiveTail<Unit>*>::iterator nextMapItr; - //foreach edge - unsigned int leftIndex = 0; - unsigned int rightIndex = 0; - bool bottomAlreadyProcessed = false; - ActiveTail<Unit>* currentTail = 0; - const Unit UnitMax = (std::numeric_limits<Unit>::max)(); - - if(vertexThreshold < (std::numeric_limits<size_t>::max)()){ - maintainPartialSimplePolygonInvariant(beginOutput, endOutput, currentX, - leftEdges, rightEdges, vertexThreshold); - return; - } - - nextMapItr = tailMap_.begin(); - while(leftIndex < leftEdges.size() || rightIndex < rightEdges.size()) { - interval_data<Unit> edges[2] = {interval_data<Unit> (UnitMax, UnitMax), - interval_data<Unit> (UnitMax, UnitMax)}; - bool haveNextEdge = true; - if(leftIndex < leftEdges.size()) - edges[0] = leftEdges[leftIndex]; - else - haveNextEdge = false; - if(rightIndex < rightEdges.size()) - edges[1] = rightEdges[rightIndex]; - else - haveNextEdge = false; - bool trailingEdge = edges[1].get(LOW) < edges[0].get(LOW); - interval_data<Unit> & edge = edges[trailingEdge]; - interval_data<Unit> & nextEdge = edges[!trailingEdge]; - //process this edge - if(!bottomAlreadyProcessed) { - //assert currentTail = 0 - - //process the bottom end of this edge - typename std::map<Unit, ActiveTail<Unit>*>::iterator thisMapItr = findAtNext(tailMap_, nextMapItr, edge.get(LOW)); - if(thisMapItr != tailMap_.end()) { - //there is an edge in the map at the low end of this edge - //it needs to turn upward and become the current tail - ActiveTail<Unit>* tail = thisMapItr->second; - if(currentTail) { - //stitch currentTail into this tail - currentTail = tail->addHole(currentTail, fractureHoles_); - if(!fractureHoles_) - currentTail->pushCoordinate(currentX); - } else { - currentTail = tail; - currentTail->pushCoordinate(currentX); - } - //assert currentTail->getOrient() == VERTICAL - nextMapItr = thisMapItr; //set nextMapItr to the next position after this one - ++nextMapItr; - //remove thisMapItr from the map - tailMap_.erase(thisMapItr); - } else { - //there is no edge in the map at the low end of this edge - //we need to create one and another one to be the current vertical tail - //if this is a trailing edge then there is space to the right of the vertical edge - //so pass the inverse of trailingEdge to indicate solid to the right - std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> tailPair = - createActiveTailsAsPair(currentX, edge.get(LOW), !trailingEdge, currentTail, fractureHoles_); - currentTail = tailPair.first; - tailMap_.insert(nextMapItr, std::pair<Unit, ActiveTail<Unit>*>(edge.get(LOW), tailPair.second)); - // leave nextMapItr unchanged - } - - } - if(haveNextEdge && edge.get(HIGH) == nextEdge.get(LOW)) { - //the top of this edge is equal to the bottom of the next edge, process them both - bottomAlreadyProcessed = true; - typename std::map<Unit, ActiveTail<Unit>*>::iterator thisMapItr = findAtNext(tailMap_, nextMapItr, edge.get(HIGH)); - if(thisMapItr == tailMap_.end()) //assert this should never happen - return; - if(trailingEdge) { - //geometry at this position - // |## - // |## - // ----- - // ##| - // ##| - //current tail should join thisMapItr tail - ActiveTail<Unit>* tail = thisMapItr->second; - //pass false because they are being joined because space is to the right and it will close a solid figure - ActiveTail<Unit>::joinChains(currentTail, tail, false, outputPolygons_); - //two new tails are created, the vertical becomes current tail, the horizontal becomes thisMapItr tail - //pass true becuase they are created at the lower left corner of some solid - //pass null because there is no hole pointer possible - std::pair<ActiveTail<Unit>*, ActiveTail<Unit>*> tailPair = - createActiveTailsAsPair<Unit>(currentX, edge.get(HIGH), true, 0, fractureHoles_); - currentTail = tailPair.first; - thisMapItr->second = tailPair.second; - } else { - //geometry at this position - // ##| - // ##| - // ----- - // |## - // |## - //current tail should turn right - currentTail->pushCoordinate(edge.get(HIGH)); - //thisMapItr tail should turn up - thisMapItr->second->pushCoordinate(currentX); - //thisMapItr tail becomes current tail and current tail becomes thisMapItr tail - std::swap(currentTail, thisMapItr->second); - } - nextMapItr = thisMapItr; //set nextMapItr to the next position after this one - ++nextMapItr; - } else { - //there is a gap between the top of this edge and the bottom of the next, process the top of this edge - bottomAlreadyProcessed = false; - //process the top of this edge - typename std::map<Unit, ActiveTail<Unit>*>::iterator thisMapItr = findAtNext(tailMap_, nextMapItr, edge.get(HIGH)); - if(thisMapItr != tailMap_.end()) { - //thisMapItr is pointing to a horizontal edge in the map at the top of this vertical edge - //we need to join them and potentially close a figure - //assert currentTail != 0 - ActiveTail<Unit>* tail = thisMapItr->second; - //pass the opositve of trailing edge to mean that they are joined because of solid to the right - currentTail = ActiveTail<Unit>::joinChains(currentTail, tail, !trailingEdge, outputPolygons_); - nextMapItr = thisMapItr; //set nextMapItr to the next position after this one - ++nextMapItr; - if(currentTail) { //figure is not closed// - Unit nextItrY = UnitMax; - if(nextMapItr != tailMap_.end()) { - nextItrY = nextMapItr->first; - } - //for it to be a hole this must have been a left edge - Unit leftY = UnitMax; - if(leftIndex + 1 < leftEdges.size()) - leftY = leftEdges[leftIndex+1].get(LOW); - Unit rightY = nextEdge.get(LOW); - if(!haveNextEdge || (nextItrY < leftY && nextItrY < rightY)) { - //we need to add it to the next edge above it in the map - tail = nextMapItr->second; - tail = tail->addHole(currentTail, fractureHoles_); - if(fractureHoles_) { - //some small additional work stitching in the filament - tail->pushCoordinate(nextItrY); - nextMapItr->second = tail; - } - //set current tail to null - currentTail = 0; - } - } - //delete thisMapItr from the map - tailMap_.erase(thisMapItr); - } else { - //currentTail must turn right and be added into the map - currentTail->pushCoordinate(edge.get(HIGH)); - //assert currentTail->getOrient() == HORIZONTAL - tailMap_.insert(nextMapItr, std::pair<Unit, ActiveTail<Unit>*>(edge.get(HIGH), currentTail)); - //set currentTail to null - currentTail = 0; - //leave nextMapItr unchanged, it is still next - } - } - - //increment index - leftIndex += !trailingEdge; - rightIndex += trailingEdge; - } //end while - beginOutput = outputPolygons_.begin(); - endOutput = outputPolygons_.end(); - } //end function - - template<bool orientT, typename Unit, typename polygon_concept_type> - inline void ScanLineToPolygonItrs<orientT, Unit, polygon_concept_type>::clearOutput_() { - for(std::size_t i = 0; i < outputPolygons_.size(); ++i) { - ActiveTail<Unit>* at1 = outputPolygons_[i].yield(); - const std::list<ActiveTail<Unit>*>& holes = at1->getHoles(); - for(typename std::list<ActiveTail<Unit>*>::const_iterator litr = holes.begin(); litr != holes.end(); ++litr) { - //delete the hole - (*litr)->destroyContents(); - destroyActiveTail((*litr)->getOtherActiveTail()); - destroyActiveTail((*litr)); - } - //delete the polygon - at1->destroyContents(); - //at2 contents are the same as at1, so it should not destroy them - destroyActiveTail((at1)->getOtherActiveTail()); - destroyActiveTail(at1); - } - outputPolygons_.clear(); - } - -} //polygon_formation namespace - - template <bool orientT, typename Unit> - struct geometry_concept<polygon_formation::PolyLinePolygonWithHolesData<orientT, Unit> > { - typedef polygon_90_with_holes_concept type; - }; - - template <bool orientT, typename Unit> - struct geometry_concept<polygon_formation::PolyLineHoleData<orientT, Unit> > { - typedef polygon_90_concept type; - }; - - //public API to access polygon formation algorithm - template <typename output_container, typename iterator_type, typename concept_type> - unsigned int get_polygons(output_container& container, - iterator_type begin, iterator_type end, orientation_2d orient, - bool fracture_holes, concept_type, - size_t sliceThreshold = (std::numeric_limits<size_t>::max)() ) { - typedef typename output_container::value_type polygon_type; - typedef typename std::iterator_traits<iterator_type>::value_type::first_type coordinate_type; - polygon_type poly; - unsigned int countPolygons = 0; - typedef typename geometry_concept<polygon_type>::type polygon_concept_type; - polygon_formation::ScanLineToPolygonItrs<true, coordinate_type, polygon_concept_type> scanlineToPolygonItrsV(fracture_holes); - polygon_formation::ScanLineToPolygonItrs<false, coordinate_type, polygon_concept_type> scanlineToPolygonItrsH(fracture_holes); - std::vector<interval_data<coordinate_type> > leftEdges; - std::vector<interval_data<coordinate_type> > rightEdges; - coordinate_type prevPos = (std::numeric_limits<coordinate_type>::max)(); - coordinate_type prevY = (std::numeric_limits<coordinate_type>::max)(); - int count = 0; - for(iterator_type itr = begin; - itr != end; ++ itr) { - coordinate_type pos = (*itr).first; - if(pos != prevPos) { - if(orient == VERTICAL) { - typename polygon_formation::ScanLineToPolygonItrs<true, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsV.processEdges(itrPoly, itrPolyEnd, prevPos, - leftEdges, rightEdges, sliceThreshold); - for( ; itrPoly != itrPolyEnd; ++ itrPoly) { - ++countPolygons; - assign(poly, *itrPoly); - container.insert(container.end(), poly); - } - } else { - typename polygon_formation::ScanLineToPolygonItrs<false, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsH.processEdges(itrPoly, itrPolyEnd, prevPos, - leftEdges, rightEdges, sliceThreshold); - for( ; itrPoly != itrPolyEnd; ++ itrPoly) { - ++countPolygons; - assign(poly, *itrPoly); - container.insert(container.end(), poly); - } - } - leftEdges.clear(); - rightEdges.clear(); - prevPos = pos; - prevY = (*itr).second.first; - count = (*itr).second.second; - continue; - } - coordinate_type y = (*itr).second.first; - if(count != 0 && y != prevY) { - std::pair<interval_data<coordinate_type>, int> element(interval_data<coordinate_type>(prevY, y), count); - if(element.second == 1) { - if(leftEdges.size() && leftEdges.back().high() == element.first.low()) { - encompass(leftEdges.back(), element.first); - } else { - leftEdges.push_back(element.first); - } - } else { - if(rightEdges.size() && rightEdges.back().high() == element.first.low()) { - encompass(rightEdges.back(), element.first); - } else { - rightEdges.push_back(element.first); - } - } - - } - prevY = y; - count += (*itr).second.second; - } - if(orient == VERTICAL) { - typename polygon_formation::ScanLineToPolygonItrs<true, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsV.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges, sliceThreshold); - for( ; itrPoly != itrPolyEnd; ++ itrPoly) { - ++countPolygons; - assign(poly, *itrPoly); - container.insert(container.end(), poly); - } - } else { - typename polygon_formation::ScanLineToPolygonItrs<false, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsH.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges, sliceThreshold); - - for( ; itrPoly != itrPolyEnd; ++ itrPoly) { - ++countPolygons; - assign(poly, *itrPoly); - container.insert(container.end(), poly); - } - } - return countPolygons; - } - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_set_view.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_set_view.hpp deleted file mode 100644 index 7d2709141c..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_set_view.hpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - 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_POLYGON_SET_VIEW_HPP -#define BOOST_POLYGON_POLYGON_SET_VIEW_HPP -namespace boost { namespace polygon{ - - - template <typename coordinate_type> - inline void polygon_set_data<coordinate_type>::clean() const { - if(dirty_) { - //polygon_45_set_data<coordinate_type> tmp; - //very important: - //the 45 degree algorithm does not satisfy - //the precondition of arbitrary polygon formation - //that vertices be "linearly consistent" - //therefore it doesn't work to fall back on 45-degree - //booleans for arbitrary angle polygons - //if(0) { //downcast(tmp) ) { - // tmp.clean(); - // data_.clear(); - // is_45_ = true; - // polygon_set_data<coordinate_type> tmp2; - // tmp2.insert(tmp); - // data_.swap(tmp2.data_); - // dirty_ = false; - // sort(); - //} else { - sort(); - arbitrary_boolean_op<coordinate_type> abo; - polygon_set_data<coordinate_type> tmp2; - abo.execute(tmp2, begin(), end(), end(), end(), 0); - data_.swap(tmp2.data_); - is_45_ = tmp2.is_45_; - dirty_ = false; - //} - } - } - - template <> - inline void polygon_set_data<double>::clean() const { - if(dirty_) { - sort(); - arbitrary_boolean_op<double> abo; - polygon_set_data<double> tmp2; - abo.execute(tmp2, begin(), end(), end(), end(), 0); - data_.swap(tmp2.data_); - is_45_ = tmp2.is_45_; - dirty_ = false; - } - } - - template <typename value_type, typename arg_type> - inline void insert_into_view_arg(value_type& dest, const arg_type& arg); - - template <typename ltype, typename rtype, int op_type> - class polygon_set_view; - - template <typename ltype, typename rtype, int op_type> - struct polygon_set_traits<polygon_set_view<ltype, rtype, op_type> > { - typedef typename polygon_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type; - typedef typename polygon_set_view<ltype, rtype, op_type>::iterator_type iterator_type; - typedef typename polygon_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type; - - static inline iterator_type begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set); - static inline iterator_type end(const polygon_set_view<ltype, rtype, op_type>& polygon_set); - - static inline bool clean(const polygon_set_view<ltype, rtype, op_type>& polygon_set); - - static inline bool sort(const polygon_set_view<ltype, rtype, op_type>& polygon_set); - }; - - //template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type> - //void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_, - // double coord) { - // typedef geometry_type_1 ltype; - // typedef geometry_type_2 rtype; - // typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; - // value_type linput_; - // value_type rinput_; - // insert_into_view_arg(linput_, lvalue_); - // insert_into_view_arg(rinput_, rvalue_); - // arbitrary_boolean_op<coordinate_type> abo; - // abo.execute(output_, linput_.begin(), linput_.end(), - // rinput_.begin(), rinput_.end(), op_type); - //} - - template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type> - void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { - typedef geometry_type_1 ltype; - //typedef geometry_type_2 rtype; - typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; - value_type linput_; - value_type rinput_; - insert_into_view_arg(linput_, lvalue_); - insert_into_view_arg(rinput_, rvalue_); - polygon_45_set_data<coordinate_type> l45, r45, o45; -// if(linput_.downcast(l45) && rinput_.downcast(r45)) { -// //the op codes are screwed up between 45 and arbitrary -//#ifdef BOOST_POLYGON_MSVC -//#pragma warning (push) -//#pragma warning (disable: 4127) -//#endif -// if(op_type < 2) -// l45.template applyAdaptiveBoolean_<op_type>(o45, r45); -// else if(op_type == 2) -// l45.template applyAdaptiveBoolean_<3>(o45, r45); -// else -// l45.template applyAdaptiveBoolean_<2>(o45, r45); -//#ifdef BOOST_POLYGON_MSVC -//#pragma warning (pop) -//#endif -// output_.insert(o45); -// } else { - arbitrary_boolean_op<coordinate_type> abo; - abo.execute(output_, linput_.begin(), linput_.end(), - rinput_.begin(), rinput_.end(), op_type); -// } - } - - template <typename ltype, typename rtype, int op_type> - class polygon_set_view { - public: - typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; - typedef polygon_set_data<coordinate_type> value_type; - typedef typename value_type::iterator_type iterator_type; - typedef polygon_set_view operator_arg_type; - private: - const ltype& lvalue_; - const rtype& rvalue_; - mutable value_type output_; - mutable bool evaluated_; - polygon_set_view& operator=(const polygon_set_view&); - public: - polygon_set_view(const ltype& lvalue, - const rtype& rvalue ) : - lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {} - - // get iterator to begin vertex data - public: - const value_type& value() const { - if(!evaluated_) { - evaluated_ = true; - execute_boolean_op<value_type, ltype, rtype, op_type>(output_, lvalue_, rvalue_); - } - return output_; - } - public: - iterator_type begin() const { return value().begin(); } - iterator_type end() const { return value().end(); } - - bool dirty() const { return false; } //result of a boolean is clean - bool sorted() const { return true; } //result of a boolean is sorted - - void sort() const {} //is always sorted - }; - - template <typename ltype, typename rtype, int op_type> - typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type - polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: - begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set) { - return polygon_set.begin(); - } - template <typename ltype, typename rtype, int op_type> - typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type - polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: - end(const polygon_set_view<ltype, rtype, op_type>& polygon_set) { - return polygon_set.end(); - } - template <typename ltype, typename rtype, int op_type> - bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: - clean(const polygon_set_view<ltype, rtype, op_type>& ) { - return true; } - template <typename ltype, typename rtype, int op_type> - bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >:: - sort(const polygon_set_view<ltype, rtype, op_type>& ) { - return true; } - - template <typename value_type, typename arg_type> - inline void insert_into_view_arg(value_type& dest, const arg_type& arg) { - typedef typename polygon_set_traits<arg_type>::iterator_type literator; - literator itr1, itr2; - itr1 = polygon_set_traits<arg_type>::begin(arg); - itr2 = polygon_set_traits<arg_type>::end(arg); - dest.insert(itr1, itr2); - } - - template <typename geometry_type_1, typename geometry_type_2, int op_type> - geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { - typedef geometry_type_1 ltype; - typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type; - typedef polygon_set_data<coordinate_type> value_type; - value_type output_; - execute_boolean_op<value_type, geometry_type_1, geometry_type_2, op_type>(output_, lvalue_, rvalue_); - polygon_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end()); - return lvalue_; - } - - // copy constructor - template <typename coordinate_type> - template <typename ltype, typename rtype, int op_type> - polygon_set_data<coordinate_type>::polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that) : - data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {} - - // equivalence operator - template <typename coordinate_type> - inline bool polygon_set_data<coordinate_type>::operator==(const polygon_set_data<coordinate_type>& p) const { - typedef polygon_set_data<coordinate_type> value_type; - value_type output_; - execute_boolean_op<value_type, value_type, value_type, 2>(output_, (*this), p); - return output_.data_.empty(); - } - - template <typename ltype, typename rtype, int op_type> - struct geometry_concept<polygon_set_view<ltype, rtype, op_type> > { typedef polygon_set_concept type; }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_simplify.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_simplify.hpp deleted file mode 100644 index 4871f507e4..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_simplify.hpp +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2011, Andrew Ross -// -// 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_DETAIL_SIMPLIFY_HPP -#define BOOST_POLYGON_DETAIL_SIMPLIFY_HPP -#include <vector> - -namespace boost { namespace polygon { namespace detail { namespace simplify_detail { - - // Does a simplification/optimization pass on the polygon. If a given - // vertex lies within "len" of the line segment joining its neighbor - // vertices, it is removed. - template <typename T> //T is a model of point concept - std::size_t simplify(std::vector<T>& dst, const std::vector<T>& src, - typename coordinate_traits< - typename point_traits<T>::coordinate_type - >::coordinate_distance len) - { - using namespace boost::polygon; - typedef typename point_traits<T>::coordinate_type coordinate_type; - typedef typename coordinate_traits<coordinate_type>::area_type ftype; - typedef typename std::vector<T>::const_iterator iter; - - std::vector<T> out; - out.reserve(src.size()); - dst = src; - std::size_t final_result = 0; - std::size_t orig_size = src.size(); - - //I can't use == if T doesn't provide it, so use generic point concept compare - bool closed = equivalence(src.front(), src.back()); - - //we need to keep smoothing until we don't find points to remove - //because removing points in the first iteration through the - //polygon may leave it in a state where more removal is possible - bool not_done = true; - while(not_done) { - if(dst.size() < 3) { - dst.clear(); - return orig_size; - } - - // Start with the second, test for the last point - // explicitly, and exit after looping back around to the first. - ftype len2 = ftype(len) * ftype(len); - for(iter prev=dst.begin(), i=prev+1, next; /**/; i = next) { - next = i+1; - if(next == dst.end()) - next = dst.begin(); - - // points A, B, C - ftype ax = x(*prev), ay = y(*prev); - ftype bx = x(*i), by = y(*i); - ftype cx = x(*next), cy = y(*next); - - // vectors AB, BC and AC: - ftype abx = bx-ax, aby = by-ay; - ftype bcx = cx-bx, bcy = cy-by; - ftype acx = cx-ax, acy = cy-ay; - - // dot products - ftype ab_ab = abx*abx + aby*aby; - ftype bc_bc = bcx*bcx + bcy*bcy; - ftype ac_ac = acx*acx + acy*acy; - ftype ab_ac = abx*acx + aby*acy; - - // projection of AB along AC - ftype projf = ab_ac / ac_ac; - ftype projx = acx * projf, projy = acy * projf; - - // perpendicular vector from the line AC to point B (i.e. AB - proj) - ftype perpx = abx - projx, perpy = aby - projy; - - // Squared fractional distance of projection. FIXME: can - // remove this division, the decisions below can be made with - // just the sign of the quotient and a check to see if - // abs(numerator) is greater than abs(divisor). - ftype f2 = (projx*acx + projy*acx) / ac_ac; - - // Square of the relevant distance from point B: - ftype dist2; - if (f2 < 0) dist2 = ab_ab; - else if(f2 > 1) dist2 = bc_bc; - else dist2 = perpx*perpx + perpy*perpy; - - if(dist2 > len2) { - prev = i; // bump prev, we didn't remove the segment - out.push_back(*i); - } - - if(i == dst.begin()) - break; - } - std::size_t result = dst.size() - out.size(); - if(result == 0) { - not_done = false; - } else { - final_result += result; - dst = out; - out.clear(); - } - } //end of while loop - if(closed) { - //if the input was closed we want the output to be closed - --final_result; - dst.push_back(dst.front()); - } - return final_result; - } - - -}}}} - -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/polygon_sort_adaptor.hpp b/contrib/restricted/boost/boost/polygon/detail/polygon_sort_adaptor.hpp deleted file mode 100644 index b3561f87d0..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/polygon_sort_adaptor.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - 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_SORT_ADAPTOR_HPP -#define BOOST_POLYGON_SORT_ADAPTOR_HPP -#ifdef __ICC -#pragma warning(disable:2022) -#pragma warning(disable:2023) -#endif - -#include <algorithm> - -//! @brief polygon_sort_adaptor default implementation that calls std::sort -namespace boost { - namespace polygon { - - template<typename iterator_type> - struct dummy_to_delay_instantiation{ - typedef int unit_type; // default GTL unit - }; - - //! @brief polygon_sort_adaptor default implementation that calls std::sort - template<typename T> - struct polygon_sort_adaptor { - //! @brief wrapper that mimics std::sort() function and takes - // the same arguments - template<typename RandomAccessIterator_Type> - static void sort(RandomAccessIterator_Type _First, - RandomAccessIterator_Type _Last) - { - std::sort(_First, _Last); - } - //! @brief wrapper that mimics std::sort() function overload and takes - // the same arguments - template<typename RandomAccessIterator_Type, typename Pred_Type> - static void sort(RandomAccessIterator_Type _First, - RandomAccessIterator_Type _Last, - const Pred_Type& _Comp) - { - std::sort(_First, _Last, _Comp); - } - }; - - //! @brief user level wrapper for sorting quantities - template <typename iter_type> - void polygon_sort(iter_type _b_, iter_type _e_) - { - polygon_sort_adaptor<typename dummy_to_delay_instantiation<iter_type>::unit_type>::sort(_b_, _e_); - } - - //! @brief user level wrapper for sorting quantities that takes predicate - // as additional argument - template <typename iter_type, typename pred_type> - void polygon_sort(iter_type _b_, iter_type _e_, const pred_type& _pred_) - { - polygon_sort_adaptor<typename dummy_to_delay_instantiation<iter_type>::unit_type>::sort(_b_, _e_, _pred_); - } - - - - } // namespace polygon -} // namespace boost -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/property_merge.hpp b/contrib/restricted/boost/boost/polygon/detail/property_merge.hpp deleted file mode 100644 index 6ea0161b05..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/property_merge.hpp +++ /dev/null @@ -1,588 +0,0 @@ -/* - 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_PROPERTY_MERGE_HPP -#define BOOST_POLYGON_PROPERTY_MERGE_HPP -namespace boost { namespace polygon{ - -template <typename coordinate_type> -class property_merge_point { -private: - coordinate_type x_, y_; -public: - inline property_merge_point() : x_(), y_() {} - inline property_merge_point(coordinate_type x, coordinate_type y) : x_(x), y_(y) {} - //use builtin assign and copy - inline bool operator==(const property_merge_point& that) const { return x_ == that.x_ && y_ == that.y_; } - inline bool operator!=(const property_merge_point& that) const { return !((*this) == that); } - inline bool operator<(const property_merge_point& that) const { - if(x_ < that.x_) return true; - if(x_ > that.x_) return false; - return y_ < that.y_; - } - inline coordinate_type x() const { return x_; } - inline coordinate_type y() const { return y_; } - inline void x(coordinate_type value) { x_ = value; } - inline void y(coordinate_type value) { y_ = value; } -}; - -template <typename coordinate_type> -class property_merge_interval { -private: - coordinate_type low_, high_; -public: - inline property_merge_interval() : low_(), high_() {} - inline property_merge_interval(coordinate_type low, coordinate_type high) : low_(low), high_(high) {} - //use builtin assign and copy - inline bool operator==(const property_merge_interval& that) const { return low_ == that.low_ && high_ == that.high_; } - inline bool operator!=(const property_merge_interval& that) const { return !((*this) == that); } - inline bool operator<(const property_merge_interval& that) const { - if(low_ < that.low_) return true; - if(low_ > that.low_) return false; - return high_ < that.high_; - } - inline coordinate_type low() const { return low_; } - inline coordinate_type high() const { return high_; } - inline void low(coordinate_type value) { low_ = value; } - inline void high(coordinate_type value) { high_ = value; } -}; - -template <typename coordinate_type, typename property_type, typename polygon_set_type, typename keytype = std::set<property_type> > -class merge_scanline { -public: - //definitions - - typedef keytype property_set; - typedef std::vector<std::pair<property_type, int> > property_map; - typedef std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > vertex_property; - typedef std::pair<property_merge_point<coordinate_type>, property_map> vertex_data; - typedef std::vector<vertex_property> property_merge_data; - //typedef std::map<property_set, polygon_set_type> Result; - typedef std::map<coordinate_type, property_map> scanline_type; - typedef typename scanline_type::iterator scanline_iterator; - typedef std::pair<property_merge_interval<coordinate_type>, std::pair<property_set, property_set> > edge_property; - typedef std::vector<edge_property> edge_property_vector; - - //static public member functions - - template <typename iT, typename orientation_2d_type> - static inline void - populate_property_merge_data(property_merge_data& pmd, iT input_begin, iT input_end, - const property_type& property, orientation_2d_type orient) { - for( ; input_begin != input_end; ++input_begin) { - std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > element; - if(orient == HORIZONTAL) - element.first = property_merge_point<coordinate_type>((*input_begin).second.first, (*input_begin).first); - else - element.first = property_merge_point<coordinate_type>((*input_begin).first, (*input_begin).second.first); - element.second.first = property; - element.second.second = (*input_begin).second.second; - pmd.push_back(element); - } - } - - //public member functions - - merge_scanline() : output(), scanline(), currentVertex(), tmpVector(), previousY(), countFromBelow(), scanlinePosition() {} - merge_scanline(const merge_scanline& that) : - output(that.output), - scanline(that.scanline), - currentVertex(that.currentVertex), - tmpVector(that.tmpVector), - previousY(that.previousY), - countFromBelow(that.countFromBelow), - scanlinePosition(that.scanlinePosition) - {} - merge_scanline& operator=(const merge_scanline& that) { - output = that.output; - scanline = that.scanline; - currentVertex = that.currentVertex; - tmpVector = that.tmpVector; - previousY = that.previousY; - countFromBelow = that.countFromBelow; - scanlinePosition = that.scanlinePosition; - return *this; - } - - template <typename result_type> - inline void perform_merge(result_type& result, property_merge_data& data) { - if(data.empty()) return; - //sort - polygon_sort(data.begin(), data.end(), less_vertex_data<vertex_property>()); - //scanline - bool firstIteration = true; - scanlinePosition = scanline.end(); - for(std::size_t i = 0; i < data.size(); ++i) { - if(firstIteration) { - mergeProperty(currentVertex.second, data[i].second); - currentVertex.first = data[i].first; - firstIteration = false; - } else { - if(data[i].first != currentVertex.first) { - if(data[i].first.x() != currentVertex.first.x()) { - processVertex(output); - //std::cout << scanline.size() << " "; - countFromBelow.clear(); //should already be clear - writeOutput(currentVertex.first.x(), result, output); - currentVertex.second.clear(); - mergeProperty(currentVertex.second, data[i].second); - currentVertex.first = data[i].first; - //std::cout << assertRedundant(scanline) << "/" << scanline.size() << " "; - } else { - processVertex(output); - currentVertex.second.clear(); - mergeProperty(currentVertex.second, data[i].second); - currentVertex.first = data[i].first; - } - } else { - mergeProperty(currentVertex.second, data[i].second); - } - } - } - processVertex(output); - writeOutput(currentVertex.first.x(), result, output); - //std::cout << assertRedundant(scanline) << "/" << scanline.size() << "\n"; - //std::cout << scanline.size() << "\n"; - } - -private: - //private supporting types - - template <class T> - class less_vertex_data { - public: - less_vertex_data() {} - bool operator()(const T& lvalue, const T& rvalue) const { - if(lvalue.first.x() < rvalue.first.x()) return true; - if(lvalue.first.x() > rvalue.first.x()) return false; - if(lvalue.first.y() < rvalue.first.y()) return true; - return false; - } - }; - - template <typename T> - struct lessPropertyCount { - lessPropertyCount() {} - bool operator()(const T& a, const T& b) { - return a.first < b.first; - } - }; - - //private static member functions - - static inline void mergeProperty(property_map& lvalue, std::pair<property_type, int>& rvalue) { - typename property_map::iterator itr = std::lower_bound(lvalue.begin(), lvalue.end(), rvalue, - lessPropertyCount<std::pair<property_type, int> >()); - if(itr == lvalue.end() || - (*itr).first != rvalue.first) { - lvalue.insert(itr, rvalue); - } else { - (*itr).second += rvalue.second; - if((*itr).second == 0) - lvalue.erase(itr); - } -// if(assertSorted(lvalue)) { -// std::cout << "in mergeProperty\n"; -// exit(0); -// } - } - -// static inline bool assertSorted(property_map& pset) { -// bool result = false; -// for(std::size_t i = 1; i < pset.size(); ++i) { -// if(pset[i] < pset[i-1]) { -// std::cout << "Out of Order Error "; -// result = true; -// } -// if(pset[i].first == pset[i-1].first) { -// std::cout << "Duplicate Property Error "; -// result = true; -// } -// if(pset[0].second == 0 || pset[1].second == 0) { -// std::cout << "Empty Property Error "; -// result = true; -// } -// } -// return result; -// } - - static inline void setProperty(property_set& pset, property_map& pmap) { - for(typename property_map::iterator itr = pmap.begin(); itr != pmap.end(); ++itr) { - if((*itr).second > 0) { - pset.insert(pset.end(), (*itr).first); - } - } - } - - //private data members - - edge_property_vector output; - scanline_type scanline; - vertex_data currentVertex; - property_map tmpVector; - coordinate_type previousY; - property_map countFromBelow; - scanline_iterator scanlinePosition; - - //private member functions - - inline void mergeCount(property_map& lvalue, property_map& rvalue) { - typename property_map::iterator litr = lvalue.begin(); - typename property_map::iterator ritr = rvalue.begin(); - tmpVector.clear(); - while(litr != lvalue.end() && ritr != rvalue.end()) { - if((*litr).first <= (*ritr).first) { - if(!tmpVector.empty() && - (*litr).first == tmpVector.back().first) { - tmpVector.back().second += (*litr).second; - } else { - tmpVector.push_back(*litr); - } - ++litr; - } else if((*ritr).first <= (*litr).first) { - if(!tmpVector.empty() && - (*ritr).first == tmpVector.back().first) { - tmpVector.back().second += (*ritr).second; - } else { - tmpVector.push_back(*ritr); - } - ++ritr; - } - } - while(litr != lvalue.end()) { - if(!tmpVector.empty() && - (*litr).first == tmpVector.back().first) { - tmpVector.back().second += (*litr).second; - } else { - tmpVector.push_back(*litr); - } - ++litr; - } - while(ritr != rvalue.end()) { - if(!tmpVector.empty() && - (*ritr).first == tmpVector.back().first) { - tmpVector.back().second += (*ritr).second; - } else { - tmpVector.push_back(*ritr); - } - ++ritr; - } - lvalue.clear(); - for(std::size_t i = 0; i < tmpVector.size(); ++i) { - if(tmpVector[i].second != 0) { - lvalue.push_back(tmpVector[i]); - } - } -// if(assertSorted(lvalue)) { -// std::cout << "in mergeCount\n"; -// exit(0); -// } - } - - inline void processVertex(edge_property_vector& output) { - if(!countFromBelow.empty()) { - //we are processing an interval of change in scanline state between - //previous vertex position and current vertex position where - //count from below represents the change on the interval - //foreach scanline element from previous to current we - //write the interval on the scanline that is changing - //the old value and the new value to output - property_merge_interval<coordinate_type> currentInterval(previousY, currentVertex.first.y()); - coordinate_type currentY = currentInterval.low(); - if(scanlinePosition == scanline.end() || - (*scanlinePosition).first != previousY) { - scanlinePosition = scanline.lower_bound(previousY); - } - scanline_iterator previousScanlinePosition = scanlinePosition; - ++scanlinePosition; - while(scanlinePosition != scanline.end()) { - coordinate_type elementY = (*scanlinePosition).first; - if(elementY <= currentInterval.high()) { - property_map& countOnLeft = (*previousScanlinePosition).second; - edge_property element; - output.push_back(element); - output.back().first = property_merge_interval<coordinate_type>((*previousScanlinePosition).first, elementY); - setProperty(output.back().second.first, countOnLeft); - mergeCount(countOnLeft, countFromBelow); - setProperty(output.back().second.second, countOnLeft); - if(output.back().second.first == output.back().second.second) { - output.pop_back(); //it was an internal vertical edge, not to be output - } - else if(output.size() > 1) { - edge_property& secondToLast = output[output.size()-2]; - if(secondToLast.first.high() == output.back().first.low() && - secondToLast.second.first == output.back().second.first && - secondToLast.second.second == output.back().second.second) { - //merge output onto previous output because properties are - //identical on both sides implying an internal horizontal edge - secondToLast.first.high(output.back().first.high()); - output.pop_back(); - } - } - if(previousScanlinePosition == scanline.begin()) { - if(countOnLeft.empty()) { - scanline.erase(previousScanlinePosition); - } - } else { - scanline_iterator tmpitr = previousScanlinePosition; - --tmpitr; - if((*tmpitr).second == (*previousScanlinePosition).second) - scanline.erase(previousScanlinePosition); - } - - } else if(currentY < currentInterval.high()){ - //elementY > currentInterval.high() - //split the interval between previous and current scanline elements - std::pair<coordinate_type, property_map> elementScan; - elementScan.first = currentInterval.high(); - elementScan.second = (*previousScanlinePosition).second; - scanlinePosition = scanline.insert(scanlinePosition, elementScan); - continue; - } else { - break; - } - previousScanlinePosition = scanlinePosition; - currentY = previousY = elementY; - ++scanlinePosition; - if(scanlinePosition == scanline.end() && - currentY < currentInterval.high()) { - //insert a new element for top of range - std::pair<coordinate_type, property_map> elementScan; - elementScan.first = currentInterval.high(); - scanlinePosition = scanline.insert(scanline.end(), elementScan); - } - } - if(scanlinePosition == scanline.end() && - currentY < currentInterval.high()) { - //handle case where we iterated to end of the scanline - //we need to insert an element into the scanline at currentY - //with property value coming from below - //and another one at currentInterval.high() with empty property value - mergeCount(scanline[currentY], countFromBelow); - std::pair<coordinate_type, property_map> elementScan; - elementScan.first = currentInterval.high(); - scanline.insert(scanline.end(), elementScan); - - edge_property element; - output.push_back(element); - output.back().first = property_merge_interval<coordinate_type>(currentY, currentInterval.high()); - setProperty(output.back().second.second, countFromBelow); - mergeCount(countFromBelow, currentVertex.second); - } else { - mergeCount(countFromBelow, currentVertex.second); - if(countFromBelow.empty()) { - if(previousScanlinePosition == scanline.begin()) { - if((*previousScanlinePosition).second.empty()) { - scanline.erase(previousScanlinePosition); - //previousScanlinePosition = scanline.end(); - //std::cout << "ERASE_A "; - } - } else { - scanline_iterator tmpitr = previousScanlinePosition; - --tmpitr; - if((*tmpitr).second == (*previousScanlinePosition).second) { - scanline.erase(previousScanlinePosition); - //previousScanlinePosition = scanline.end(); - //std::cout << "ERASE_B "; - } - } - } - } - } else { - //count from below is empty, we are starting a new interval of change - countFromBelow = currentVertex.second; - scanlinePosition = scanline.lower_bound(currentVertex.first.y()); - if(scanlinePosition != scanline.end()) { - if((*scanlinePosition).first != currentVertex.first.y()) { - if(scanlinePosition != scanline.begin()) { - //decrement to get the lower position of the first interval this vertex intersects - --scanlinePosition; - //insert a new element into the scanline for the incoming vertex - property_map& countOnLeft = (*scanlinePosition).second; - std::pair<coordinate_type, property_map> element(currentVertex.first.y(), countOnLeft); - scanlinePosition = scanline.insert(scanlinePosition, element); - } else { - property_map countOnLeft; - std::pair<coordinate_type, property_map> element(currentVertex.first.y(), countOnLeft); - scanlinePosition = scanline.insert(scanlinePosition, element); - } - } - } else { - property_map countOnLeft; - std::pair<coordinate_type, property_map> element(currentVertex.first.y(), countOnLeft); - scanlinePosition = scanline.insert(scanlinePosition, element); - } - } - previousY = currentVertex.first.y(); - } - - template <typename T> - inline int assertRedundant(T& t) { - if(t.empty()) return 0; - int count = 0; - typename T::iterator itr = t.begin(); - if((*itr).second.empty()) - ++count; - typename T::iterator itr2 = itr; - ++itr2; - while(itr2 != t.end()) { - if((*itr).second == (*itr2).second) - ++count; - itr = itr2; - ++itr2; - } - return count; - } - - template <typename T> - inline void performExtract(T& result, property_merge_data& data) { - if(data.empty()) return; - //sort - polygon_sort(data.begin(), data.end(), less_vertex_data<vertex_property>()); - - //scanline - bool firstIteration = true; - scanlinePosition = scanline.end(); - for(std::size_t i = 0; i < data.size(); ++i) { - if(firstIteration) { - mergeProperty(currentVertex.second, data[i].second); - currentVertex.first = data[i].first; - firstIteration = false; - } else { - if(data[i].first != currentVertex.first) { - if(data[i].first.x() != currentVertex.first.x()) { - processVertex(output); - //std::cout << scanline.size() << " "; - countFromBelow.clear(); //should already be clear - writeGraph(result, output, scanline); - currentVertex.second.clear(); - mergeProperty(currentVertex.second, data[i].second); - currentVertex.first = data[i].first; - } else { - processVertex(output); - currentVertex.second.clear(); - mergeProperty(currentVertex.second, data[i].second); - currentVertex.first = data[i].first; - } - } else { - mergeProperty(currentVertex.second, data[i].second); - } - } - } - processVertex(output); - writeGraph(result, output, scanline); - //std::cout << scanline.size() << "\n"; - } - - template <typename T> - inline void insertEdges(T& graph, property_set& p1, property_set& p2) { - for(typename property_set::iterator itr = p1.begin(); itr != p1.end(); ++itr) { - for(typename property_set::iterator itr2 = p2.begin(); itr2 != p2.end(); ++itr2) { - if(*itr != *itr2) { - graph[*itr].insert(*itr2); - graph[*itr2].insert(*itr); - } - } - } - } - - template <typename T> - inline void propertySetAbove(coordinate_type y, property_set& ps, T& scanline) { - ps.clear(); - typename T::iterator itr = scanline.find(y); - if(itr != scanline.end()) - setProperty(ps, (*itr).second); - } - - template <typename T> - inline void propertySetBelow(coordinate_type y, property_set& ps, T& scanline) { - ps.clear(); - typename T::iterator itr = scanline.find(y); - if(itr != scanline.begin()) { - --itr; - setProperty(ps, (*itr).second); - } - } - - template <typename T, typename T2> - inline void writeGraph(T& graph, edge_property_vector& output, T2& scanline) { - if(output.empty()) return; - edge_property* previousEdgeP = &(output[0]); - bool firstIteration = true; - property_set ps; - for(std::size_t i = 0; i < output.size(); ++i) { - edge_property& previousEdge = *previousEdgeP; - edge_property& edge = output[i]; - if(previousEdge.first.high() == edge.first.low()) { - //horizontal edge - insertEdges(graph, edge.second.first, previousEdge.second.first); - //corner 1 - insertEdges(graph, edge.second.first, previousEdge.second.second); - //other horizontal edge - insertEdges(graph, edge.second.second, previousEdge.second.second); - //corner 2 - insertEdges(graph, edge.second.second, previousEdge.second.first); - } else { - if(!firstIteration){ - //look up regions above previous edge - propertySetAbove(previousEdge.first.high(), ps, scanline); - insertEdges(graph, ps, previousEdge.second.first); - insertEdges(graph, ps, previousEdge.second.second); - } - //look up regions below current edge in the scanline - propertySetBelow(edge.first.high(), ps, scanline); - insertEdges(graph, ps, edge.second.first); - insertEdges(graph, ps, edge.second.second); - } - firstIteration = false; - //vertical edge - insertEdges(graph, edge.second.second, edge.second.first); - //shared region to left - insertEdges(graph, edge.second.second, edge.second.second); - //shared region to right - insertEdges(graph, edge.second.first, edge.second.first); - previousEdgeP = &(output[i]); - } - edge_property& previousEdge = *previousEdgeP; - propertySetAbove(previousEdge.first.high(), ps, scanline); - insertEdges(graph, ps, previousEdge.second.first); - insertEdges(graph, ps, previousEdge.second.second); - output.clear(); - } - - template <typename Result> - inline void writeOutput(coordinate_type x, Result& result, edge_property_vector& output) { - for(std::size_t i = 0; i < output.size(); ++i) { - edge_property& edge = output[i]; - //edge.second.first is the property set on the left of the edge - if(!edge.second.first.empty()) { - typename Result::iterator itr = result.find(edge.second.first); - if(itr == result.end()) { - std::pair<property_set, polygon_set_type> element(edge.second.first, polygon_set_type(VERTICAL)); - itr = result.insert(result.end(), element); - } - std::pair<interval_data<coordinate_type>, int> element2(interval_data<coordinate_type>(edge.first.low(), edge.first.high()), -1); //right edge of figure - (*itr).second.insert(x, element2); - } - if(!edge.second.second.empty()) { - //edge.second.second is the property set on the right of the edge - typename Result::iterator itr = result.find(edge.second.second); - if(itr == result.end()) { - std::pair<property_set, polygon_set_type> element(edge.second.second, polygon_set_type(VERTICAL)); - itr = result.insert(result.end(), element); - } - std::pair<interval_data<coordinate_type>, int> element3(interval_data<coordinate_type>(edge.first.low(), edge.first.high()), 1); //left edge of figure - (*itr).second.insert(x, element3); - } - } - output.clear(); - } -}; - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/property_merge_45.hpp b/contrib/restricted/boost/boost/polygon/detail/property_merge_45.hpp deleted file mode 100644 index c2feffc98f..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/property_merge_45.hpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - 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_PROPERTY_MERGE_45_HPP -#define BOOST_POLYGON_PROPERTY_MERGE_45_HPP -namespace boost { namespace polygon{ - - template <typename Unit, typename property_type> - struct polygon_45_property_merge { - - typedef point_data<Unit> Point; - typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit; - - template <typename property_map> - static inline void merge_property_maps(property_map& mp, const property_map& mp2, bool subtract = false) { - polygon_45_touch<Unit>::merge_property_maps(mp, mp2, subtract); - } - - class CountMerge { - public: - inline CountMerge() : counts() {} - //inline CountMerge(int count) { counts[0] = counts[1] = count; } - //inline CountMerge(int count1, int count2) { counts[0] = count1; counts[1] = count2; } - inline CountMerge(const CountMerge& count) : counts(count.counts) {} - inline bool operator==(const CountMerge& count) const { return counts == count.counts; } - inline bool operator!=(const CountMerge& count) const { return !((*this) == count); } - //inline CountMerge& operator=(int count) { counts[0] = counts[1] = count; return *this; } - inline CountMerge& operator=(const CountMerge& count) { counts = count.counts; return *this; } - inline int& operator[](property_type index) { - std::vector<std::pair<int, int> >::iterator itr = lower_bound(counts.begin(), counts.end(), std::make_pair(index, int(0))); - if(itr != counts.end() && itr->first == index) { - return itr->second; - } - itr = counts.insert(itr, std::make_pair(index, int(0))); - return itr->second; - } -// inline int operator[](int index) const { -// std::vector<std::pair<int, int> >::const_iterator itr = counts.begin(); -// for( ; itr != counts.end() && itr->first <= index; ++itr) { -// if(itr->first == index) { -// return itr->second; -// } -// } -// return 0; -// } - inline CountMerge& operator+=(const CountMerge& count){ - merge_property_maps(counts, count.counts, false); - return *this; - } - inline CountMerge& operator-=(const CountMerge& count){ - merge_property_maps(counts, count.counts, true); - return *this; - } - inline CountMerge operator+(const CountMerge& count) const { - return CountMerge(*this)+=count; - } - inline CountMerge operator-(const CountMerge& count) const { - return CountMerge(*this)-=count; - } - inline CountMerge invert() const { - CountMerge retval; - retval -= *this; - return retval; - } - std::vector<std::pair<property_type, int> > counts; - }; - - //output is a std::map<std::set<property_type>, polygon_45_set_data<Unit> > - struct merge_45_output_functor { - template <typename cT> - void operator()(cT& output, const CountMerge& count1, const CountMerge& count2, - const Point& pt, int rise, direction_1d end) { - typedef typename cT::key_type keytype; - keytype left; - keytype right; - int edgeType = end == LOW ? -1 : 1; - for(typename std::vector<std::pair<property_type, int> >::const_iterator itr = count1.counts.begin(); - itr != count1.counts.end(); ++itr) { - left.insert(left.end(), (*itr).first); - } - for(typename std::vector<std::pair<property_type, int> >::const_iterator itr = count2.counts.begin(); - itr != count2.counts.end(); ++itr) { - right.insert(right.end(), (*itr).first); - } - if(left == right) return; - if(!left.empty()) { - //std::cout << pt.x() << " " << pt.y() << " " << rise << " " << edgeType << std::endl; - output[left].insert_clean(typename boolean_op_45<Unit>::Vertex45(pt, rise, -edgeType)); - } - if(!right.empty()) { - //std::cout << pt.x() << " " << pt.y() << " " << rise << " " << -edgeType << std::endl; - output[right].insert_clean(typename boolean_op_45<Unit>::Vertex45(pt, rise, edgeType)); - } - } - }; - - typedef typename std::pair<Point, - typename boolean_op_45<Unit>::template Scan45CountT<CountMerge> > Vertex45Compact; - typedef std::vector<Vertex45Compact> MergeSetData; - - struct lessVertex45Compact { - bool operator()(const Vertex45Compact& l, const Vertex45Compact& r) { - return l.first < r.first; - } - }; - - template <typename output_type> - static void performMerge(output_type& result, MergeSetData& tsd) { - - polygon_sort(tsd.begin(), tsd.end(), lessVertex45Compact()); - typedef std::vector<std::pair<Point, typename boolean_op_45<Unit>::template Scan45CountT<CountMerge> > > TSD; - TSD tsd_; - tsd_.reserve(tsd.size()); - for(typename MergeSetData::iterator itr = tsd.begin(); itr != tsd.end(); ) { - typename MergeSetData::iterator itr2 = itr; - ++itr2; - for(; itr2 != tsd.end() && itr2->first == itr->first; ++itr2) { - (itr->second) += (itr2->second); //accumulate - } - tsd_.push_back(std::make_pair(itr->first, itr->second)); - itr = itr2; - } - typename boolean_op_45<Unit>::template Scan45<CountMerge, merge_45_output_functor> scanline; - for(typename TSD::iterator itr = tsd_.begin(); itr != tsd_.end(); ) { - typename TSD::iterator itr2 = itr; - ++itr2; - while(itr2 != tsd_.end() && itr2->first.x() == itr->first.x()) { - ++itr2; - } - scanline.scan(result, itr, itr2); - itr = itr2; - } - } - - template <typename iT> - static void populateMergeSetData(MergeSetData& tsd, iT begin, iT end, property_type property) { - for( ; begin != end; ++begin) { - Vertex45Compact vertex; - vertex.first = typename Vertex45Compact::first_type(begin->pt.x() * 2, begin->pt.y() * 2); - tsd.push_back(vertex); - for(unsigned int i = 0; i < 4; ++i) { - if(begin->count[i]) { - tsd.back().second[i][property] += begin->count[i]; - } - } - } - } - - }; - - - -} -} - -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/rectangle_formation.hpp b/contrib/restricted/boost/boost/polygon/detail/rectangle_formation.hpp deleted file mode 100644 index 07a2209f48..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/rectangle_formation.hpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - 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_RECTANGLE_FORMATION_HPP -#define BOOST_POLYGON_RECTANGLE_FORMATION_HPP -namespace boost { namespace polygon{ - -namespace rectangle_formation { - template <class T> - class ScanLineToRects { - public: - typedef T rectangle_type; - typedef typename rectangle_traits<T>::coordinate_type coordinate_type; - typedef rectangle_data<coordinate_type> scan_rect_type; - private: - - typedef std::set<scan_rect_type, less_rectangle_concept<scan_rect_type, scan_rect_type> > ScanData; - ScanData scanData_; - bool haveCurrentRect_; - scan_rect_type currentRect_; - orientation_2d orient_; - typename rectangle_traits<T>::coordinate_type currentCoordinate_; - public: - inline ScanLineToRects() : scanData_(), haveCurrentRect_(), currentRect_(), orient_(), currentCoordinate_() {} - - inline ScanLineToRects(orientation_2d orient, rectangle_type model) : - scanData_(orientation_2d(orient.to_int() ? VERTICAL : HORIZONTAL)), - haveCurrentRect_(false), currentRect_(), orient_(orient), currentCoordinate_() { - assign(currentRect_, model); - currentCoordinate_ = (std::numeric_limits<coordinate_type>::max)(); - } - - template <typename CT> - inline ScanLineToRects& processEdge(CT& rectangles, const interval_data<coordinate_type>& edge); - - inline ScanLineToRects& nextMajorCoordinate(coordinate_type currentCoordinate) { - if(haveCurrentRect_) { - scanData_.insert(scanData_.end(), currentRect_); - haveCurrentRect_ = false; - } - currentCoordinate_ = currentCoordinate; - return *this; - } - - }; - - template <class CT, class ST, class rectangle_type, typename interval_type, typename coordinate_type> inline CT& - processEdge_(CT& rectangles, ST& scanData, const interval_type& edge, - bool& haveCurrentRect, rectangle_type& currentRect, coordinate_type currentCoordinate, orientation_2d orient) - { - typedef typename CT::value_type result_type; - bool edgeProcessed = false; - if(!scanData.empty()) { - - //process all rectangles in the scanData that touch the edge - typename ST::iterator dataIter = scanData.lower_bound(rectangle_type(edge, edge)); - //decrement beginIter until its low is less than edge's low - while((dataIter == scanData.end() || (*dataIter).get(orient).get(LOW) > edge.get(LOW)) && - dataIter != scanData.begin()) - { - --dataIter; - } - //process each rectangle until the low end of the rectangle - //is greater than the high end of the edge - while(dataIter != scanData.end() && - (*dataIter).get(orient).get(LOW) <= edge.get(HIGH)) - { - const rectangle_type& rect = *dataIter; - //if the rectangle data intersects the edge at all - if(rect.get(orient).get(HIGH) >= edge.get(LOW)) { - if(contains(rect.get(orient), edge, true)) { - //this is a closing edge - //we need to write out the intersecting rectangle and - //insert between 0 and 2 rectangles into the scanData - //write out rectangle - rectangle_type tmpRect = rect; - - if(rect.get(orient.get_perpendicular()).get(LOW) < currentCoordinate) { - //set the high coordinate perpedicular to slicing orientation - //to the current coordinate of the scan event - tmpRect.set(orient.get_perpendicular().get_direction(HIGH), - currentCoordinate); - result_type result; - assign(result, tmpRect); - rectangles.insert(rectangles.end(), result); - } - //erase the rectangle from the scan data - typename ST::iterator nextIter = dataIter; - ++nextIter; - scanData.erase(dataIter); - if(tmpRect.get(orient).get(LOW) < edge.get(LOW)) { - //insert a rectangle for the overhang of the bottom - //of the rectangle back into scan data - rectangle_type lowRect(tmpRect); - lowRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate, - currentCoordinate)); - lowRect.set(orient.get_direction(HIGH), edge.get(LOW)); - scanData.insert(nextIter, lowRect); - } - if(tmpRect.get(orient).get(HIGH) > edge.get(HIGH)) { - //insert a rectangle for the overhang of the top - //of the rectangle back into scan data - rectangle_type highRect(tmpRect); - highRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate, - currentCoordinate)); - highRect.set(orient.get_direction(LOW), edge.get(HIGH)); - scanData.insert(nextIter, highRect); - } - //we are done with this edge - edgeProcessed = true; - break; - } else { - //it must be an opening edge - //assert that rect does not overlap the edge but only touches - //write out rectangle - rectangle_type tmpRect = rect; - //set the high coordinate perpedicular to slicing orientation - //to the current coordinate of the scan event - if(tmpRect.get(orient.get_perpendicular().get_direction(LOW)) < currentCoordinate) { - tmpRect.set(orient.get_perpendicular().get_direction(HIGH), - currentCoordinate); - result_type result; - assign(result, tmpRect); - rectangles.insert(rectangles.end(), result); - } - //erase the rectangle from the scan data - typename ST::iterator nextIter = dataIter; - ++nextIter; - scanData.erase(dataIter); - dataIter = nextIter; - if(haveCurrentRect) { - if(currentRect.get(orient).get(HIGH) >= edge.get(LOW)){ - if(!edgeProcessed && currentRect.get(orient.get_direction(HIGH)) > edge.get(LOW)){ - rectangle_type tmpRect2(currentRect); - tmpRect2.set(orient.get_direction(HIGH), edge.get(LOW)); - scanData.insert(nextIter, tmpRect2); - if(currentRect.get(orient.get_direction(HIGH)) > edge.get(HIGH)) { - currentRect.set(orient, interval_data<coordinate_type>(edge.get(HIGH), currentRect.get(orient.get_direction(HIGH)))); - } else { - haveCurrentRect = false; - } - } else { - //extend the top of current rect - currentRect.set(orient.get_direction(HIGH), - (std::max)(edge.get(HIGH), - tmpRect.get(orient.get_direction(HIGH)))); - } - } else { - //insert current rect into the scanData - scanData.insert(nextIter, currentRect); - //create a new current rect - currentRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate, - currentCoordinate)); - currentRect.set(orient, interval_data<coordinate_type>((std::min)(tmpRect.get(orient).get(LOW), - edge.get(LOW)), - (std::max)(tmpRect.get(orient).get(HIGH), - edge.get(HIGH)))); - } - } else { - haveCurrentRect = true; - currentRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate, - currentCoordinate)); - currentRect.set(orient, interval_data<coordinate_type>((std::min)(tmpRect.get(orient).get(LOW), - edge.get(LOW)), - (std::max)(tmpRect.get(orient).get(HIGH), - edge.get(HIGH)))); - } - //skip to nextIter position - edgeProcessed = true; - continue; - } - //edgeProcessed = true; - } - ++dataIter; - } //end while edge intersects rectangle data - - } - if(!edgeProcessed) { - if(haveCurrentRect) { - if(currentRect.get(orient.get_perpendicular().get_direction(HIGH)) - == currentCoordinate && - currentRect.get(orient.get_direction(HIGH)) >= edge.get(LOW)) - { - if(currentRect.get(orient.get_direction(HIGH)) > edge.get(LOW)){ - rectangle_type tmpRect(currentRect); - tmpRect.set(orient.get_direction(HIGH), edge.get(LOW)); - scanData.insert(scanData.end(), tmpRect); - if(currentRect.get(orient.get_direction(HIGH)) > edge.get(HIGH)) { - currentRect.set(orient, - interval_data<coordinate_type>(edge.get(HIGH), - currentRect.get(orient.get_direction(HIGH)))); - return rectangles; - } else { - haveCurrentRect = false; - return rectangles; - } - } - //extend current rect - currentRect.set(orient.get_direction(HIGH), edge.get(HIGH)); - return rectangles; - } - scanData.insert(scanData.end(), currentRect); - haveCurrentRect = false; - } - rectangle_type tmpRect(currentRect); - tmpRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate, - currentCoordinate)); - tmpRect.set(orient, edge); - scanData.insert(tmpRect); - return rectangles; - } - return rectangles; - - } - - template <class T> - template <class CT> - inline - ScanLineToRects<T>& ScanLineToRects<T>::processEdge(CT& rectangles, const interval_data<coordinate_type>& edge) - { - processEdge_(rectangles, scanData_, edge, haveCurrentRect_, currentRect_, currentCoordinate_, orient_); - return *this; - } - - -} //namespace rectangle_formation - - template <typename T, typename T2> - struct get_coordinate_type_for_rectangles { - typedef typename polygon_traits<T>::coordinate_type type; - }; - template <typename T> - struct get_coordinate_type_for_rectangles<T, rectangle_concept> { - typedef typename rectangle_traits<T>::coordinate_type type; - }; - - template <typename output_container, typename iterator_type, typename rectangle_concept> - void form_rectangles(output_container& output, iterator_type begin, iterator_type end, - orientation_2d orient, rectangle_concept ) { - typedef typename output_container::value_type rectangle_type; - typedef typename get_coordinate_type_for_rectangles<rectangle_type, typename geometry_concept<rectangle_type>::type>::type Unit; - rectangle_data<Unit> model; - Unit prevPos = (std::numeric_limits<Unit>::max)(); - rectangle_formation::ScanLineToRects<rectangle_data<Unit> > scanlineToRects(orient, model); - for(iterator_type itr = begin; - itr != end; ++ itr) { - Unit pos = (*itr).first; - if(pos != prevPos) { - scanlineToRects.nextMajorCoordinate(pos); - prevPos = pos; - } - Unit lowy = (*itr).second.first; - iterator_type tmp_itr = itr; - ++itr; - Unit highy = (*itr).second.first; - scanlineToRects.processEdge(output, interval_data<Unit>(lowy, highy)); - if(std::abs((*itr).second.second) > 1) itr = tmp_itr; //next edge begins from this vertex - } - } -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/scan_arbitrary.hpp b/contrib/restricted/boost/boost/polygon/detail/scan_arbitrary.hpp deleted file mode 100644 index 86f77784aa..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/scan_arbitrary.hpp +++ /dev/null @@ -1,2861 +0,0 @@ -/* - 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_SCAN_ARBITRARY_HPP -#define BOOST_POLYGON_SCAN_ARBITRARY_HPP -#ifdef BOOST_POLYGON_DEBUG_FILE -#include <fstream> -#endif -#include "polygon_sort_adaptor.hpp" -namespace boost { namespace polygon{ - - template <typename Unit> - class line_intersection : public scanline_base<Unit> { - private: - typedef typename scanline_base<Unit>::Point Point; - - //the first point is the vertex and and second point establishes the slope of an edge eminating from the vertex - //typedef std::pair<Point, Point> half_edge; - typedef typename scanline_base<Unit>::half_edge half_edge; - - //scanline comparator functor - typedef typename scanline_base<Unit>::less_half_edge less_half_edge; - typedef typename scanline_base<Unit>::less_point less_point; - - //when parallel half edges are encounterd the set of segments is expanded - //when a edge leaves the scanline it is removed from the set - //when the set is empty the element is removed from the map - typedef int segment_id; - typedef std::pair<half_edge, std::set<segment_id> > scanline_element; - typedef std::map<half_edge, std::set<segment_id>, less_half_edge> edge_scanline; - typedef typename edge_scanline::iterator iterator; - -// std::map<Unit, std::set<segment_id> > vertical_data_; -// edge_scanline edge_scanline_; -// Unit x_; -// int just_before_; -// segment_id segment_id_; -// std::vector<std::pair<half_edge, int> > event_edges_; -// std::set<Point> intersection_queue_; - public: -// inline line_intersection() : vertical_data_(), edge_scanline_(), x_((std::numeric_limits<Unit>::max)()), just_before_(0), segment_id_(0), event_edges_(), intersection_queue_() { -// less_half_edge lessElm(&x_, &just_before_); -// edge_scanline_ = edge_scanline(lessElm); -// } -// inline line_intersection(const line_intersection& that) : vertical_data_(), edge_scanline_(), x_(), just_before_(), segment_id_(), event_edges_(), intersection_queue_() { (*this) = that; } -// inline line_intersection& operator=(const line_intersection& that) { -// x_ = that.x_; -// just_before_ = that.just_before_; -// segment_id_ = that.segment_id_; - -// //I cannot simply copy that.edge_scanline_ to this edge_scanline_ becuase the functor store pointers to other members! -// less_half_edge lessElm(&x_, &just_before_); -// edge_scanline_ = edge_scanline(lessElm); - -// edge_scanline_.insert(that.edge_scanline_.begin(), that.edge_scanline_.end()); -// return *this; -// } - -// static inline void between(Point pt, Point pt1, Point pt2) { -// less_point lp; -// if(lp(pt1, pt2)) -// return lp(pt, pt2) && lp(pt1, pt); -// return lp(pt, pt1) && lp(pt2, pt); -// } - - template <typename iT> - static inline void compute_histogram_in_y(iT begin, iT end, std::size_t size, std::vector<std::pair<Unit, std::pair<std::size_t, std::size_t> > >& histogram) { - std::vector<std::pair<Unit, int> > ends; - ends.reserve(size * 2); - for(iT itr = begin ; itr != end; ++itr) { - int count = (*itr).first.first.y() < (*itr).first.second.y() ? 1 : -1; - ends.push_back(std::make_pair((*itr).first.first.y(), count)); - ends.push_back(std::make_pair((*itr).first.second.y(), -count)); - } - polygon_sort(ends.begin(), ends.end()); - histogram.reserve(ends.size()); - histogram.push_back(std::make_pair(ends.front().first, std::make_pair(0, 0))); - for(typename std::vector<std::pair<Unit, int> >::iterator itr = ends.begin(); itr != ends.end(); ++itr) { - if((*itr).first != histogram.back().first) { - histogram.push_back(std::make_pair((*itr).first, histogram.back().second)); - } - if((*itr).second < 0) - histogram.back().second.second -= (*itr).second; - histogram.back().second.first += (*itr).second; - } - } - - template <typename iT> - static inline void compute_y_cuts(std::vector<Unit>& y_cuts, iT begin, iT end, std::size_t size) { - if(begin == end) return; - if(size < 30) return; //30 is empirically chosen, but the algorithm is not sensitive to this constant - std::size_t min_cut = size; - iT cut = begin; - std::size_t position = 0; - std::size_t cut_size = 0; - std::size_t histogram_size = std::distance(begin, end); - for(iT itr = begin; itr != end; ++itr, ++position) { - if(position < histogram_size / 3) - continue; - if(histogram_size - position < histogram_size / 3) break; - if((*itr).second.first < min_cut) { - cut = itr; - min_cut = (*cut).second.first; - cut_size = position; - } - } - if(cut_size == 0 || (*cut).second.first > size / 9) //nine is empirically chosen - return; - compute_y_cuts(y_cuts, begin, cut, (*cut).second.first + (*cut).second.second); - y_cuts.push_back((*cut).first); - compute_y_cuts(y_cuts, cut, end, size - (*cut).second.second); - } - - template <typename iT> - static inline void validate_scan_divide_and_conquer(std::vector<std::set<Point> >& intersection_points, - iT begin, iT end) { - std::vector<std::pair<Unit, std::pair<std::size_t, std::size_t> > > histogram; - compute_histogram_in_y(begin, end, std::distance(begin, end), histogram); - std::vector<Unit> y_cuts; - compute_y_cuts(y_cuts, histogram.begin(), histogram.end(), std::distance(begin, end)); - std::map<Unit, std::vector<std::pair<half_edge, segment_id> > > bins; - bins[histogram.front().first] = std::vector<std::pair<half_edge, segment_id> >(); - for(typename std::vector<Unit>::iterator itr = y_cuts.begin(); itr != y_cuts.end(); ++itr) { - bins[*itr] = std::vector<std::pair<half_edge, segment_id> >(); - } - for(iT itr = begin; itr != end; ++itr) { - typename std::map<Unit, std::vector<std::pair<half_edge, segment_id> > >::iterator lb = - bins.lower_bound((std::min)((*itr).first.first.y(), (*itr).first.second.y())); - if(lb != bins.begin()) - --lb; - typename std::map<Unit, std::vector<std::pair<half_edge, segment_id> > >::iterator ub = - bins.upper_bound((std::max)((*itr).first.first.y(), (*itr).first.second.y())); - for( ; lb != ub; ++lb) { - (*lb).second.push_back(*itr); - } - } - validate_scan(intersection_points, bins[histogram.front().first].begin(), bins[histogram.front().first].end()); - for(typename std::vector<Unit>::iterator itr = y_cuts.begin(); itr != y_cuts.end(); ++itr) { - validate_scan(intersection_points, bins[*itr].begin(), bins[*itr].end(), *itr); - } - } - - template <typename iT> - static inline void validate_scan(std::vector<std::set<Point> >& intersection_points, - iT begin, iT end) { - validate_scan(intersection_points, begin, end, (std::numeric_limits<Unit>::min)()); - } - //quadratic algorithm to do same work as optimal scan for cross checking - template <typename iT> - static inline void validate_scan(std::vector<std::set<Point> >& intersection_points, - iT begin, iT end, Unit min_y) { - std::vector<Point> pts; - std::vector<std::pair<half_edge, segment_id> > data(begin, end); - for(std::size_t i = 0; i < data.size(); ++i) { - if(data[i].first.second < data[i].first.first) { - std::swap(data[i].first.first, data[i].first.second); - } - } - typename scanline_base<Unit>::compute_intersection_pack pack_; - polygon_sort(data.begin(), data.end()); - //find all intersection points - for(typename std::vector<std::pair<half_edge, segment_id> >::iterator outer = data.begin(); - outer != data.end(); ++outer) { - const half_edge& he1 = (*outer).first; - //its own end points - pts.push_back(he1.first); - pts.push_back(he1.second); - std::set<Point>& segmentpts = intersection_points[(*outer).second]; - for(typename std::set<Point>::iterator itr = segmentpts.begin(); itr != segmentpts.end(); ++itr) { - if ((*itr).y() >= min_y) { - pts.push_back(*itr); - } - } - bool have_first_y = he1.first.y() >= min_y && he1.second.y() >= min_y; - for(typename std::vector<std::pair<half_edge, segment_id> >::iterator inner = outer; - inner != data.end(); ++inner) { - const half_edge& he2 = (*inner).first; - if(have_first_y || (he2.first.y() >= min_y && he2.second.y() >= min_y)) { - //at least one segment has a low y value within the range - if(he1 == he2) continue; - if((std::min)(he2. first.get(HORIZONTAL), - he2.second.get(HORIZONTAL)) >= - (std::max)(he1.second.get(HORIZONTAL), - he1.first.get(HORIZONTAL))) - break; - if(he1.first == he2.first || he1.second == he2.second) - continue; - Point intersection; - if(pack_.compute_intersection(intersection, he1, he2)) { - //their intersection point - pts.push_back(intersection); - intersection_points[(*inner).second].insert(intersection); - intersection_points[(*outer).second].insert(intersection); - } - } - } - } - polygon_sort(pts.begin(), pts.end()); - typename std::vector<Point>::iterator newend = std::unique(pts.begin(), pts.end()); - typename std::vector<Point>::iterator lfinger = pts.begin(); - //find all segments that interact with intersection points - for(typename std::vector<std::pair<half_edge, segment_id> >::iterator outer = data.begin(); - outer != data.end(); ++outer) { - const half_edge& he1 = (*outer).first; - segment_id id1 = (*outer).second; - //typedef rectangle_data<Unit> Rectangle; - //Rectangle rect1; - //set_points(rect1, he1.first, he1.second); - //typename std::vector<Point>::iterator itr = lower_bound(pts.begin(), newend, (std::min)(he1.first, he1.second)); - //typename std::vector<Point>::iterator itr2 = upper_bound(pts.begin(), newend, (std::max)(he1.first, he1.second)); - Point startpt = (std::min)(he1.first, he1.second); - Point stoppt = (std::max)(he1.first, he1.second); - //while(itr != newend && itr != pts.begin() && (*itr).get(HORIZONTAL) >= (std::min)(he1.first.get(HORIZONTAL), he1.second.get(HORIZONTAL))) --itr; - //while(itr2 != newend && (*itr2).get(HORIZONTAL) <= (std::max)(he1.first.get(HORIZONTAL), he1.second.get(HORIZONTAL))) ++itr2; - //itr = pts.begin(); - //itr2 = pts.end(); - while(lfinger != newend && (*lfinger).x() < startpt.x()) ++lfinger; - for(typename std::vector<Point>::iterator itr = lfinger ; itr != newend && (*itr).x() <= stoppt.x(); ++itr) { - if(scanline_base<Unit>::intersects_grid(*itr, he1)) - intersection_points[id1].insert(*itr); - } - } - } - - template <typename iT, typename property_type> - static inline void validate_scan(std::vector<std::pair<half_edge, std::pair<property_type, int> > >& output_segments, - iT begin, iT end) { - std::vector<std::pair<property_type, int> > input_properties; - std::vector<std::pair<half_edge, int> > input_segments, intermediate_segments; - int index = 0; - for( ; begin != end; ++begin) { - input_properties.push_back((*begin).second); - input_segments.push_back(std::make_pair((*begin).first, index++)); - } - validate_scan(intermediate_segments, input_segments.begin(), input_segments.end()); - for(std::size_t i = 0; i < intermediate_segments.size(); ++i) { - output_segments.push_back(std::make_pair(intermediate_segments[i].first, - input_properties[intermediate_segments[i].second])); - less_point lp; - if(lp(output_segments.back().first.first, output_segments.back().first.second) != - lp(input_segments[intermediate_segments[i].second].first.first, - input_segments[intermediate_segments[i].second].first.second)) { - //edge changed orientation, invert count on edge - output_segments.back().second.second *= -1; - } - if(!scanline_base<Unit>::is_vertical(input_segments[intermediate_segments[i].second].first) && - scanline_base<Unit>::is_vertical(output_segments.back().first)) { - output_segments.back().second.second *= -1; - } - if(lp(output_segments.back().first.second, output_segments.back().first.first)) { - std::swap(output_segments.back().first.first, output_segments.back().first.second); - } - } - } - - template <typename iT> - static inline void validate_scan(std::vector<std::pair<half_edge, int> >& output_segments, - iT begin, iT end) { - std::vector<std::set<Point> > intersection_points(std::distance(begin, end)); - validate_scan_divide_and_conquer(intersection_points, begin, end); - //validate_scan(intersection_points, begin, end); - segment_intersections(output_segments, intersection_points, begin, end); -// std::pair<segment_id, segment_id> offenders; -// if(!verify_scan(offenders, output_segments.begin(), output_segments.end())) { -// std::cout << "break here!\n"; -// for(typename std::set<Point>::iterator itr = intersection_points[offenders.first].begin(); -// itr != intersection_points[offenders.first].end(); ++itr) { -// std::cout << (*itr).x() << " " << (*itr).y() << " "; -// } std::cout << "\n"; -// for(typename std::set<Point>::iterator itr = intersection_points[offenders.second].begin(); -// itr != intersection_points[offenders.second].end(); ++itr) { -// std::cout << (*itr).x() << " " << (*itr).y() << " "; -// } std::cout << "\n"; -// exit(1); -// } - } - - //quadratic algorithm to find intersections - template <typename iT, typename segment_id> - static inline bool verify_scan(std::pair<segment_id, segment_id>& offenders, - iT begin, iT end) { - - std::vector<std::pair<half_edge, segment_id> > data(begin, end); - for(std::size_t i = 0; i < data.size(); ++i) { - if(data[i].first.second < data[i].first.first) { - std::swap(data[i].first.first, data[i].first.second); - } - } - polygon_sort(data.begin(), data.end()); - for(typename std::vector<std::pair<half_edge, segment_id> >::iterator outer = data.begin(); - outer != data.end(); ++outer) { - const half_edge& he1 = (*outer).first; - segment_id id1 = (*outer).second; - for(typename std::vector<std::pair<half_edge, segment_id> >::iterator inner = outer; - inner != data.end(); ++inner) { - const half_edge& he2 = (*inner).first; - if(he1 == he2) continue; - if((std::min)(he2. first.get(HORIZONTAL), - he2.second.get(HORIZONTAL)) > - (std::max)(he1.second.get(HORIZONTAL), - he1.first.get(HORIZONTAL))) - break; - segment_id id2 = (*inner).second; - if(scanline_base<Unit>::intersects(he1, he2)) { - offenders.first = id1; - offenders.second = id2; - //std::cout << he1.first.x() << " " << he1.first.y() << " " << he1.second.x() << " " << he1.second.y() << " " << he2.first.x() << " " << he2.first.y() << " " << he2.second.x() << " " << he2.second.y() << "\n"; - return false; - } - } - } - return true; - } - - class less_point_down_slope { - public: - typedef Point first_argument_type; - typedef Point second_argument_type; - typedef bool result_type; - inline less_point_down_slope() {} - inline bool operator () (const Point& pt1, const Point& pt2) const { - if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true; - if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) { - if(pt1.get(VERTICAL) > pt2.get(VERTICAL)) return true; - } - return false; - } - }; - - template <typename iT> - static inline void segment_edge(std::vector<std::pair<half_edge, int> >& output_segments, - const half_edge& , segment_id id, iT begin, iT end) { - iT current = begin; - iT next = begin; - ++next; - while(next != end) { - output_segments.push_back(std::make_pair(half_edge(*current, *next), id)); - current = next; - ++next; - } - } - - template <typename iT> - static inline void segment_intersections(std::vector<std::pair<half_edge, int> >& output_segments, - std::vector<std::set<Point> >& intersection_points, - iT begin, iT end) { - for(iT iter = begin; iter != end; ++iter) { - //less_point lp; - const half_edge& he = (*iter).first; - //if(lp(he.first, he.second)) { - // //it is the begin event - segment_id id = (*iter).second; - const std::set<Point>& pts = intersection_points[id]; - Point hpt(he.first.get(HORIZONTAL)+1, he.first.get(VERTICAL)); - if(!scanline_base<Unit>::is_vertical(he) && scanline_base<Unit>::less_slope(he.first.get(HORIZONTAL), he.first.get(VERTICAL), - he.second, hpt)) { - //slope is below horizontal - std::vector<Point> tmpPts; - tmpPts.reserve(pts.size()); - tmpPts.insert(tmpPts.end(), pts.begin(), pts.end()); - less_point_down_slope lpds; - polygon_sort(tmpPts.begin(), tmpPts.end(), lpds); - segment_edge(output_segments, he, id, tmpPts.begin(), tmpPts.end()); - } else { - segment_edge(output_segments, he, id, pts.begin(), pts.end()); - } - //} - } - } - -// //iT iterator over unsorted pair<Point> representing line segments of input -// //output_segments is populated with fully intersected output line segment half -// //edges and the index of the input segment that they are assoicated with -// //duplicate output half edges with different ids will be generated in the case -// //that parallel input segments intersection -// //outputs are in sorted order and include both begin and end events for -// //each segment -// template <typename iT> -// inline void scan(std::vector<std::pair<half_edge, int> >& output_segments, -// iT begin, iT end) { -// std::map<segment_id, std::set<Point> > intersection_points; -// scan(intersection_points, begin, end); -// segment_intersections(output_segments, intersection_points, begin, end); -// } - -// //iT iterator over sorted sequence of half edge, segment id pairs representing segment begin and end points -// //intersection points provides a mapping from input segment id (vector index) to the set -// //of intersection points assocated with that input segment -// template <typename iT> -// inline void scan(std::map<segment_id, std::set<Point> >& intersection_points, -// iT begin, iT end) { -// for(iT iter = begin; iter != end; ++iter) { -// const std::pair<half_edge, int>& elem = *iter; -// const half_edge& he = elem.first; -// Unit current_x = he.first.get(HORIZONTAL); -// if(current_x != x_) { -// process_scan_event(intersection_points); -// while(!intersection_queue_.empty() && -// (*(intersection_queue_.begin()).get(HORIZONTAL) < current_x)) { -// x_ = *(intersection_queue_.begin()).get(HORIZONTAL); -// process_intersections_at_scan_event(intersection_points); -// } -// x_ = current_x; -// } -// event_edges_.push_back(elem); -// } -// process_scan_event(intersection_points); -// } - -// inline iterator lookup(const half_edge& he) { -// return edge_scanline_.find(he); -// } - -// inline void insert_into_scanline(const half_edge& he, int id) { -// edge_scanline_[he].insert(id); -// } - -// inline void lookup_and_remove(const half_edge& he, int id) { -// iterator remove_iter = lookup(he); -// if(remove_iter == edge_scanline_.end()) { -// //std::cout << "failed to find removal segment in scanline\n"; -// return; -// } -// std::set<segment_id>& ids = (*remove_iter).second; -// std::set<segment_id>::iterator id_iter = ids.find(id); -// if(id_iter == ids.end()) { -// //std::cout << "failed to find removal segment id in scanline set\n"; -// return; -// } -// ids.erase(id_iter); -// if(ids.empty()) -// edge_scanline_.erase(remove_iter); -// } - -// static inline void update_segments(std::map<segment_id, std::set<Point> >& intersection_points, -// const std::set<segment_id>& segments, Point pt) { -// for(std::set<segment_id>::const_iterator itr = segments.begin(); itr != segments.end(); ++itr) { -// intersection_points[*itr].insert(pt); -// } -// } - -// inline void process_intersections_at_scan_event(std::map<segment_id, std::set<Point> >& intersection_points) { -// //there may be additional intersection points at this x location that haven't been -// //found yet if vertical or near vertical line segments intersect more than -// //once before the next x location -// just_before_ = true; -// std::set<iterator> intersecting_elements; -// std::set<Unit> intersection_locations; -// typedef typename std::set<Point>::iterator intersection_iterator; -// intersection_iterator iter; -// //first find all secondary intersection locations and all scanline iterators -// //that are intersecting -// for(iter = intersection_queue_.begin(); -// iter != intersection_queue_.end() && (*iter).get(HORIZONTAL) == x_; ++iter) { -// Point pt = *iter; -// Unit y = pt.get(VERTICAL); -// intersection_locations.insert(y); -// //if x_ is max there can be only end events and no sloping edges -// if(x_ != (std::numeric_limits<Unit>::max)()) { -// //deal with edges that project to the right of scanline -// //first find the edges in the scanline adjacent to primary intersectin points -// //lookup segment in scanline at pt -// iterator itr = edge_scanline_.lower_bound(half_edge(pt, Point(x_+1, y))); -// //look above pt in scanline until reaching end or segment that doesn't intersect -// //1x1 grid upper right of pt -// //look below pt in scanline until reaching begin or segment that doesn't interset -// //1x1 grid upper right of pt - -// //second find edges in scanline on the y interval of each edge found in the previous -// //step for x_ to x_ + 1 - -// //third find overlaps in the y intervals of all found edges to find all -// //secondary intersection points - -// } -// } -// //erase the intersection points from the queue -// intersection_queue_.erase(intersection_queue_.begin(), iter); -// std::vector<scanline_element> insertion_edges; -// insertion_edges.reserve(intersecting_elements.size()); -// std::vector<std::pair<Unit, iterator> > sloping_ends; -// //do all the work of updating the output of all intersecting -// for(typename std::set<iterator>::iterator inter_iter = intersecting_elements.begin(); -// inter_iter != intersecting_elements.end(); ++inter_iter) { -// //if it is horizontal update it now and continue -// if(is_horizontal((*inter_iter).first)) { -// update_segments(intersection_points, (*inter_iter).second, Point(x_, (*inter_iter).first.get(VERTICAL))); -// } else { -// //if x_ is max there can be only end events and no sloping edges -// if(x_ != (std::numeric_limits<Unit>::max)()) { -// //insert its end points into the vector of sloping ends -// const half_edge& he = (*inter_iter).first; -// Unit y = evalAtXforY(x_, he.first, he.second); -// Unit y2 = evalAtXforY(x_+1, he.first, he.second); -// if(y2 >= y) y2 +=1; //we round up, in exact case we don't worry about overbite of one -// else y += 1; //downward sloping round up -// sloping_ends.push_back(std::make_pair(y, inter_iter)); -// sloping_ends.push_back(std::make_pair(y2, inter_iter)); -// } -// } -// } - -// //merge sloping element data -// polygon_sort(sloping_ends.begin(), sloping_ends.end()); -// std::map<Unit, std::set<iterator> > sloping_elements; -// std::set<iterator> merge_elements; -// for(typename std::vector<std::pair<Unit, iterator> >::iterator slop_iter = sloping_ends.begin(); -// slop_iter == sloping_ends.end(); ++slop_iter) { -// //merge into sloping elements -// typename std::set<iterator>::iterator merge_iterator = merge_elements.find((*slop_iter).second); -// if(merge_iterator == merge_elements.end()) { -// merge_elements.insert((*slop_iter).second); -// } else { -// merge_elements.erase(merge_iterator); -// } -// sloping_elements[(*slop_iter).first] = merge_elements; -// } - -// //scan intersection points -// typename std::map<Unit, std::set<segment_id> >::iterator vertical_iter = vertical_data_.begin(); -// typename std::map<Unit, std::set<iterator> >::iterator sloping_iter = sloping_elements.begin(); -// for(typename std::set<Unit>::iterator position_iter = intersection_locations.begin(); -// position_iter == intersection_locations.end(); ++position_iter) { -// //look for vertical segments that intersect this point and update them -// Unit y = *position_iter; -// Point pt(x_, y); -// //handle vertical segments -// if(vertical_iter != vertical_data_.end()) { -// typename std::map<Unit, std::set<segment_id> >::iterator next_vertical = vertical_iter; -// for(++next_vertical; next_vertical != vertical_data_.end() && -// (*next_vertical).first < y; ++next_vertical) { -// vertical_iter = next_vertical; -// } -// if((*vertical_iter).first < y && !(*vertical_iter).second.empty()) { -// update_segments(intersection_points, (*vertical_iter).second, pt); -// ++vertical_iter; -// if(vertical_iter != vertical_data_.end() && (*vertical_iter).first == y) -// update_segments(intersection_points, (*vertical_iter).second, pt); -// } -// } -// //handle sloping segments -// if(sloping_iter != sloping_elements.end()) { -// typename std::map<Unit, std::set<iterator> >::iterator next_sloping = sloping_iter; -// for(++next_sloping; next_sloping != sloping_elements.end() && -// (*next_sloping).first < y; ++next_sloping) { -// sloping_iter = next_sloping; -// } -// if((*sloping_iter).first < y && !(*sloping_iter).second.empty()) { -// for(typename std::set<iterator>::iterator element_iter = (*sloping_iter).second.begin(); -// element_iter != (*sloping_iter).second.end(); ++element_iter) { -// const half_edge& he = (*element_iter).first; -// if(intersects_grid(pt, he)) { -// update_segments(intersection_points, (*element_iter).second, pt); -// } -// } -// ++sloping_iter; -// if(sloping_iter != sloping_elements.end() && (*sloping_iter).first == y && -// !(*sloping_iter).second.empty()) { -// for(typename std::set<iterator>::iterator element_iter = (*sloping_iter).second.begin(); -// element_iter != (*sloping_iter).second.end(); ++element_iter) { -// const half_edge& he = (*element_iter).first; -// if(intersects_grid(pt, he)) { -// update_segments(intersection_points, (*element_iter).second, pt); -// } -// } -// } -// } -// } -// } - -// //erase and reinsert edges into scanline with check for future intersection -// } - -// inline void process_scan_event(std::map<segment_id, std::set<Point> >& intersection_points) { -// just_before_ = true; - -// //process end events by removing those segments from the scanline -// //and insert vertices of all events into intersection queue -// Point prev_point((std::numeric_limits<Unit>::min)(), (std::numeric_limits<Unit>::min)()); -// less_point lp; -// std::set<segment_id> vertical_ids; -// vertical_data_.clear(); -// for(std::size_t i = 0; i < event_edges_.size(); ++i) { -// segment_id id = event_edges_[i].second; -// const half_edge& he = event_edges_[i].first; -// //vertical half edges are handled during intersection processing because -// //they cannot be inserted into the scanline -// if(!is_vertical(he)) { -// if(lp(he.second, he.first)) { -// //half edge is end event -// lookup_and_remove(he, id); -// } else { -// //half edge is begin event -// insert_into_scanline(he, id); -// //note that they will be immediately removed and reinserted after -// //handling their intersection (vertex) -// //an optimization would allow them to be processed specially to avoid the redundant -// //removal and reinsertion -// } -// } else { -// //common case if you are lucky -// //update the map of y to set of segment id -// if(lp(he.second, he.first)) { -// //half edge is end event -// std::set<segment_id>::iterator itr = vertical_ids.find(id); -// if(itr == vertical_ids.end()) { -// //std::cout << "Failed to find end event id in vertical ids\n"; -// } else { -// vertical_ids.erase(itr); -// vertical_data_[he.first.get(HORIZONTAL)] = vertical_ids; -// } -// } else { -// //half edge is a begin event -// vertical_ids.insert(id); -// vertical_data_[he.first.get(HORIZONTAL)] = vertical_ids; -// } -// } -// //prevent repeated insertion of same vertex into intersection queue -// if(prev_point != he.first) -// intersection_queue_.insert(he.first); -// else -// prev_point = he.first; -// // process intersections at scan event -// process_intersections_at_scan_event(intersection_points); -// } -// event_edges_.clear(); -// } - - public: - template <typename stream_type> - static inline bool test_validate_scan(stream_type& stdcout) { - std::vector<std::pair<half_edge, segment_id> > input, edges; - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), 0)); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 10)), 1)); - std::pair<segment_id, segment_id> result; - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail1 " << result.first << " " << result.second << "\n"; - return false; - } - input.push_back(std::make_pair(half_edge(Point(0, 5), Point(5, 5)), 2)); - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 " << result.first << " " << result.second << "\n"; - return false; - } - input.pop_back(); - input.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), input.size())); - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail3 " << result.first << " " << result.second << "\n"; - return false; - } - input.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), input.size())); - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail4 " << result.first << " " << result.second << "\n"; - return false; - } - input.pop_back(); - input.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), input.size())); - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail5 " << result.first << " " << result.second << "\n"; - return false; - } - input.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), input.size())); - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail6 " << result.first << " " << result.second << "\n"; - return false; - } - input.pop_back(); - for(std::size_t i = 0; i < input.size(); ++i) { - std::swap(input[i].first.first, input[i].first.second); - } - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail5 2 " << result.first << " " << result.second << "\n"; - return false; - } - for(std::size_t i = 0; i < input.size(); ++i) { - input[i].first.first = Point(input[i].first.first.get(HORIZONTAL) * -1, - input[i].first.first.get(VERTICAL) * -1); - input[i].first.second = Point(input[i].first.second.get(HORIZONTAL) * -1, - input[i].first.second.get(VERTICAL) * -1); - } - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - stdcout << edges.size() << "\n"; - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail5 3 " << result.first << " " << result.second << "\n"; - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(5, 7), Point(7, 6)), 0)); - input.push_back(std::make_pair(half_edge(Point(2, 4), Point(6, 7)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 1 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(3, 2), Point(1, 7)), 0)); - input.push_back(std::make_pair(half_edge(Point(0, 6), Point(7, 4)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 2 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(6, 6), Point(1, 0)), 0)); - input.push_back(std::make_pair(half_edge(Point(3, 6), Point(2, 3)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 3 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(7, 0)), 0)); - input.push_back(std::make_pair(half_edge(Point(6, 0), Point(2, 0)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 4 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(-17333131 - -17208131, -10316869 - -10191869), Point(0, 0)), 0)); - input.push_back(std::make_pair(half_edge(Point(-17291260 - -17208131, -10200000 - -10191869), Point(-17075000 - -17208131, -10200000 - -10191869)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 5 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(-17333131, -10316869), Point(-17208131, -10191869)), 0)); - input.push_back(std::make_pair(half_edge(Point(-17291260, -10200000), Point(-17075000, -10200000)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 6 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(-9850009+9853379, -286971+290340), Point(-12777869+9853379, -3214831+290340)), 0)); - input.push_back(std::make_pair(half_edge(Point(-5223510+9853379, -290340+290340), Point(-9858140+9853379, -290340+290340)), 1)); - validate_scan(edges, input.begin(), input.end()); - print(edges); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 7 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(-9850009, -286971), Point(-12777869, -3214831)), 0)); - input.push_back(std::make_pair(half_edge(Point(-5223510, -290340), Point(-9858140, -290340)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 8 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - //3 3 2 2: 0; 4 2 0 6: 1; 0 3 6 3: 2; 4 1 5 5: 3; - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(3, 3), Point(2, 2)), 0)); - input.push_back(std::make_pair(half_edge(Point(4, 2), Point(0, 6)), 1)); - input.push_back(std::make_pair(half_edge(Point(0, 3), Point(6, 3)), 2)); - input.push_back(std::make_pair(half_edge(Point(4, 1), Point(5, 5)), 3)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail4 1 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - //5 7 1 3: 0; 4 5 2 1: 1; 2 5 2 1: 2; 4 1 5 3: 3; - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(5, 7), Point(1, 3)), 0)); - input.push_back(std::make_pair(half_edge(Point(4, 5), Point(2, 1)), 1)); - input.push_back(std::make_pair(half_edge(Point(2, 5), Point(2, 1)), 2)); - input.push_back(std::make_pair(half_edge(Point(4, 1), Point(5, 3)), 3)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail4 2 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - //1 0 -4 -1: 0; 0 0 2 -1: 1; - input.clear(); - edges.clear(); - input.push_back(std::make_pair(half_edge(Point(1, 0), Point(-4, -1)), 0)); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(2, -1)), 1)); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail2 5 " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - Unit min_c =0; - Unit max_c =0; - for(unsigned int outer = 0; outer < 1000; ++outer) { - input.clear(); - for(unsigned int i = 0; i < 4; ++i) { - Unit x1 = rand(); - Unit x2 = rand(); - Unit y1 = rand(); - Unit y2 = rand(); - int neg1 = rand() % 2; - if(neg1) x1 *= -1; - int neg2 = rand() % 2; - if(neg2) x2 *= -1; - int neg3 = rand() % 2; - if(neg3) y1 *= -1; - int neg4 = rand() % 2; - if(neg4) y2 *= -1; - if(x1 < min_c) min_c = x1; - if(x2 < min_c) min_c = x2; - if(y1 < min_c) min_c = y1; - if(y2 < min_c) min_c = y2; - if(x1 > max_c) max_c = x1; - if(x2 > max_c) max_c = x2; - if(y1 > max_c) max_c = y1; - if(y2 > max_c) max_c = y2; - Point pt1(x1, y1); - Point pt2(x2, y2); - if(pt1 != pt2) - input.push_back(std::make_pair(half_edge(pt1, pt2), i)); - } - edges.clear(); - validate_scan(edges, input.begin(), input.end()); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "s fail9 " << outer << ": " << result.first << " " << result.second << "\n"; - print(input); - print(edges); - return false; - } - } - return true; - } - - //static void print(const std::pair<half_edge, segment_id>& segment) { - //std::cout << segment.first.first << " " << segment.first.second << ": " << segment.second << "; "; - //} - static void print(const std::vector<std::pair<half_edge, segment_id> >& vec) { - for(std::size_t i = 0; i < vec.size(); ++ i) { - // print(vec[i]); - } - //std::cout << "\n"; - } - - template <typename stream_type> - static inline bool test_verify_scan(stream_type& stdcout) { - std::vector<std::pair<half_edge, segment_id> > edges; - edges.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), 0)); - edges.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 10)), 1)); - std::pair<segment_id, segment_id> result; - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail1\n"; - return false; - } - edges.push_back(std::make_pair(half_edge(Point(0, 5), Point(5, 5)), 2)); - if(verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail2\n"; - return false; - } - edges.pop_back(); - edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(11, 11)), (segment_id)edges.size())); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail3\n"; - return false; - } - edges.push_back(std::make_pair(half_edge(Point(1, 0), Point(10, 11)), (segment_id)edges.size())); - if(verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail4\n"; - return false; - } - edges.pop_back(); - edges.push_back(std::make_pair(half_edge(Point(1, 2), Point(11, 11)), (segment_id)edges.size())); - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail5 " << result.first << " " << result.second << "\n"; - return false; - } - edges.push_back(std::make_pair(half_edge(Point(0, 5), Point(0, 11)), (segment_id)edges.size())); - if(verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail6 " << result.first << " " << result.second << "\n"; - return false; - } - edges.pop_back(); - for(std::size_t i = 0; i < edges.size(); ++i) { - std::swap(edges[i].first.first, edges[i].first.second); - } - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail5 2 " << result.first << " " << result.second << "\n"; - return false; - } - for(std::size_t i = 0; i < edges.size(); ++i) { - edges[i].first.first = Point(edges[i].first.first.get(HORIZONTAL) * -1, - edges[i].first.first.get(VERTICAL) * -1); - edges[i].first.second = Point(edges[i].first.second.get(HORIZONTAL) * -1, - edges[i].first.second.get(VERTICAL) * -1); - } - if(!verify_scan(result, edges.begin(), edges.end())) { - stdcout << "fail5 3 " << result.first << " " << result.second << "\n"; - return false; - } - return true; - } - - }; - - //scanline consumes the "flattened" fully intersected line segments produced by - //a pass of line_intersection along with property and count information and performs a - //useful operation like booleans or property merge or connectivity extraction - template <typename Unit, typename property_type, typename keytype = std::set<property_type> > - class scanline : public scanline_base<Unit> { - public: - //definitions - typedef typename scanline_base<Unit>::Point Point; - - //the first point is the vertex and and second point establishes the slope of an edge eminating from the vertex - //typedef std::pair<Point, Point> half_edge; - typedef typename scanline_base<Unit>::half_edge half_edge; - - //scanline comparator functor - typedef typename scanline_base<Unit>::less_half_edge less_half_edge; - typedef typename scanline_base<Unit>::less_point less_point; - - typedef keytype property_set; - //this is the data type used internally to store the combination of property counts at a given location - typedef std::vector<std::pair<property_type, int> > property_map; - //this data structure assocates a property and count to a half edge - typedef std::pair<half_edge, std::pair<property_type, int> > vertex_property; - //this data type is used internally to store the combined property data for a given half edge - typedef std::pair<half_edge, property_map> vertex_data; - //this data type stores the combination of many half edges - typedef std::vector<vertex_property> property_merge_data; - //this data structure stores end points of edges in the scanline - typedef std::set<Point, less_point> end_point_queue; - - //this is the output data type that is created by the scanline before it is post processed based on content of property sets - typedef std::pair<half_edge, std::pair<property_set, property_set> > half_edge_property; - - //this is the scanline data structure - typedef std::map<half_edge, property_map, less_half_edge> scanline_type; - typedef std::pair<half_edge, property_map> scanline_element; - typedef typename scanline_type::iterator iterator; - typedef typename scanline_type::const_iterator const_iterator; - - //data - scanline_type scan_data_; - std::vector<iterator> removal_set_; //edges to be removed at the current scanline stop - std::vector<scanline_element> insertion_set_; //edge to be inserted after current scanline stop - end_point_queue end_point_queue_; - Unit x_; - Unit y_; - int just_before_; - typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_; - public: - inline scanline() : scan_data_(), removal_set_(), insertion_set_(), end_point_queue_(), - x_((std::numeric_limits<Unit>::max)()), y_((std::numeric_limits<Unit>::max)()), just_before_(false), evalAtXforYPack_() { - less_half_edge lessElm(&x_, &just_before_, &evalAtXforYPack_); - scan_data_ = scanline_type(lessElm); - } - inline scanline(const scanline& that) : scan_data_(), removal_set_(), insertion_set_(), end_point_queue_(), - x_((std::numeric_limits<Unit>::max)()), y_((std::numeric_limits<Unit>::max)()), just_before_(false), evalAtXforYPack_() { - (*this) = that; } - inline scanline& operator=(const scanline& that) { - x_ = that.x_; - y_ = that.y_; - just_before_ = that.just_before_; - end_point_queue_ = that.end_point_queue_; - //I cannot simply copy that.scanline_type to this scanline_type becuase the functor store pointers to other members! - less_half_edge lessElm(&x_, &just_before_); - scan_data_ = scanline_type(lessElm); - - scan_data_.insert(that.scan_data_.begin(), that.scan_data_.end()); - return *this; - } - - template <typename result_type, typename result_functor> - void write_out(result_type& result, result_functor rf, const half_edge& he, - const property_map& pm_left, const property_map& pm_right) { - //std::cout << "write out "; - //std::cout << he.first << ", " << he.second << "\n"; - property_set ps_left, ps_right; - set_unique_property(ps_left, pm_left); - set_unique_property(ps_right, pm_right); - if(ps_left != ps_right) { - //std::cout << "!equivalent\n"; - rf(result, he, ps_left, ps_right); - } - } - - template <typename result_type, typename result_functor, typename iT> - iT handle_input_events(result_type& result, result_functor rf, iT begin, iT end) { - //typedef typename high_precision_type<Unit>::type high_precision; - //for each event - property_map vertical_properties_above; - property_map vertical_properties_below; - half_edge vertical_edge_above; - half_edge vertical_edge_below; - std::vector<scanline_element> insertion_elements; - //current_iter should increase monotonically toward end as we process scanline stop - iterator current_iter = scan_data_.begin(); - just_before_ = true; - Unit y = (std::numeric_limits<Unit>::min)(); - bool first_iteration = true; - //we want to return from inside the loop when we hit end or new x -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - while(true) { - if(begin == end || (!first_iteration && ((*begin).first.first.get(VERTICAL) != y || - (*begin).first.first.get(HORIZONTAL) != x_))) { - //lookup iterator range in scanline for elements coming in from the left - //that end at this y - Point pt(x_, y); - //grab the properties coming in from below - property_map properties_below; - if(current_iter != scan_data_.end()) { - //make sure we are looking at element in scanline just below y - //if(evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) != y) { - if(scanline_base<Unit>::on_above_or_below(Point(x_, y), (*current_iter).first) != 0) { - Point e2(pt); - if(e2.get(VERTICAL) != (std::numeric_limits<Unit>::max)()) - e2.set(VERTICAL, e2.get(VERTICAL) + 1); - else - e2.set(VERTICAL, e2.get(VERTICAL) - 1); - half_edge vhe(pt, e2); - current_iter = scan_data_.lower_bound(vhe); - } - if(current_iter != scan_data_.end()) { - //get the bottom iterator for elements at this point - //while(evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) >= (high_precision)y && - while(scanline_base<Unit>::on_above_or_below(Point(x_, y), (*current_iter).first) != 1 && - current_iter != scan_data_.begin()) { - --current_iter; - } - //if(evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) >= (high_precision)y) { - if(scanline_base<Unit>::on_above_or_below(Point(x_, y), (*current_iter).first) != 1) { - properties_below.clear(); - } else { - properties_below = (*current_iter).second; - //move back up to y or one past y - ++current_iter; - } - } - } - std::vector<iterator> edges_from_left; - while(current_iter != scan_data_.end() && - //can only be true if y is integer - //evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) == y) { - scanline_base<Unit>::on_above_or_below(Point(x_, y), (*current_iter).first) == 0) { - //removal_set_.push_back(current_iter); - ++current_iter; - } - //merge vertical count with count from below - if(!vertical_properties_below.empty()) { - merge_property_maps(vertical_properties_below, properties_below); - //write out vertical edge - write_out(result, rf, vertical_edge_below, properties_below, vertical_properties_below); - } else { - merge_property_maps(vertical_properties_below, properties_below); - } - //iteratively add intertion element counts to count from below - //and write them to insertion set - for(std::size_t i = 0; i < insertion_elements.size(); ++i) { - if(i == 0) { - merge_property_maps(insertion_elements[i].second, vertical_properties_below); - write_out(result, rf, insertion_elements[i].first, insertion_elements[i].second, vertical_properties_below); - } else { - merge_property_maps(insertion_elements[i].second, insertion_elements[i-1].second); - write_out(result, rf, insertion_elements[i].first, insertion_elements[i].second, insertion_elements[i-1].second); - } - insertion_set_.push_back(insertion_elements[i]); - } - if((begin == end || (*begin).first.first.get(HORIZONTAL) != x_)) { - if(vertical_properties_above.empty()) { - return begin; - } else { - y = vertical_edge_above.second.get(VERTICAL); - vertical_properties_below.clear(); - vertical_properties_above.swap(vertical_properties_below); - vertical_edge_below = vertical_edge_above; - insertion_elements.clear(); - continue; - } - } - vertical_properties_below.clear(); - vertical_properties_above.swap(vertical_properties_below); - vertical_edge_below = vertical_edge_above; - insertion_elements.clear(); - } - if(begin != end) { - const vertex_property& vp = *begin; - const half_edge& he = vp.first; - y = he.first.get(VERTICAL); - first_iteration = false; - if(! vertical_properties_below.empty() && - vertical_edge_below.second.get(VERTICAL) < y) { - y = vertical_edge_below.second.get(VERTICAL); - continue; - } - if(scanline_base<Unit>::is_vertical(he)) { - update_property_map(vertical_properties_above, vp.second); - vertical_edge_above = he; - } else { - if(insertion_elements.empty() || - insertion_elements.back().first != he) { - insertion_elements.push_back(scanline_element(he, property_map())); - } - update_property_map(insertion_elements.back().second, vp.second); - } - ++begin; - } - } -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - - } - - inline void erase_end_events(typename end_point_queue::iterator epqi) { - end_point_queue_.erase(end_point_queue_.begin(), epqi); - for(typename std::vector<iterator>::iterator retire_itr = removal_set_.begin(); - retire_itr != removal_set_.end(); ++retire_itr) { - scan_data_.erase(*retire_itr); - } - removal_set_.clear(); - } - - - inline void remove_retired_edges_from_scanline() { - just_before_ = true; - typename end_point_queue::iterator epqi = end_point_queue_.begin(); - Unit current_x = x_; - Unit previous_x = x_; - while(epqi != end_point_queue_.end() && - (*epqi).get(HORIZONTAL) <= current_x) { - x_ = (*epqi).get(HORIZONTAL); - if(x_ != previous_x) erase_end_events(epqi); - previous_x = x_; - //lookup elements - Point e2(*epqi); - if(e2.get(VERTICAL) != (std::numeric_limits<Unit>::max)()) - e2.set(VERTICAL, e2.get(VERTICAL) + 1); - else - e2.set(VERTICAL, e2.get(VERTICAL) - 1); - half_edge vhe_e(*epqi, e2); - iterator current_iter = scan_data_.lower_bound(vhe_e); - while(current_iter != scan_data_.end() && (*current_iter).first.second == (*epqi)) { - //evalAtXforY(x_, (*current_iter).first.first, (*current_iter).first.second) == (*epqi).get(VERTICAL)) { - removal_set_.push_back(current_iter); - ++current_iter; - } - ++epqi; - } - x_ = current_x; - erase_end_events(epqi); - } - - inline void insert_new_edges_into_scanline() { - just_before_ = false; - for(typename std::vector<scanline_element>::iterator insert_itr = insertion_set_.begin(); - insert_itr != insertion_set_.end(); ++insert_itr) { - scan_data_.insert(*insert_itr); - end_point_queue_.insert((*insert_itr).first.second); - } - insertion_set_.clear(); - } - - //iterator over range of vertex property elements and call result functor - //passing edge to be output, the merged data on both sides and the result - template <typename result_type, typename result_functor, typename iT> - void scan(result_type& result, result_functor rf, iT begin, iT end) { - while(begin != end) { - x_ = (*begin).first.first.get(HORIZONTAL); //update scanline stop location - //print_scanline(); - --x_; - remove_retired_edges_from_scanline(); - ++x_; - begin = handle_input_events(result, rf, begin, end); - remove_retired_edges_from_scanline(); - //print_scanline(); - insert_new_edges_into_scanline(); - } - //print_scanline(); - x_ = (std::numeric_limits<Unit>::max)(); - remove_retired_edges_from_scanline(); - } - - //inline void print_scanline() { - // std::cout << "scanline at " << x_ << ": "; - // for(iterator itr = scan_data_.begin(); itr != scan_data_.end(); ++itr) { - // const scanline_element& se = *itr; - // const half_edge& he = se.first; - // const property_map& mp = se.second; - // std::cout << he.first << ", " << he.second << " ( "; - // for(std::size_t i = 0; i < mp.size(); ++i) { - // std::cout << mp[i].first << ":" << mp[i].second << " "; - // } std::cout << ") "; - // } std::cout << "\n"; - //} - - static inline void merge_property_maps(property_map& mp, const property_map& mp2) { - property_map newmp; - newmp.reserve(mp.size() + mp2.size()); - unsigned int i = 0; - unsigned int j = 0; - while(i != mp.size() && j != mp2.size()) { - if(mp[i].first < mp2[j].first) { - newmp.push_back(mp[i]); - ++i; - } else if(mp[i].first > mp2[j].first) { - newmp.push_back(mp2[j]); - ++j; - } else { - int count = mp[i].second; - count += mp2[j].second; - if(count) { - newmp.push_back(mp[i]); - newmp.back().second = count; - } - ++i; - ++j; - } - } - while(i != mp.size()) { - newmp.push_back(mp[i]); - ++i; - } - while(j != mp2.size()) { - newmp.push_back(mp2[j]); - ++j; - } - mp.swap(newmp); - } - - static inline void update_property_map(property_map& mp, const std::pair<property_type, int>& prop_data) { - property_map newmp; - newmp.reserve(mp.size() +1); - bool consumed = false; - for(std::size_t i = 0; i < mp.size(); ++i) { - if(!consumed && prop_data.first == mp[i].first) { - consumed = true; - int count = prop_data.second + mp[i].second; - if(count) - newmp.push_back(std::make_pair(prop_data.first, count)); - } else if(!consumed && prop_data.first < mp[i].first) { - consumed = true; - newmp.push_back(prop_data); - newmp.push_back(mp[i]); - } else { - newmp.push_back(mp[i]); - } - } - if(!consumed) newmp.push_back(prop_data); - mp.swap(newmp); - } - - static inline void set_unique_property(property_set& unqiue_property, const property_map& property) { - unqiue_property.clear(); - for(typename property_map::const_iterator itr = property.begin(); itr != property.end(); ++itr) { - if((*itr).second > 0) - unqiue_property.insert(unqiue_property.end(), (*itr).first); - } - } - - static inline bool common_vertex(const half_edge& he1, const half_edge& he2) { - return he1.first == he2.first || - he1.first == he2.second || - he1.second == he2.first || - he1.second == he2.second; - } - - typedef typename scanline_base<Unit>::vertex_half_edge vertex_half_edge; - template <typename iT> - static inline void convert_segments_to_vertex_half_edges(std::vector<vertex_half_edge>& output, iT begin, iT end) { - for( ; begin != end; ++begin) { - const half_edge& he = (*begin).first; - int count = (*begin).second; - output.push_back(vertex_half_edge(he.first, he.second, count)); - output.push_back(vertex_half_edge(he.second, he.first, -count)); - } - polygon_sort(output.begin(), output.end()); - } - - class test_functor { - public: - inline test_functor() {} - inline void operator()(std::vector<std::pair<half_edge, std::pair<property_set, property_set> > >& result, - const half_edge& he, const property_set& ps_left, const property_set& ps_right) { - result.push_back(std::make_pair(he, std::make_pair(ps_left, ps_right))); - } - }; - template <typename stream_type> - static inline bool test_scanline(stream_type& stdcout) { - std::vector<std::pair<half_edge, std::pair<property_set, property_set> > > result; - std::vector<std::pair<half_edge, std::pair<property_type, int> > > input; - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(10, 10)), std::make_pair(0, -1))); - scanline sl; - test_functor tf; - sl.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(-1, -1), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(-1, -1), Point(0, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(11, 11)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(11, 11)), std::make_pair(0, 1))); - scanline sl2; - sl2.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(1, 1), Point(8, 2)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(1, 1), Point(2, 8)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(2, 8), Point(9, 9)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(8, 2), Point(9, 9)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(10, 10)), std::make_pair(0, -1))); - scanline sl3; - sl3.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(1, 1), Point(8, 2)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(1, 1), Point(2, 8)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(2, 8), Point(9, 9)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(8, 2), Point(9, 9)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(10, 10)), std::make_pair(0, -1))); - scanline sl4; - sl4.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(9, 1)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(1, 9)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(1, 9), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(9, 1), Point(10, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(10, 10)), std::make_pair(0, -1))); - scanline sl5; - sl5.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(9, 1)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(1, 9)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(1, 9), Point(10, 10)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(9, 1), Point(10, 10)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(10, 10)), std::make_pair(0, -1))); - scanline sl6; - sl6.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(10, 0)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(9, 1)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(1, 9)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(0, 0), Point(0, 10)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(10, 10)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(0, 20), Point(10, 20)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 20), Point(9, 21)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 20), Point(1, 29)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(0, 20), Point(0, 30)), std::make_pair(0, 1))); - input.push_back(std::make_pair(half_edge(Point(0, 30), Point(10, 30)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(1, 9), Point(10, 10)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(1, 29), Point(10, 30)), std::make_pair(1, -1))); - input.push_back(std::make_pair(half_edge(Point(9, 1), Point(10, 10)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(9, 21), Point(10, 30)), std::make_pair(1, 1))); - input.push_back(std::make_pair(half_edge(Point(10, 20), Point(10, 30)), std::make_pair(0, -1))); - input.push_back(std::make_pair(half_edge(Point(10, 20), Point(10, 30)), std::make_pair(0, -1))); - scanline sl7; - sl7.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - input.clear(); - result.clear(); - input.push_back(std::make_pair(half_edge(Point(-1, -1), Point(10, 0)), std::make_pair(0, 1))); //a - input.push_back(std::make_pair(half_edge(Point(-1, -1), Point(0, 10)), std::make_pair(0, -1))); //a - input.push_back(std::make_pair(half_edge(Point(0, 10), Point(11, 11)), std::make_pair(0, -1))); //a - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(20, 0)), std::make_pair(0, 1))); //b - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(11, 11)), std::make_pair(0, -1))); //b - input.push_back(std::make_pair(half_edge(Point(10, 0), Point(11, 11)), std::make_pair(0, 1))); //a - input.push_back(std::make_pair(half_edge(Point(11, 11), Point(20, 10)), std::make_pair(0, -1))); //b - input.push_back(std::make_pair(half_edge(Point(20, 0), Point(30, 0)), std::make_pair(0, 1))); //c - input.push_back(std::make_pair(half_edge(Point(20, 0), Point(20, 10)), std::make_pair(0, -1))); //b - input.push_back(std::make_pair(half_edge(Point(20, 0), Point(20, 10)), std::make_pair(0, 1))); //c - input.push_back(std::make_pair(half_edge(Point(20, 10), Point(30, 10)), std::make_pair(0, -1))); //c - input.push_back(std::make_pair(half_edge(Point(30, 0), Point(30, 10)), std::make_pair(0, -1))); //c - scanline sl8; - sl8.scan(result, tf, input.begin(), input.end()); - stdcout << "scanned\n"; - for(std::size_t i = 0; i < result.size(); ++i) { - stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << "\n"; - return true; - } - - }; - - template <typename Unit> - class merge_output_functor { - public: - typedef typename scanline_base<Unit>::half_edge half_edge; - merge_output_functor() {} - template <typename result_type, typename key_type> - void operator()(result_type& result, const half_edge& edge, const key_type& left, const key_type& right) { - typename std::pair<half_edge, int> elem; - elem.first = edge; - elem.second = 1; - if(edge.second < edge.first) elem.second *= -1; - if(scanline_base<Unit>::is_vertical(edge)) elem.second *= -1; - if(!left.empty()) - result[left].insert_clean(elem); - elem.second *= -1; - if(!right.empty()) - result[right].insert_clean(elem); - } - }; - - template <typename Unit, typename property_type, typename key_type = std::set<property_type>, - typename output_functor_type = merge_output_functor<Unit> > - class property_merge : public scanline_base<Unit> { - protected: - typedef typename scanline_base<Unit>::Point Point; - - //the first point is the vertex and and second point establishes the slope of an edge eminating from the vertex - //typedef std::pair<Point, Point> half_edge; - typedef typename scanline_base<Unit>::half_edge half_edge; - - //scanline comparator functor - typedef typename scanline_base<Unit>::less_half_edge less_half_edge; - typedef typename scanline_base<Unit>::less_point less_point; - - //this data structure assocates a property and count to a half edge - typedef std::pair<half_edge, std::pair<property_type, int> > vertex_property; - //this data type stores the combination of many half edges - typedef std::vector<vertex_property> property_merge_data; - - //this is the data type used internally to store the combination of property counts at a given location - typedef std::vector<std::pair<property_type, int> > property_map; - //this data type is used internally to store the combined property data for a given half edge - typedef std::pair<half_edge, property_map> vertex_data; - - property_merge_data pmd; - typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_; - - template<typename vertex_data_type> - class less_vertex_data { - typename scanline_base<Unit>::evalAtXforYPack* pack_; - public: - less_vertex_data() : pack_() {} - less_vertex_data(typename scanline_base<Unit>::evalAtXforYPack* pack) : pack_(pack) {} - bool operator() (const vertex_data_type& lvalue, const vertex_data_type& rvalue) const { - less_point lp; - if(lp(lvalue.first.first, rvalue.first.first)) return true; - if(lp(rvalue.first.first, lvalue.first.first)) return false; - Unit x = lvalue.first.first.get(HORIZONTAL); - int just_before_ = 0; - less_half_edge lhe(&x, &just_before_, pack_); - return lhe(lvalue.first, rvalue.first); - } - }; - - - inline void sort_property_merge_data() { - less_vertex_data<vertex_property> lvd(&evalAtXforYPack_); - polygon_sort(pmd.begin(), pmd.end(), lvd); - } - public: - inline property_merge_data& get_property_merge_data() { return pmd; } - inline property_merge() : pmd(), evalAtXforYPack_() {} - inline property_merge(const property_merge& pm) : pmd(pm.pmd), evalAtXforYPack_(pm.evalAtXforYPack_) {} - inline property_merge& operator=(const property_merge& pm) { pmd = pm.pmd; return *this; } - - template <typename polygon_type> - void insert(const polygon_type& polygon_object, const property_type& property_value, bool is_hole = false) { - insert(polygon_object, property_value, is_hole, typename geometry_concept<polygon_type>::type()); - } - - //result type should be std::map<std::set<property_type>, polygon_set_type> - //or std::map<std::vector<property_type>, polygon_set_type> - template <typename result_type> - void merge(result_type& result) { - if(pmd.empty()) return; - //intersect data - property_merge_data tmp_pmd; - line_intersection<Unit>::validate_scan(tmp_pmd, pmd.begin(), pmd.end()); - pmd.swap(tmp_pmd); - sort_property_merge_data(); - scanline<Unit, property_type, key_type> sl; - output_functor_type mof; - sl.scan(result, mof, pmd.begin(), pmd.end()); - } - - inline bool verify1() { - std::pair<int, int> offenders; - std::vector<std::pair<half_edge, int> > lines; - int count = 0; - for(std::size_t i = 0; i < pmd.size(); ++i) { - lines.push_back(std::make_pair(pmd[i].first, count++)); - } - if(!line_intersection<Unit>::verify_scan(offenders, lines.begin(), lines.end())) { - //stdcout << "Intersection failed!\n"; - //stdcout << offenders.first << " " << offenders.second << "\n"; - return false; - } - std::vector<Point> pts; - for(std::size_t i = 0; i < lines.size(); ++i) { - pts.push_back(lines[i].first.first); - pts.push_back(lines[i].first.second); - } - polygon_sort(pts.begin(), pts.end()); - for(std::size_t i = 0; i < pts.size(); i+=2) { - if(pts[i] != pts[i+1]) { - //stdcout << "Non-closed figures after line intersection!\n"; - return false; - } - } - return true; - } - - void clear() {*this = property_merge();} - - protected: - template <typename polygon_type> - void insert(const polygon_type& polygon_object, const property_type& property_value, bool is_hole, - polygon_concept ) { - bool first_iteration = true; - bool second_iteration = true; - Point first_point; - Point second_point; - Point previous_previous_point; - Point previous_point; - Point current_point; - direction_1d winding_dir = winding(polygon_object); - for(typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon_object); - itr != end_points(polygon_object); ++itr) { - assign(current_point, *itr); - if(first_iteration) { - first_iteration = false; - first_point = previous_point = current_point; - } else if(second_iteration) { - if(previous_point != current_point) { - second_iteration = false; - previous_previous_point = previous_point; - second_point = previous_point = current_point; - } - } else { - if(previous_point != current_point) { - create_vertex(pmd, previous_point, current_point, winding_dir, - is_hole, property_value); - previous_previous_point = previous_point; - previous_point = current_point; - } - } - } - current_point = first_point; - if(!first_iteration && !second_iteration) { - if(previous_point != current_point) { - create_vertex(pmd, previous_point, current_point, winding_dir, - is_hole, property_value); - previous_previous_point = previous_point; - previous_point = current_point; - } - current_point = second_point; - create_vertex(pmd, previous_point, current_point, winding_dir, - is_hole, property_value); - previous_previous_point = previous_point; - previous_point = current_point; - } - } - - template <typename polygon_with_holes_type> - void insert(const polygon_with_holes_type& polygon_with_holes_object, const property_type& property_value, bool is_hole, - polygon_with_holes_concept) { - insert(polygon_with_holes_object, property_value, is_hole, polygon_concept()); - for(typename polygon_with_holes_traits<polygon_with_holes_type>::iterator_holes_type itr = - begin_holes(polygon_with_holes_object); - itr != end_holes(polygon_with_holes_object); ++itr) { - insert(*itr, property_value, !is_hole, polygon_concept()); - } - } - - template <typename rectangle_type> - void insert(const rectangle_type& rectangle_object, const property_type& property_value, bool is_hole, - rectangle_concept ) { - polygon_90_data<Unit> poly; - assign(poly, rectangle_object); - insert(poly, property_value, is_hole, polygon_concept()); - } - - public: //change to private when done testing - - static inline void create_vertex(property_merge_data& pmd, - const Point& current_point, - const Point& next_point, - direction_1d winding, - bool is_hole, const property_type& property) { - if(current_point == next_point) return; - vertex_property current_vertex; - current_vertex.first.first = current_point; - current_vertex.first.second = next_point; - current_vertex.second.first = property; - int multiplier = 1; - if(winding == CLOCKWISE) - multiplier = -1; - if(is_hole) - multiplier *= -1; - if(current_point < next_point) { - multiplier *= -1; - std::swap(current_vertex.first.first, current_vertex.first.second); - } - current_vertex.second.second = multiplier * (euclidean_distance(next_point, current_point, HORIZONTAL) == 0 ? -1: 1); - pmd.push_back(current_vertex); - //current_vertex.first.second = previous_point; - //current_vertex.second.second *= -1; - //pmd.push_back(current_vertex); - } - - static inline void sort_vertex_half_edges(vertex_data& vertex) { - less_half_edge_pair lessF(vertex.first); - polygon_sort(vertex.second.begin(), vertex.second.end(), lessF); - } - - class less_half_edge_pair { - private: - Point pt_; - public: - less_half_edge_pair(const Point& pt) : pt_(pt) {} - bool operator()(const half_edge& e1, const half_edge& e2) { - const Point& pt1 = e1.first; - const Point& pt2 = e2.first; - if(get(pt1, HORIZONTAL) == - get(pt_, HORIZONTAL)) { - //vertical edge is always largest - return false; - } - if(get(pt2, HORIZONTAL) == - get(pt_, HORIZONTAL)) { - //if half edge 1 is not vertical its slope is less than that of half edge 2 - return get(pt1, HORIZONTAL) != get(pt2, HORIZONTAL); - } - return scanline_base<Unit>::less_slope(get(pt_, HORIZONTAL), - get(pt_, VERTICAL), pt1, pt2); - } - }; - - public: - //test functions - template <typename stream_type> - static stream_type& print (stream_type& o, const property_map& c) - { - o << "count: {"; - for(typename property_map::const_iterator itr = c.begin(); itr != c.end(); ++itr) { - o << ((*itr).first) << ":" << ((*itr).second) << " "; - } - return o << "} "; - } - - - template <typename stream_type> - static stream_type& print (stream_type& o, const half_edge& he) - { - o << "half edge: ("; - o << (he.first); - return o << ", " << (he.second) << ") "; - } - - template <typename stream_type> - static stream_type& print (stream_type& o, const vertex_property& c) - { - o << "vertex property: {"; - print(o, c.first); - o << ", " << c.second.first << ":" << c.second.second << " "; - return o; - } - - template <typename stream_type> - static stream_type& print (stream_type& o, const std::vector<vertex_property>& hev) - { - o << "vertex properties: {"; - for(std::size_t i = 0; i < hev.size(); ++i) { - print(o, (hev[i])) << " "; - } - return o << "} "; - } - - template <typename stream_type> - static stream_type& print (stream_type& o, const std::vector<half_edge>& hev) - { - o << "half edges: {"; - for(std::size_t i = 0; i < hev.size(); ++i) { - print(o, (hev[i])) << " "; - } - return o << "} "; - } - - template <typename stream_type> - static stream_type& print (stream_type& o, const vertex_data& v) - { - return print(o << "vertex: <" << (v.first) << ", ", (v.second)) << "> "; - } - - template <typename stream_type> - static stream_type& print (stream_type& o, const std::vector<vertex_data>& vv) - { - o << "vertices: {"; - for(std::size_t i = 0; i < vv.size(); ++i) { - print(o, (vv[i])) << " "; - } - return o << "} "; - } - - - - template <typename stream_type> - static inline bool test_insertion(stream_type& stdcout) { - property_merge si; - rectangle_data<Unit> rect; - xl(rect, 0); - yl(rect, 1); - xh(rect, 10); - yh(rect, 11); - - si.insert(rect, 333); - print(stdcout, si.pmd) << "\n"; - - Point pts[4] = {Point(0, 0), Point(10,-3), Point(13, 8), Point(0, 0) }; - polygon_data<Unit> poly; - property_merge si2; - poly.set(pts, pts+3); - si2.insert(poly, 444); - si2.sort_property_merge_data(); - print(stdcout, si2.pmd) << "\n"; - property_merge si3; - poly.set(pts, pts+4); - si3.insert(poly, 444); - si3.sort_property_merge_data(); - stdcout << (si2.pmd == si3.pmd) << "\n"; - std::reverse(pts, pts+4); - property_merge si4; - poly.set(pts, pts+4); - si4.insert(poly, 444); - si4.sort_property_merge_data(); - print(stdcout, si4.pmd) << "\n"; - stdcout << (si2.pmd == si4.pmd) << "\n"; - std::reverse(pts, pts+3); - property_merge si5; - poly.set(pts, pts+4); - si5.insert(poly, 444); - si5.sort_property_merge_data(); - stdcout << (si2.pmd == si5.pmd) << "\n"; - - return true; - } - - template <typename stream_type> - static inline bool test_merge(stream_type& stdcout) { - property_merge si; - rectangle_data<Unit> rect; - xl(rect, 0); - yl(rect, 1); - xh(rect, 10); - yh(rect, 11); - - si.insert(rect, 333); - std::map<std::set<property_type>, polygon_set_data<Unit> > result; - si.merge(result); - print(stdcout, si.pmd) << "\n"; - polygon_set_data<Unit> psd = (*(result.begin())).second; - std::vector<polygon_data<Unit> > polys; - psd.get(polys); - if(polys.size() != 1) { - stdcout << "fail merge 1\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - si.clear(); - std::vector<Point> pts; - pts.push_back(Point(0, 0)); - pts.push_back(Point(10, -10)); - pts.push_back(Point(10, 10)); - polygon_data<Unit> poly; - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(5, 0)); - pts.push_back(Point(-5, -10)); - pts.push_back(Point(-5, 10)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() != 1) { - stdcout << "fail merge 2\n"; - return false; - } - //Polygon { -4 -1, 3 3, -2 3 } - //Polygon { 0 -4, -4 -2, -2 1 } - si.clear(); - pts.clear(); - pts.push_back(Point(-4, -1)); - pts.push_back(Point(3, 3)); - pts.push_back(Point(-2, 3)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(0, -4)); - pts.push_back(Point(-4, -2)); - pts.push_back(Point(-2, 1)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() != 1) { - stdcout << "fail merge 3\n"; - return false; - } - stdcout << "Polygon { -2 2, -2 2, 1 4 } \n"; - stdcout << "Polygon { 2 4, 2 -4, -3 1 } \n"; - si.clear(); - pts.clear(); - pts.push_back(Point(-2, 2)); - pts.push_back(Point(-2, 2)); - pts.push_back(Point(1, 4)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(2, 4)); - pts.push_back(Point(2, -4)); - pts.push_back(Point(-3, 1)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() != 1) { - stdcout << "fail merge 4\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - stdcout << "Polygon { -4 0, -2 -3, 3 -4 } \n"; - stdcout << "Polygon { -1 1, 1 -2, -4 -3 } \n"; - si.clear(); - pts.clear(); - pts.push_back(Point(-4, 0)); - pts.push_back(Point(-2, -3)); - pts.push_back(Point(3, -4)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(-1, 1)); - pts.push_back(Point(1, -2)); - pts.push_back(Point(-4, -3)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() != 1) { - stdcout << "fail merge 5\n"; - return false; - } - stdcout << "Polygon { 2 2, -2 0, 0 1 } \n"; - stdcout << "Polygon { 4 -2, 3 -1, 2 3 } \n"; - si.clear(); - pts.clear(); - pts.push_back(Point(2, 2)); - pts.push_back(Point(-2, 0)); - pts.push_back(Point(0, 1)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(4, -2)); - pts.push_back(Point(3, -1)); - pts.push_back(Point(2, 3)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - if(!result.empty()) { - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() != 1) { - stdcout << "fail merge 6\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - } - stdcout << "Polygon { 0 2, 3 -1, 4 1 } \n"; - stdcout << "Polygon { -4 3, 3 3, 4 2 } \n"; - si.clear(); - pts.clear(); - pts.push_back(Point(0, 2)); - pts.push_back(Point(3, -1)); - pts.push_back(Point(4, 1)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(-4, 3)); - pts.push_back(Point(3, 3)); - pts.push_back(Point(4, 2)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - if(!result.empty()) { - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() == 0) { - stdcout << "fail merge 7\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - } -stdcout << "Polygon { 1 -2, -1 4, 3 -2 } \n"; -stdcout << "Polygon { 0 -3, 3 1, -3 -4 } \n"; - si.clear(); - pts.clear(); - pts.push_back(Point(1, -2)); - pts.push_back(Point(-1, 4)); - pts.push_back(Point(3, -2)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(0, -3)); - pts.push_back(Point(3, 1)); - pts.push_back(Point(-3, -4)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - if(!result.empty()) { - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() == 0) { - stdcout << "fail merge 8\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - } -stdcout << "Polygon { 2 2, 3 0, -3 4 } \n"; -stdcout << "Polygon { -2 -2, 0 0, -1 -1 } \n"; - si.clear(); - pts.clear(); - pts.push_back(Point(2, 2)); - pts.push_back(Point(3, 0)); - pts.push_back(Point(-3, 4)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - pts.clear(); - pts.push_back(Point(-2, -2)); - pts.push_back(Point(0, 0)); - pts.push_back(Point(-1, -1)); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - if(!result.empty()) { - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() == 0) { - stdcout << "fail merge 9\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - } - si.clear(); - pts.clear(); - //5624841,17616200,75000,9125000 - //pts.push_back(Point(5624841,75000)); - //pts.push_back(Point(5624841,9125000)); - //pts.push_back(Point(17616200,9125000)); - //pts.push_back(Point(17616200,75000)); -pts.push_back(Point(12262940, 6652520 )); pts.push_back(Point(12125750, 6652520 )); pts.push_back(Point(12121272, 6652961 )); pts.push_back(Point(12112981, 6656396 )); pts.push_back(Point(12106636, 6662741 )); pts.push_back(Point(12103201, 6671032 )); pts.push_back(Point(12103201, 6680007 )); pts.push_back(Point(12106636, 6688298 )); -pts.push_back(Point(12109500, 6691780 )); pts.push_back(Point(12748600, 7330890 )); pts.push_back(Point(15762600, 7330890 )); pts.push_back(Point(15904620, 7472900 )); pts.push_back(Point(15909200, 7473030 )); pts.push_back(Point(15935830, 7476006 )); pts.push_back(Point(15992796, 7499602 )); pts.push_back(Point(16036397, 7543203 )); -pts.push_back(Point(16059993, 7600169 )); pts.push_back(Point(16059993, 7661830 )); pts.push_back(Point(16036397, 7718796 )); pts.push_back(Point(15992796, 7762397 )); pts.push_back(Point(15935830, 7785993 )); pts.push_back(Point(15874169, 7785993 )); pts.push_back(Point(15817203, 7762397 )); pts.push_back(Point(15773602, 7718796 )); -pts.push_back(Point(15750006, 7661830 )); pts.push_back(Point(15747030, 7635200 )); pts.push_back(Point(15746900, 7630620 )); pts.push_back(Point(15670220, 7553930 )); pts.push_back(Point(14872950, 7553930 )); pts.push_back(Point(14872950, 7626170 )); -pts.push_back(Point(14869973, 7661280 )); pts.push_back(Point(14846377, 7718246 )); pts.push_back(Point(14802776, 7761847 )); pts.push_back(Point(14745810, 7785443 )); pts.push_back(Point(14684149, 7785443 )); pts.push_back(Point(14627183, 7761847 )); pts.push_back(Point(14583582, 7718246 )); -pts.push_back(Point(14559986, 7661280 )); pts.push_back(Point(14557070, 7636660 )); pts.push_back(Point(14556670, 7625570 )); pts.push_back(Point(13703330, 7625570 )); pts.push_back(Point(13702930, 7636660 )); pts.push_back(Point(13699993, 7661830 )); pts.push_back(Point(13676397, 7718796 )); -pts.push_back(Point(13632796, 7762397 )); pts.push_back(Point(13575830, 7785993 )); pts.push_back(Point(13514169, 7785993 )); pts.push_back(Point(13457203, 7762397 )); pts.push_back(Point(13436270, 7745670 )); pts.push_back(Point(13432940, 7742520 )); pts.push_back(Point(12963760, 7742520 )); -pts.push_back(Point(12959272, 7742961 )); pts.push_back(Point(12950981, 7746396 )); pts.push_back(Point(12944636, 7752741 )); pts.push_back(Point(12941201, 7761032 )); pts.push_back(Point(12941201, 7770007 )); pts.push_back(Point(12944636, 7778298 )); pts.push_back(Point(12947490, 7781780 )); -pts.push_back(Point(13425330, 8259620 )); pts.push_back(Point(15601330, 8259620 )); pts.push_back(Point(15904620, 8562900 )); pts.push_back(Point(15909200, 8563030 )); pts.push_back(Point(15935830, 8566006 )); pts.push_back(Point(15992796, 8589602 )); pts.push_back(Point(16036397, 8633203 )); -pts.push_back(Point(16059993, 8690169 )); pts.push_back(Point(16059993, 8751830 )); pts.push_back(Point(16036397, 8808796 )); pts.push_back(Point(15992796, 8852397 )); pts.push_back(Point(15935830, 8875993 )); pts.push_back(Point(15874169, 8875993 )); pts.push_back(Point(15817203, 8852397 )); pts.push_back(Point(15773602, 8808796 )); -pts.push_back(Point(15750006, 8751830 )); pts.push_back(Point(15747030, 8725200 )); pts.push_back(Point(15746900, 8720620 )); pts.push_back(Point(15508950, 8482660 )); pts.push_back(Point(14689890, 8482660 )); pts.push_back(Point(14685412, 8483101 )); pts.push_back(Point(14677121, 8486536 )); -pts.push_back(Point(14670776, 8492881 )); pts.push_back(Point(14667341, 8501172 )); pts.push_back(Point(14667341, 8510147 )); pts.push_back(Point(14670776, 8518438 )); pts.push_back(Point(14673630, 8521920 )); pts.push_back(Point(14714620, 8562900 )); pts.push_back(Point(14719200, 8563030 )); pts.push_back(Point(14745830, 8566006 )); -pts.push_back(Point(14802796, 8589602 )); pts.push_back(Point(14846397, 8633203 )); pts.push_back(Point(14869993, 8690169 )); pts.push_back(Point(14869993, 8751830 )); pts.push_back(Point(14846397, 8808796 )); pts.push_back(Point(14802796, 8852397 )); pts.push_back(Point(14745830, 8875993 )); pts.push_back(Point(14684169, 8875993 )); -pts.push_back(Point(14627203, 8852397 )); pts.push_back(Point(14583602, 8808796 )); pts.push_back(Point(14560006, 8751830 )); pts.push_back(Point(14557030, 8725200 )); pts.push_back(Point(14556900, 8720620 )); pts.push_back(Point(14408270, 8571980 )); pts.push_back(Point(13696320, 8571980 )); pts.push_back(Point(13696320, 8675520 )); -pts.push_back(Point(13699963, 8690161 )); pts.push_back(Point(13699963, 8751818 )); pts.push_back(Point(13676368, 8808781 )); pts.push_back(Point(13632771, 8852378 )); pts.push_back(Point(13575808, 8875973 )); pts.push_back(Point(13514151, 8875973 )); pts.push_back(Point(13457188, 8852378 )); pts.push_back(Point(13436270, 8835670 )); pts.push_back(Point(13432940, 8832520 )); -pts.push_back(Point(13281760, 8832520 )); pts.push_back(Point(13277272, 8832961 )); pts.push_back(Point(13268981, 8836396 )); pts.push_back(Point(13262636, 8842741 )); pts.push_back(Point(13259201, 8851032 )); pts.push_back(Point(13259201, 8860007 )); pts.push_back(Point(13262636, 8868298 )); pts.push_back(Point(13265500, 8871780 )); -pts.push_back(Point(13518710, 9125000 )); pts.push_back(Point(16270720, 9125000 )); pts.push_back(Point(16270720, 8939590 )); pts.push_back(Point(17120780, 8939590 )); pts.push_back(Point(17120780, 9125000 )); pts.push_back(Point(17616200, 9125000 )); pts.push_back(Point(17616200, 75000 )); pts.push_back(Point(16024790, 75000 )); -pts.push_back(Point(16021460, 80700 )); pts.push_back(Point(16016397, 88796 )); pts.push_back(Point(15972796, 132397 )); pts.push_back(Point(15915830, 155993 )); pts.push_back(Point(15908730, 157240 )); pts.push_back(Point(15905000, 157800 )); pts.push_back(Point(15516800, 546000 )); pts.push_back(Point(15905000, 934200 )); -pts.push_back(Point(15908730, 934760 )); pts.push_back(Point(15915830, 936006 )); pts.push_back(Point(15972796, 959602 )); pts.push_back(Point(16016397, 1003203 )); pts.push_back(Point(16039993, 1060169 )); pts.push_back(Point(16039993, 1121830 )); pts.push_back(Point(16016397, 1178796 )); pts.push_back(Point(15972796, 1222397 )); -pts.push_back(Point(15915830, 1245993 )); pts.push_back(Point(15854169, 1245993 )); pts.push_back(Point(15797203, 1222397 )); pts.push_back(Point(15753602, 1178796 )); pts.push_back(Point(15730006, 1121830 )); pts.push_back(Point(15728760, 1114730 )); pts.push_back(Point(15728200, 1111000 )); pts.push_back(Point(15363500, 746300 )); -pts.push_back(Point(14602620, 746300 )); pts.push_back(Point(14598142, 746741 )); pts.push_back(Point(14589851, 750176 )); pts.push_back(Point(14583506, 756521 )); pts.push_back(Point(14580071, 764812 )); pts.push_back(Point(14580071, 773787 )); pts.push_back(Point(14583506, 782078 )); pts.push_back(Point(14586360, 785560 )); -pts.push_back(Point(14586370, 785560 )); pts.push_back(Point(14735000, 934200 )); pts.push_back(Point(14738730, 934760 )); pts.push_back(Point(14745830, 936006 )); pts.push_back(Point(14802796, 959602 )); pts.push_back(Point(14846397, 1003203 )); pts.push_back(Point(14869993, 1060169 )); -pts.push_back(Point(14870450, 1062550 )); pts.push_back(Point(14872170, 1071980 )); pts.push_back(Point(14972780, 1071980 )); pts.push_back(Point(15925000, 2024200 )); pts.push_back(Point(15928730, 2024760 )); pts.push_back(Point(15935830, 2026006 )); pts.push_back(Point(15992796, 2049602 )); -pts.push_back(Point(16036397, 2093203 )); pts.push_back(Point(16059993, 2150169 )); pts.push_back(Point(16059993, 2211830 )); pts.push_back(Point(16036397, 2268796 )); pts.push_back(Point(15992796, 2312397 )); pts.push_back(Point(15935830, 2335993 )); pts.push_back(Point(15874169, 2335993 )); -pts.push_back(Point(15817203, 2312397 )); pts.push_back(Point(15773602, 2268796 )); pts.push_back(Point(15750006, 2211830 )); pts.push_back(Point(15748760, 2204730 )); pts.push_back(Point(15748200, 2201000 )); pts.push_back(Point(14869220, 1322020 )); pts.push_back(Point(14088350, 1322020 )); -pts.push_back(Point(14083862, 1322461 )); pts.push_back(Point(14075571, 1325896 )); pts.push_back(Point(14069226, 1332241 )); pts.push_back(Point(14065791, 1340532 )); pts.push_back(Point(14065791, 1349507 )); pts.push_back(Point(14069226, 1357798 )); pts.push_back(Point(14072080, 1361280 )); -pts.push_back(Point(14072090, 1361280 )); pts.push_back(Point(14735000, 2024200 )); pts.push_back(Point(14738730, 2024760 )); pts.push_back(Point(14745830, 2026006 )); pts.push_back(Point(14802796, 2049602 )); pts.push_back(Point(14846397, 2093203 )); pts.push_back(Point(14869993, 2150169 )); -pts.push_back(Point(14869993, 2211830 )); pts.push_back(Point(14846397, 2268796 )); pts.push_back(Point(14802796, 2312397 )); pts.push_back(Point(14745830, 2335993 )); pts.push_back(Point(14684169, 2335993 )); pts.push_back(Point(14627203, 2312397 )); pts.push_back(Point(14583602, 2268796 )); pts.push_back(Point(14560006, 2211830 )); -pts.push_back(Point(14558760, 2204730 )); pts.push_back(Point(14558200, 2201000 )); pts.push_back(Point(13752220, 1395020 )); pts.push_back(Point(12991340, 1395020 )); pts.push_back(Point(12986862, 1395461 )); pts.push_back(Point(12978571, 1398896 )); pts.push_back(Point(12972226, 1405241 )); -pts.push_back(Point(12968791, 1413532 )); pts.push_back(Point(12968791, 1422507 )); pts.push_back(Point(12972226, 1430798 )); pts.push_back(Point(12975080, 1434280 )); pts.push_back(Point(12975090, 1434280 )); pts.push_back(Point(13565000, 2024200 )); pts.push_back(Point(13568730, 2024760 )); pts.push_back(Point(13575830, 2026006 )); -pts.push_back(Point(13632796, 2049602 )); pts.push_back(Point(13676397, 2093203 )); pts.push_back(Point(13699993, 2150169 )); pts.push_back(Point(13699993, 2211830 )); pts.push_back(Point(13676397, 2268796 )); pts.push_back(Point(13632796, 2312397 )); pts.push_back(Point(13575830, 2335993 )); -pts.push_back(Point(13514169, 2335993 )); pts.push_back(Point(13457203, 2312397 )); pts.push_back(Point(13413602, 2268796 )); pts.push_back(Point(13390006, 2211830 )); pts.push_back(Point(13388760, 2204730 )); pts.push_back(Point(13388200, 2201000 )); pts.push_back(Point(12655220, 1468020 )); -pts.push_back(Point(11894340, 1468020 )); pts.push_back(Point(11889862, 1468461 )); pts.push_back(Point(11881571, 1471896 )); pts.push_back(Point(11875226, 1478241 )); pts.push_back(Point(11871791, 1486532 )); pts.push_back(Point(11871791, 1495507 )); -pts.push_back(Point(11875226, 1503798 )); pts.push_back(Point(11878090, 1507280 )); pts.push_back(Point(12395000, 2024200 )); pts.push_back(Point(12398730, 2024760 )); pts.push_back(Point(12405830, 2026006 )); pts.push_back(Point(12462796, 2049602 )); pts.push_back(Point(12506397, 2093203 )); -pts.push_back(Point(12529993, 2150169 )); pts.push_back(Point(12529993, 2211830 )); pts.push_back(Point(12506397, 2268796 )); pts.push_back(Point(12462796, 2312397 )); pts.push_back(Point(12405830, 2335993 )); pts.push_back(Point(12344169, 2335993 )); -pts.push_back(Point(12287203, 2312397 )); pts.push_back(Point(12243602, 2268796 )); pts.push_back(Point(12220006, 2211830 )); pts.push_back(Point(12218760, 2204730 )); pts.push_back(Point(12218200, 2201000 )); pts.push_back(Point(11558220, 1541020 )); -pts.push_back(Point(10797340, 1541020 )); pts.push_back(Point(10792862, 1541461 )); pts.push_back(Point(10784571, 1544896 )); pts.push_back(Point(10778226, 1551241 )); pts.push_back(Point(10774791, 1559532 )); pts.push_back(Point(10774791, 1568507 )); pts.push_back(Point(10778226, 1576798 )); pts.push_back(Point(10781080, 1580280 )); -pts.push_back(Point(10781090, 1580280 )); pts.push_back(Point(11225000, 2024200 )); pts.push_back(Point(11228730, 2024760 )); pts.push_back(Point(11235830, 2026006 )); pts.push_back(Point(11292796, 2049602 )); pts.push_back(Point(11336397, 2093203 )); pts.push_back(Point(11359993, 2150169 )); -pts.push_back(Point(11359993, 2211830 )); pts.push_back(Point(11336397, 2268796 )); pts.push_back(Point(11292796, 2312397 )); pts.push_back(Point(11235830, 2335993 )); pts.push_back(Point(11174169, 2335993 )); pts.push_back(Point(11117203, 2312397 )); pts.push_back(Point(11073602, 2268796 )); pts.push_back(Point(11050006, 2211830 )); -pts.push_back(Point(11048760, 2204730 )); pts.push_back(Point(11048200, 2201000 )); pts.push_back(Point(10461220, 1614020 )); pts.push_back(Point( 5647400, 1614020 )); pts.push_back(Point( 5642912, 1614461 )); -pts.push_back(Point( 5634621, 1617896 )); pts.push_back(Point( 5628276, 1624241 )); pts.push_back(Point( 5624841, 1632532 )); pts.push_back(Point( 5624841, 1641507 )); pts.push_back(Point( 5628276, 1649798 )); pts.push_back(Point( 5631130, 1653280 )); -pts.push_back(Point( 5688490, 1710640 )); pts.push_back(Point( 9722350, 1710640 )); pts.push_back(Point(10034620, 2022900 )); pts.push_back(Point(10039200, 2023030 )); pts.push_back(Point(10065830, 2026006 )); pts.push_back(Point(10122796, 2049602 )); -pts.push_back(Point(10166397, 2093203 )); pts.push_back(Point(10189993, 2150169 )); pts.push_back(Point(10189993, 2211830 )); pts.push_back(Point(10166397, 2268796 )); pts.push_back(Point(10158620, 2279450 )); pts.push_back(Point(10158620, 2404900 )); pts.push_back(Point(10548950, 2795240 )); -pts.push_back(Point(15586950, 2795240 )); pts.push_back(Point(15904620, 3112900 )); pts.push_back(Point(15909200, 3113030 )); pts.push_back(Point(15935830, 3116006 )); pts.push_back(Point(15992796, 3139602 )); pts.push_back(Point(16036397, 3183203 )); pts.push_back(Point(16059993, 3240169 )); pts.push_back(Point(16059993, 3301830 )); -pts.push_back(Point(16036397, 3358796 )); pts.push_back(Point(15992796, 3402397 )); pts.push_back(Point(15935830, 3425993 )); pts.push_back(Point(15874169, 3425993 )); pts.push_back(Point(15817203, 3402397 )); pts.push_back(Point(15773602, 3358796 )); pts.push_back(Point(15750006, 3301830 )); pts.push_back(Point(15747030, 3275200 )); -pts.push_back(Point(15746900, 3270620 )); pts.push_back(Point(15494570, 3018280 )); pts.push_back(Point(14675510, 3018280 )); pts.push_back(Point(14671032, 3018721 )); pts.push_back(Point(14662741, 3022156 )); pts.push_back(Point(14656396, 3028501 )); pts.push_back(Point(14652961, 3036792 )); -pts.push_back(Point(14652961, 3045767 )); pts.push_back(Point(14656396, 3054058 )); pts.push_back(Point(14659260, 3057540 )); pts.push_back(Point(14714620, 3112900 )); pts.push_back(Point(14719200, 3113030 )); pts.push_back(Point(14745830, 3116006 )); pts.push_back(Point(14802796, 3139602 )); -pts.push_back(Point(14846397, 3183203 )); pts.push_back(Point(14869993, 3240169 )); pts.push_back(Point(14869993, 3301830 )); pts.push_back(Point(14846397, 3358796 )); pts.push_back(Point(14802796, 3402397 )); pts.push_back(Point(14745830, 3425993 )); pts.push_back(Point(14684169, 3425993 )); pts.push_back(Point(14627203, 3402397 )); -pts.push_back(Point(14583602, 3358796 )); pts.push_back(Point(14560006, 3301830 )); pts.push_back(Point(14557030, 3275200 )); pts.push_back(Point(14556900, 3270620 )); pts.push_back(Point(14370700, 3084410 )); pts.push_back(Point(13702830, 3084410 )); pts.push_back(Point(13702830, 3263160 )); -pts.push_back(Point(13700003, 3302210 )); pts.push_back(Point(13676407, 3359176 )); pts.push_back(Point(13632806, 3402777 )); pts.push_back(Point(13575840, 3426373 )); pts.push_back(Point(13514179, 3426373 )); pts.push_back(Point(13457213, 3402777 )); pts.push_back(Point(13413612, 3359176 )); -pts.push_back(Point(13390016, 3302210 )); pts.push_back(Point(13387030, 3275200 )); pts.push_back(Point(13386900, 3270620 )); pts.push_back(Point(13266840, 3150550 )); pts.push_back(Point(12532920, 3150550 )); pts.push_back(Point(12532920, 3264990 )); pts.push_back(Point(12529993, 3301820 )); -pts.push_back(Point(12506397, 3358786 )); pts.push_back(Point(12462796, 3402387 )); pts.push_back(Point(12405830, 3425983 )); pts.push_back(Point(12344169, 3425983 )); pts.push_back(Point(12287203, 3402387 )); pts.push_back(Point(12243602, 3358786 )); pts.push_back(Point(12220006, 3301820 )); pts.push_back(Point(12217030, 3275200 )); -pts.push_back(Point(12216900, 3270620 )); pts.push_back(Point(12157460, 3211170 )); pts.push_back(Point(11362030, 3211170 )); pts.push_back(Point(11360250, 3220520 )); pts.push_back(Point(11359993, 3221830 )); pts.push_back(Point(11336397, 3278796 )); -pts.push_back(Point(11292796, 3322397 )); pts.push_back(Point(11235830, 3345993 )); pts.push_back(Point(11174169, 3345993 )); pts.push_back(Point(11117203, 3322397 )); pts.push_back(Point(11096270, 3305670 )); pts.push_back(Point(11092940, 3302520 )); pts.push_back(Point(10680760, 3302520 )); -pts.push_back(Point(10676272, 3302961 )); pts.push_back(Point(10667981, 3306396 )); pts.push_back(Point(10661636, 3312741 )); pts.push_back(Point(10658201, 3321032 )); pts.push_back(Point(10658201, 3330007 )); pts.push_back(Point(10661636, 3338298 )); pts.push_back(Point(10664500, 3341780 )); -pts.push_back(Point(11264260, 3941550 )); pts.push_back(Point(15643260, 3941550 )); pts.push_back(Point(15904620, 4202900 )); pts.push_back(Point(15909200, 4203030 )); pts.push_back(Point(15935830, 4206006 )); pts.push_back(Point(15992796, 4229602 )); -pts.push_back(Point(16036397, 4273203 )); pts.push_back(Point(16059993, 4330169 )); pts.push_back(Point(16059993, 4391830 )); pts.push_back(Point(16036397, 4448796 )); pts.push_back(Point(15992796, 4492397 )); -pts.push_back(Point(15935830, 4515993 )); pts.push_back(Point(15874169, 4515993 )); pts.push_back(Point(15817203, 4492397 )); pts.push_back(Point(15773602, 4448796 )); pts.push_back(Point(15750006, 4391830 )); pts.push_back(Point(15747030, 4365200 )); pts.push_back(Point(15746900, 4360620 )); -pts.push_back(Point(15550880, 4164590 )); pts.push_back(Point(14825070, 4164590 )); pts.push_back(Point(14825070, 4247610 )); pts.push_back(Point(14846397, 4273213 )); pts.push_back(Point(14869993, 4330179 )); pts.push_back(Point(14869993, 4391840 )); pts.push_back(Point(14846397, 4448806 )); -pts.push_back(Point(14802796, 4492407 )); pts.push_back(Point(14745830, 4516003 )); pts.push_back(Point(14684169, 4516003 )); pts.push_back(Point(14627203, 4492407 )); pts.push_back(Point(14583602, 4448806 )); pts.push_back(Point(14560006, 4391840 )); pts.push_back(Point(14557030, 4365200 )); -pts.push_back(Point(14556900, 4360620 )); pts.push_back(Point(14432520, 4236230 )); pts.push_back(Point(13702830, 4236230 )); pts.push_back(Point(13702830, 4352930 )); pts.push_back(Point(13699993, 4391750 )); pts.push_back(Point(13676397, 4448716 )); -pts.push_back(Point(13632796, 4492317 )); pts.push_back(Point(13575830, 4515913 )); pts.push_back(Point(13514169, 4515913 )); pts.push_back(Point(13457203, 4492317 )); pts.push_back(Point(13413602, 4448716 )); pts.push_back(Point(13390006, 4391750 )); pts.push_back(Point(13387030, 4365200 )); -pts.push_back(Point(13386900, 4360620 )); pts.push_back(Point(13334170, 4307880 )); pts.push_back(Point(12532990, 4307880 )); pts.push_back(Point(12532990, 4357550 )); pts.push_back(Point(12529993, 4391760 )); pts.push_back(Point(12506397, 4448726 )); pts.push_back(Point(12462796, 4492327 )); -pts.push_back(Point(12405830, 4515923 )); pts.push_back(Point(12344169, 4515923 )); pts.push_back(Point(12287203, 4492327 )); pts.push_back(Point(12243602, 4448726 )); pts.push_back(Point(12220006, 4391760 )); pts.push_back(Point(12217970, 4378710 )); pts.push_back(Point(12216810, 4368500 )); -pts.push_back(Point(11363190, 4368500 )); pts.push_back(Point(11362030, 4378710 )); pts.push_back(Point(11359983, 4391828 )); pts.push_back(Point(11336388, 4448791 )); pts.push_back(Point(11292791, 4492388 )); pts.push_back(Point(11235828, 4515983 )); pts.push_back(Point(11174171, 4515983 )); pts.push_back(Point(11117208, 4492388 )); -pts.push_back(Point(11096270, 4475670 )); pts.push_back(Point(11092940, 4472520 )); pts.push_back(Point(11057750, 4472520 )); pts.push_back(Point(11053272, 4472961 )); pts.push_back(Point(11044981, 4476396 )); pts.push_back(Point(11038636, 4482741 )); pts.push_back(Point(11035201, 4491032 )); -pts.push_back(Point(11035201, 4500007 )); pts.push_back(Point(11038636, 4508298 )); pts.push_back(Point(11041490, 4511780 )); pts.push_back(Point(11573490, 5043780 )); pts.push_back(Point(15655490, 5043780 )); pts.push_back(Point(15904620, 5292900 )); -pts.push_back(Point(15909200, 5293030 )); pts.push_back(Point(15935830, 5296006 )); pts.push_back(Point(15992796, 5319602 )); pts.push_back(Point(16036397, 5363203 )); pts.push_back(Point(16059993, 5420169 )); pts.push_back(Point(16059993, 5481830 )); pts.push_back(Point(16036397, 5538796 )); -pts.push_back(Point(15992796, 5582397 )); pts.push_back(Point(15935830, 5605993 )); pts.push_back(Point(15874169, 5605993 )); pts.push_back(Point(15817203, 5582397 )); pts.push_back(Point(15773602, 5538796 )); pts.push_back(Point(15750006, 5481830 )); pts.push_back(Point(15747030, 5455200 )); -pts.push_back(Point(15746900, 5450620 )); pts.push_back(Point(15563110, 5266820 )); pts.push_back(Point(14857380, 5266820 )); pts.push_back(Point(14857380, 5382430 )); pts.push_back(Point(14869993, 5420179 )); pts.push_back(Point(14869993, 5481840 )); pts.push_back(Point(14846397, 5538806 )); pts.push_back(Point(14802796, 5582407 )); -pts.push_back(Point(14745830, 5606003 )); pts.push_back(Point(14684169, 5606003 )); pts.push_back(Point(14627203, 5582407 )); pts.push_back(Point(14583602, 5538806 )); pts.push_back(Point(14560006, 5481840 )); pts.push_back(Point(14557030, 5455200 )); pts.push_back(Point(14556900, 5450620 )); pts.push_back(Point(14444750, 5338460 )); -pts.push_back(Point(13702890, 5338460 )); pts.push_back(Point(13702890, 5364400 )); pts.push_back(Point(13699993, 5401800 )); pts.push_back(Point(13676397, 5458766 )); pts.push_back(Point(13632796, 5502367 )); pts.push_back(Point(13575830, 5525963 )); pts.push_back(Point(13514169, 5525963 )); pts.push_back(Point(13457203, 5502367 )); -pts.push_back(Point(13413602, 5458766 )); pts.push_back(Point(13390006, 5401800 )); pts.push_back(Point(13389230, 5397620 )); pts.push_back(Point(13387590, 5388060 )); pts.push_back(Point(12532960, 5388060 )); pts.push_back(Point(12532960, 5446220 )); pts.push_back(Point(12529993, 5481820 )); -pts.push_back(Point(12506397, 5538786 )); pts.push_back(Point(12462796, 5582387 )); pts.push_back(Point(12405830, 5605983 )); pts.push_back(Point(12344169, 5605983 )); pts.push_back(Point(12287203, 5582387 )); pts.push_back(Point(12266270, 5565670 )); pts.push_back(Point(12262940, 5562520 )); pts.push_back(Point(11737750, 5562520 )); -pts.push_back(Point(11733272, 5562961 )); pts.push_back(Point(11724981, 5566396 )); pts.push_back(Point(11718636, 5572741 )); pts.push_back(Point(11715201, 5581032 )); pts.push_back(Point(11715201, 5590007 )); pts.push_back(Point(11718636, 5598298 )); pts.push_back(Point(11721500, 5601780 )); -pts.push_back(Point(12287760, 6168050 )); pts.push_back(Point(15689760, 6168050 )); pts.push_back(Point(15904620, 6382900 )); pts.push_back(Point(15909200, 6383030 )); pts.push_back(Point(15935830, 6386006 )); pts.push_back(Point(15992796, 6409602 )); -pts.push_back(Point(16036397, 6453203 )); pts.push_back(Point(16059993, 6510169 )); pts.push_back(Point(16059993, 6571830 )); pts.push_back(Point(16036397, 6628796 )); pts.push_back(Point(15992796, 6672397 )); pts.push_back(Point(15935830, 6695993 )); pts.push_back(Point(15874169, 6695993 )); -pts.push_back(Point(15817203, 6672397 )); pts.push_back(Point(15773602, 6628796 )); pts.push_back(Point(15750006, 6571830 )); pts.push_back(Point(15747030, 6545200 )); pts.push_back(Point(15746900, 6540620 )); pts.push_back(Point(15597380, 6391090 )); pts.push_back(Point(14858060, 6391090 )); -pts.push_back(Point(14858060, 6473860 )); pts.push_back(Point(14869993, 6510179 )); pts.push_back(Point(14869993, 6571840 )); pts.push_back(Point(14846397, 6628806 )); pts.push_back(Point(14802796, 6672407 )); pts.push_back(Point(14745830, 6696003 )); pts.push_back(Point(14684169, 6696003 )); -pts.push_back(Point(14627203, 6672407 )); pts.push_back(Point(14583602, 6628806 )); pts.push_back(Point(14560006, 6571840 )); pts.push_back(Point(14557030, 6545200 )); pts.push_back(Point(14556900, 6540620 )); pts.push_back(Point(14479020, 6462730 )); -pts.push_back(Point(13702990, 6462730 )); pts.push_back(Point(13702990, 6537170 )); pts.push_back(Point(13700003, 6571840 )); pts.push_back(Point(13676407, 6628806 )); pts.push_back(Point(13632806, 6672407 )); pts.push_back(Point(13575840, 6696003 )); -pts.push_back(Point(13514179, 6696003 )); pts.push_back(Point(13457213, 6672407 )); pts.push_back(Point(13413612, 6628806 )); pts.push_back(Point(13390016, 6571840 )); pts.push_back(Point(13387040, 6545550 )); pts.push_back(Point(13386710, 6534380 )); -pts.push_back(Point(12533290, 6534380 )); pts.push_back(Point(12532960, 6545550 )); pts.push_back(Point(12529983, 6571828 )); pts.push_back(Point(12506388, 6628791 )); pts.push_back(Point(12462791, 6672388 )); pts.push_back(Point(12405828, 6695983 )); -pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 )); pts.push_back(Point(12266270, 6655670 )); - poly.set(pts.begin(), pts.end()); - si.insert(poly, 444); - result.clear(); - si.merge(result); - si.verify1(); - print(stdcout, si.pmd) << "\n"; - if(!result.empty()) { - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - std::vector<Point> outpts; - for(typename polygon_set_data<Unit>::iterator_type itr = psd.begin(); - itr != psd.end(); ++itr) { - outpts.push_back((*itr).first.first); - outpts.push_back((*itr).first.second); - } - polygon_sort(outpts.begin(), outpts.end()); - for(std::size_t i = 0; i < outpts.size(); i+=2) { - if(outpts[i] != outpts[i+1]) { - stdcout << "Polygon set not a closed figure\n"; - stdcout << i << "\n"; - stdcout << outpts[i] << " " << outpts[i+1] << "\n"; - return 0; - } - } - polys.clear(); - psd.get(polys); - if(polys.size() == 0) { - stdcout << "fail merge 10\n"; - return false; - } - stdcout << (polys[0]) << "\n"; - } - for(unsigned int i = 0; i < 10; ++i) { - stdcout << "random case # " << i << "\n"; - si.clear(); - pts.clear(); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - polygon_data<Unit> poly1; - poly1.set(pts.begin(), pts.end()); - stdcout << poly1 << "\n"; - si.insert(poly1, 444); - pts.clear(); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - polygon_data<Unit> poly2; - poly2.set(pts.begin(), pts.end()); - stdcout << poly2 << "\n"; - si.insert(poly2, 444); - result.clear(); - si.merge(result); - print(stdcout, si.pmd) << "\n"; - if(!result.empty()) { - psd = (*(result.begin())).second; - stdcout << psd << "\n"; - polys.clear(); - psd.get(polys); - if(polys.size() == 0) { - si.clear(); - si.insert(poly1, 333); - result.clear(); - si.merge(result); - psd = (*(result.begin())).second; - std::vector<polygon_data<Unit> > polys1; - psd.get(polys1); - si.clear(); - si.insert(poly2, 333); - result.clear(); - si.merge(result); - psd = (*(result.begin())).second; - std::vector<polygon_data<Unit> > polys2; - psd.get(polys2); - if(!polys1.empty() || !polys2.empty()) { - stdcout << "fail random merge " << i << "\n"; - return false; - } - } - } - if(!polys.empty()) - stdcout << polys.size() << ": " << (polys[0]) << "\n"; - } - return true; - } - - template <typename stream_type> - static inline bool check_rectangle_trio(rectangle_data<Unit> rect1, rectangle_data<Unit> rect2, rectangle_data<Unit> rect3, stream_type& stdcout) { - property_merge si; - std::map<std::set<property_type>, polygon_set_data<Unit> > result; - std::vector<polygon_data<Unit> > polys; - property_merge_90<property_type, Unit> si90; - std::map<std::set<property_type>, polygon_90_set_data<Unit> > result90; - std::vector<polygon_data<Unit> > polys90; - si.insert(rect1, 111); - si90.insert(rect1, 111); - stdcout << rect1 << "\n"; - si.insert(rect2, 222); - si90.insert(rect2, 222); - stdcout << rect2 << "\n"; - si.insert(rect3, 333); - si90.insert(rect3, 333); - stdcout << rect3 << "\n"; - si.merge(result); - si90.merge(result90); - if(result.size() != result90.size()) { - stdcout << "merge failed with size mismatch\n"; - return 0; - } - typename std::map<std::set<property_type>, polygon_90_set_data<Unit> >::iterator itr90 = result90.begin(); - for(typename std::map<std::set<property_type>, polygon_set_data<Unit> >::iterator itr = result.begin(); - itr != result.end(); ++itr) { - for(typename std::set<property_type>::const_iterator set_itr = (*itr).first.begin(); - set_itr != (*itr).first.end(); ++set_itr) { - stdcout << (*set_itr) << " "; - } stdcout << ") \n"; - polygon_set_data<Unit> psd = (*itr).second; - polygon_90_set_data<Unit> psd90 = (*itr90).second; - polys.clear(); - polys90.clear(); - psd.get(polys); - psd90.get(polys90); - if(polys.size() != polys90.size()) { - stdcout << "merge failed with polygon count mismatch\n"; - stdcout << psd << "\n"; - for(std::size_t j = 0; j < polys.size(); ++j) { - stdcout << polys[j] << "\n"; - } - stdcout << "reference\n"; - for(std::size_t j = 0; j < polys90.size(); ++j) { - stdcout << polys90[j] << "\n"; - } - return 0; - } - bool failed = false; - for(std::size_t j = 0; j < polys.size(); ++j) { - stdcout << polys[j] << "\n"; - stdcout << polys90[j] << "\n"; -#ifdef BOOST_POLYGON_ICC -#pragma warning (push) -#pragma warning (disable:1572) -#endif - if(area(polys[j]) != area(polys90[j])) { -#ifdef BOOST_POLYGON_ICC -#pragma warning (pop) -#endif - stdcout << "merge failed with area mismatch\n"; - failed = true; - } - } - if(failed) return 0; - ++itr90; - } - return true; - } - - template <typename stream_type> - static inline bool test_manhattan_intersection(stream_type& stdcout) { - rectangle_data<Unit> rect1, rect2, rect3; - set_points(rect1, (Point(-1, 2)), (Point(1, 4))); - set_points(rect2, (Point(-1, 2)), (Point(2, 3))); - set_points(rect3, (Point(-3, 0)), (Point(4, 2))); - if(!check_rectangle_trio(rect1, rect2, rect3, stdcout)) { - return false; - } - for(unsigned int i = 0; i < 100; ++i) { - property_merge si; - std::map<std::set<property_type>, polygon_set_data<Unit> > result; - std::vector<polygon_data<Unit> > polys; - property_merge_90<property_type, Unit> si90; - std::map<std::set<property_type>, polygon_90_set_data<Unit> > result90; - std::vector<polygon_data<Unit> > polys90; - stdcout << "random case # " << i << "\n"; - set_points(rect1, (Point(rand()%9-4, rand()%9-4)), (Point(rand()%9-4, rand()%9-4))); - set_points(rect2, (Point(rand()%9-4, rand()%9-4)), (Point(rand()%9-4, rand()%9-4))); - set_points(rect3, (Point(rand()%9-4, rand()%9-4)), (Point(rand()%9-4, rand()%9-4))); - if(!check_rectangle_trio(rect1, rect2, rect3, stdcout)) { - return false; - } - } - return true; - } - - template <typename stream_type> - static inline bool test_intersection(stream_type& stdcout) { - property_merge si; - rectangle_data<Unit> rect; - xl(rect, 0); - yl(rect, 10); - xh(rect, 30); - yh(rect, 20); - si.insert(rect, 333); - xl(rect, 10); - yl(rect, 0); - xh(rect, 20); - yh(rect, 30); - si.insert(rect, 444); - xl(rect, 15); - yl(rect, 0); - xh(rect, 25); - yh(rect, 30); - si.insert(rect, 555); - std::map<std::set<property_type>, polygon_set_data<Unit> > result; - si.merge(result); - print(stdcout, si.pmd) << "\n"; - for(typename std::map<std::set<property_type>, polygon_set_data<Unit> >::iterator itr = result.begin(); - itr != result.end(); ++itr) { - stdcout << "( "; - for(typename std::set<property_type>::const_iterator set_itr = (*itr).first.begin(); - set_itr != (*itr).first.end(); ++set_itr) { - stdcout << (*set_itr) << " "; - } stdcout << ") \n"; - polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << "\n"; - std::vector<polygon_data<Unit> > polys; - psd.get(polys); - for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << "\n"; - } - } - std::vector<Point> pts; - std::vector<polygon_data<Unit> > polys; - for(unsigned int i = 0; i < 10; ++i) { - property_merge si2; - stdcout << "random case # " << i << "\n"; - si.clear(); - pts.clear(); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - polygon_data<Unit> poly1; - poly1.set(pts.begin(), pts.end()); - stdcout << poly1 << "\n"; - si.insert(poly1, 444); - si2.insert(poly1, 333); - pts.clear(); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - polygon_data<Unit> poly2; - poly2.set(pts.begin(), pts.end()); - stdcout << poly2 << "\n"; - si.insert(poly2, 444); - si2.insert(poly2, 444); - pts.clear(); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - pts.push_back(Point(rand()%9-4, rand()%9-4)); - polygon_data<Unit> poly3; - poly3.set(pts.begin(), pts.end()); - stdcout << poly3 << "\n"; - si.insert(poly3, 444); - si2.insert(poly3, 555); - result.clear(); - std::map<std::set<property_type>, polygon_set_data<Unit> > result2; - si.merge(result); - si2.merge(result2); - stdcout << "merged result\n"; - for(typename std::map<std::set<property_type>, polygon_set_data<Unit> >::iterator itr = result.begin(); - itr != result.end(); ++itr) { - stdcout << "( "; - for(typename std::set<property_type>::const_iterator set_itr = (*itr).first.begin(); - set_itr != (*itr).first.end(); ++set_itr) { - stdcout << (*set_itr) << " "; - } stdcout << ") \n"; - polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << "\n"; - std::vector<polygon_data<Unit> > polys2; - psd.get(polys2); - for(std::size_t ii = 0; ii < polys2.size(); ++ii) { - stdcout << polys2[ii] << "\n"; - } - } - stdcout << "intersected pmd\n"; - print(stdcout, si2.pmd) << "\n"; - stdcout << "intersected result\n"; - for(typename std::map<std::set<property_type>, polygon_set_data<Unit> >::iterator itr = result2.begin(); - itr != result2.end(); ++itr) { - stdcout << "( "; - for(typename std::set<property_type>::const_iterator set_itr = (*itr).first.begin(); - set_itr != (*itr).first.end(); ++set_itr) { - stdcout << (*set_itr) << " "; - } stdcout << ") \n"; - polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << "\n"; - std::vector<polygon_data<Unit> > polys2; - psd.get(polys2); - for(std::size_t ii = 0; ii < polys2.size(); ++ii) { - stdcout << polys2[ii] << "\n"; - } - } - si.clear(); - for(typename std::map<std::set<property_type>, polygon_set_data<Unit> >::iterator itr = result2.begin(); - itr != result2.end(); ++itr) { - polys.clear(); - (*itr).second.get(polys); - for(std::size_t j = 0; j < polys.size(); ++j) { - si.insert(polys[j], 444); - } - } - result2.clear(); - si.merge(result2); - stdcout << "remerged result\n"; - for(typename std::map<std::set<property_type>, polygon_set_data<Unit> >::iterator itr = result2.begin(); - itr != result2.end(); ++itr) { - stdcout << "( "; - for(typename std::set<property_type>::const_iterator set_itr = (*itr).first.begin(); - set_itr != (*itr).first.end(); ++set_itr) { - stdcout << (*set_itr) << " "; - } stdcout << ") \n"; - polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << "\n"; - std::vector<polygon_data<Unit> > polys2; - psd.get(polys2); - for(std::size_t ii = 0; ii < polys2.size(); ++ii) { - stdcout << polys2[ii] << "\n"; - } - } - std::vector<polygon_data<Unit> > polys2; - polys.clear(); - (*(result.begin())).second.get(polys); - (*(result2.begin())).second.get(polys2); - if(!(polys == polys2)) { - stdcout << "failed intersection check # " << i << "\n"; - return false; - } - } - return true; - } - }; - - template <typename Unit> - class arbitrary_boolean_op : public scanline_base<Unit> { - private: - - typedef int property_type; - typedef typename scanline_base<Unit>::Point Point; - - //the first point is the vertex and and second point establishes the slope of an edge eminating from the vertex - //typedef std::pair<Point, Point> half_edge; - typedef typename scanline_base<Unit>::half_edge half_edge; - - //scanline comparator functor - typedef typename scanline_base<Unit>::less_half_edge less_half_edge; - typedef typename scanline_base<Unit>::less_point less_point; - - //this data structure assocates a property and count to a half edge - typedef std::pair<half_edge, std::pair<property_type, int> > vertex_property; - //this data type stores the combination of many half edges - typedef std::vector<vertex_property> property_merge_data; - - //this is the data type used internally to store the combination of property counts at a given location - typedef std::vector<std::pair<property_type, int> > property_map; - //this data type is used internally to store the combined property data for a given half edge - typedef std::pair<half_edge, property_map> vertex_data; - - property_merge_data pmd; - typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_; - - template<typename vertex_data_type> - class less_vertex_data { - typename scanline_base<Unit>::evalAtXforYPack* pack_; - public: - less_vertex_data() : pack_() {} - less_vertex_data(typename scanline_base<Unit>::evalAtXforYPack* pack) : pack_(pack) {} - bool operator()(const vertex_data_type& lvalue, const vertex_data_type& rvalue) const { - less_point lp; - if(lp(lvalue.first.first, rvalue.first.first)) return true; - if(lp(rvalue.first.first, lvalue.first.first)) return false; - Unit x = lvalue.first.first.get(HORIZONTAL); - int just_before_ = 0; - less_half_edge lhe(&x, &just_before_, pack_); - return lhe(lvalue.first, rvalue.first); - } - }; - - template <typename result_type, typename key_type, int op_type> - class boolean_output_functor { - public: - boolean_output_functor() {} - void operator()(result_type& result, const half_edge& edge, const key_type& left, const key_type& right) { - typename std::pair<half_edge, int> elem; - elem.first = edge; - elem.second = 1; - if(edge.second < edge.first) elem.second *= -1; - if(scanline_base<Unit>::is_vertical(edge)) elem.second *= -1; -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op_type == 0) { //OR - if(!left.empty() && right.empty()) { - result.insert_clean(elem); - } else if(!right.empty() && left.empty()) { - elem.second *= -1; - result.insert_clean(elem); - } - } else if(op_type == 1) { //AND - if(left.size() == 2 && right.size() != 2) { - result.insert_clean(elem); - } else if(right.size() == 2 && left.size() != 2) { - elem.second *= -1; - result.insert_clean(elem); - } - } else if(op_type == 2) { //XOR - if(left.size() == 1 && right.size() != 1) { - result.insert_clean(elem); - } else if(right.size() == 1 && left.size() != 1) { - elem.second *= -1; - result.insert_clean(elem); - } - } else { //SUBTRACT - if(left.size() == 1) { - if((*(left.begin())) == 0) { - result.insert_clean(elem); - } - } -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - if(right.size() == 1) { - if((*(right.begin())) == 0) { - elem.second *= -1; - result.insert_clean(elem); - } - } - } - } - }; - - inline void sort_property_merge_data() { - less_vertex_data<vertex_property> lvd(&evalAtXforYPack_); - polygon_sort(pmd.begin(), pmd.end(), lvd); - } - public: - inline arbitrary_boolean_op() : pmd(), evalAtXforYPack_() {} - inline arbitrary_boolean_op(const arbitrary_boolean_op& pm) : pmd(pm.pmd), evalAtXforYPack_(pm.evalAtXforYPack_) {} - inline arbitrary_boolean_op& operator=(const arbitrary_boolean_op& pm) { pmd = pm.pmd; return *this; } - - enum BOOLEAN_OP_TYPE { - BOOLEAN_OR = 0, - BOOLEAN_AND = 1, - BOOLEAN_XOR = 2, - BOOLEAN_NOT = 3 - }; - template <typename result_type, typename iT1, typename iT2> - inline void execute(result_type& result, iT1 b1, iT1 e1, iT2 b2, iT2 e2, int op) { - //intersect data - insert(b1, e1, 0); - insert(b2, e2, 1); - property_merge_data tmp_pmd; - //#define BOOST_POLYGON_DEBUG_FILE -#ifdef BOOST_POLYGON_DEBUG_FILE - std::fstream debug_file; - debug_file.open("gtl_debug.txt", std::ios::out); - property_merge<Unit, property_type, std::vector<property_type> >::print(debug_file, pmd); - debug_file.close(); -#endif - if(pmd.empty()) - return; - line_intersection<Unit>::validate_scan(tmp_pmd, pmd.begin(), pmd.end()); - pmd.swap(tmp_pmd); - sort_property_merge_data(); - scanline<Unit, property_type, std::vector<property_type> > sl; - if(op == BOOLEAN_OR) { - boolean_output_functor<result_type, std::vector<property_type>, 0> bof; - sl.scan(result, bof, pmd.begin(), pmd.end()); - } else if(op == BOOLEAN_AND) { - boolean_output_functor<result_type, std::vector<property_type>, 1> bof; - sl.scan(result, bof, pmd.begin(), pmd.end()); - } else if(op == BOOLEAN_XOR) { - boolean_output_functor<result_type, std::vector<property_type>, 2> bof; - sl.scan(result, bof, pmd.begin(), pmd.end()); - } else if(op == BOOLEAN_NOT) { - boolean_output_functor<result_type, std::vector<property_type>, 3> bof; - sl.scan(result, bof, pmd.begin(), pmd.end()); - } - } - - inline void clear() {*this = arbitrary_boolean_op();} - - private: - template <typename iT> - void insert(iT b, iT e, int id) { - for(; - b != e; ++b) { - pmd.push_back(vertex_property(half_edge((*b).first.first, (*b).first.second), - std::pair<property_type, int>(id, (*b).second))); - } - } - - }; - - template <typename Unit, typename stream_type> - bool test_arbitrary_boolean_op(stream_type& stdcout) { - polygon_set_data<Unit> psd; - rectangle_data<Unit> rect; - set_points(rect, point_data<Unit>(0, 0), point_data<Unit>(10, 10)); - psd.insert(rect); - polygon_set_data<Unit> psd2; - set_points(rect, point_data<Unit>(5, 5), point_data<Unit>(15, 15)); - psd2.insert(rect); - std::vector<polygon_data<Unit> > pv; - pv.clear(); - arbitrary_boolean_op<Unit> abo; - polygon_set_data<Unit> psd3; - abo.execute(psd3, psd.begin(), psd.end(), psd2.begin(), psd2.end(), arbitrary_boolean_op<Unit>::BOOLEAN_OR); - psd3.get(pv); - for(std::size_t i = 0; i < pv.size(); ++i) { - stdcout << pv[i] << "\n"; - } - pv.clear(); - abo.clear(); - psd3.clear(); - abo.execute(psd3, psd.begin(), psd.end(), psd2.begin(), psd2.end(), arbitrary_boolean_op<Unit>::BOOLEAN_AND); - psd3.get(pv); - for(std::size_t i = 0; i < pv.size(); ++i) { - stdcout << pv[i] << "\n"; - } - pv.clear(); - abo.clear(); - psd3.clear(); - abo.execute(psd3, psd.begin(), psd.end(), psd2.begin(), psd2.end(), arbitrary_boolean_op<Unit>::BOOLEAN_XOR); - psd3.get(pv); - for(std::size_t i = 0; i < pv.size(); ++i) { - stdcout << pv[i] << "\n"; - } - pv.clear(); - abo.clear(); - psd3.clear(); - abo.execute(psd3, psd.begin(), psd.end(), psd2.begin(), psd2.end(), arbitrary_boolean_op<Unit>::BOOLEAN_NOT); - psd3.get(pv); - for(std::size_t i = 0; i < pv.size(); ++i) { - stdcout << pv[i] << "\n"; - } - return true; - } - - - - - - - - - - - - - - - template <typename Unit, typename property_type> - class arbitrary_connectivity_extraction : public scanline_base<Unit> { - private: - - typedef typename scanline_base<Unit>::Point Point; - - //the first point is the vertex and and second point establishes the slope of an edge eminating from the vertex - //typedef std::pair<Point, Point> half_edge; - typedef typename scanline_base<Unit>::half_edge half_edge; - - //scanline comparator functor - typedef typename scanline_base<Unit>::less_half_edge less_half_edge; - typedef typename scanline_base<Unit>::less_point less_point; - - //this data structure assocates a property and count to a half edge - typedef std::pair<half_edge, std::pair<property_type, int> > vertex_property; - //this data type stores the combination of many half edges - typedef std::vector<vertex_property> property_merge_data; - - //this is the data type used internally to store the combination of property counts at a given location - typedef std::vector<std::pair<property_type, int> > property_map; - //this data type is used internally to store the combined property data for a given half edge - typedef std::pair<half_edge, property_map> vertex_data; - - property_merge_data pmd; - typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_; - - template<typename vertex_data_type> - class less_vertex_data { - typename scanline_base<Unit>::evalAtXforYPack* pack_; - public: - less_vertex_data() : pack_() {} - less_vertex_data(typename scanline_base<Unit>::evalAtXforYPack* pack) : pack_(pack) {} - bool operator()(const vertex_data_type& lvalue, const vertex_data_type& rvalue) const { - less_point lp; - if(lp(lvalue.first.first, rvalue.first.first)) return true; - if(lp(rvalue.first.first, lvalue.first.first)) return false; - Unit x = lvalue.first.first.get(HORIZONTAL); - int just_before_ = 0; - less_half_edge lhe(&x, &just_before_, pack_); - return lhe(lvalue.first, rvalue.first); - } - }; - - - template <typename cT> - static void process_previous_x(cT& output) { - std::map<point_data<Unit>, std::set<property_type> >& y_prop_map = output.first.second; - if(y_prop_map.empty()) return; - Unit x = output.first.first; - for(typename std::map<point_data<Unit>, std::set<property_type> >::iterator itr = - y_prop_map.begin(); itr != y_prop_map.end(); ++itr) { - if((*itr).first.x() < x) { - y_prop_map.erase(y_prop_map.begin(), itr); - continue; - } - for(typename std::set<property_type>::iterator inner_itr = itr->second.begin(); - inner_itr != itr->second.end(); ++inner_itr) { - std::set<property_type>& output_edges = (*(output.second))[*inner_itr]; - typename std::set<property_type>::iterator inner_inner_itr = inner_itr; - ++inner_inner_itr; - for( ; inner_inner_itr != itr->second.end(); ++inner_inner_itr) { - output_edges.insert(output_edges.end(), *inner_inner_itr); - std::set<property_type>& output_edges_2 = (*(output.second))[*inner_inner_itr]; - output_edges_2.insert(output_edges_2.end(), *inner_itr); - } - } - } - } - - template <typename result_type, typename key_type> - class connectivity_extraction_output_functor { - public: - connectivity_extraction_output_functor() {} - void operator()(result_type& result, const half_edge& edge, const key_type& left, const key_type& right) { - Unit& x = result.first.first; - std::map<point_data<Unit>, std::set<property_type> >& y_prop_map = result.first.second; - point_data<Unit> pt = edge.first; - if(pt.x() != x) process_previous_x(result); - x = pt.x(); - std::set<property_type>& output_set = y_prop_map[pt]; - { - for(typename key_type::const_iterator itr1 = - left.begin(); itr1 != left.end(); ++itr1) { - output_set.insert(output_set.end(), *itr1); - } - for(typename key_type::const_iterator itr2 = - right.begin(); itr2 != right.end(); ++itr2) { - output_set.insert(output_set.end(), *itr2); - } - } - std::set<property_type>& output_set2 = y_prop_map[edge.second]; - for(typename key_type::const_iterator itr1 = - left.begin(); itr1 != left.end(); ++itr1) { - output_set2.insert(output_set2.end(), *itr1); - } - for(typename key_type::const_iterator itr2 = - right.begin(); itr2 != right.end(); ++itr2) { - output_set2.insert(output_set2.end(), *itr2); - } - } - }; - - inline void sort_property_merge_data() { - less_vertex_data<vertex_property> lvd(&evalAtXforYPack_); - polygon_sort(pmd.begin(), pmd.end(), lvd); - } - public: - inline arbitrary_connectivity_extraction() : pmd(), evalAtXforYPack_() {} - inline arbitrary_connectivity_extraction - (const arbitrary_connectivity_extraction& pm) : pmd(pm.pmd), evalAtXforYPack_(pm.evalAtXforYPack_) {} - inline arbitrary_connectivity_extraction& operator= - (const arbitrary_connectivity_extraction& pm) { pmd = pm.pmd; return *this; } - - template <typename result_type> - inline void execute(result_type& result) { - //intersect data - property_merge_data tmp_pmd; - line_intersection<Unit>::validate_scan(tmp_pmd, pmd.begin(), pmd.end()); - pmd.swap(tmp_pmd); - sort_property_merge_data(); - scanline<Unit, property_type, std::vector<property_type> > sl; - std::pair<std::pair<Unit, std::map<point_data<Unit>, std::set<property_type> > >, - result_type*> output - (std::make_pair(std::make_pair((std::numeric_limits<Unit>::max)(), - std::map<point_data<Unit>, - std::set<property_type> >()), &result)); - connectivity_extraction_output_functor<std::pair<std::pair<Unit, - std::map<point_data<Unit>, std::set<property_type> > >, result_type*>, - std::vector<property_type> > ceof; - sl.scan(output, ceof, pmd.begin(), pmd.end()); - process_previous_x(output); - } - - inline void clear() {*this = arbitrary_connectivity_extraction();} - - template <typename iT> - void populateTouchSetData(iT begin, iT end, - property_type property) { - for( ; begin != end; ++begin) { - pmd.push_back(vertex_property(half_edge((*begin).first.first, (*begin).first.second), - std::pair<property_type, int>(property, (*begin).second))); - } - } - - }; - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/detail/voronoi_ctypes.hpp b/contrib/restricted/boost/boost/polygon/detail/voronoi_ctypes.hpp deleted file mode 100644 index a2ea9ffd63..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/voronoi_ctypes.hpp +++ /dev/null @@ -1,642 +0,0 @@ -// Boost.Polygon library detail/voronoi_ctypes.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_DETAIL_VORONOI_CTYPES -#define BOOST_POLYGON_DETAIL_VORONOI_CTYPES - -#include <boost/cstdint.hpp> - -#include <cmath> -#include <cstring> -#include <utility> -#include <vector> - -namespace boost { -namespace polygon { -namespace detail { - -typedef boost::int32_t int32; -typedef boost::int64_t int64; -typedef boost::uint32_t uint32; -typedef boost::uint64_t uint64; -typedef double fpt64; - -// If two floating-point numbers in the same format are ordered (x < y), -// then they are ordered the same way when their bits are reinterpreted as -// sign-magnitude integers. Values are considered to be almost equal if -// their integer bits reinterpretations differ in not more than maxUlps units. -template <typename _fpt> -struct ulp_comparison; - -template <> -struct ulp_comparison<fpt64> { - enum Result { - LESS = -1, - EQUAL = 0, - MORE = 1 - }; - - Result operator()(fpt64 a, fpt64 b, unsigned int maxUlps) const { - uint64 ll_a, ll_b; - - // Reinterpret double bits as 64-bit signed integer. - std::memcpy(&ll_a, &a, sizeof(fpt64)); - std::memcpy(&ll_b, &b, sizeof(fpt64)); - - // Positive 0.0 is integer zero. Negative 0.0 is 0x8000000000000000. - // Map negative zero to an integer zero representation - making it - // identical to positive zero - the smallest negative number is - // represented by negative one, and downwards from there. - if (ll_a < 0x8000000000000000ULL) - ll_a = 0x8000000000000000ULL - ll_a; - if (ll_b < 0x8000000000000000ULL) - ll_b = 0x8000000000000000ULL - ll_b; - - // Compare 64-bit signed integer representations of input values. - // Difference in 1 Ulp is equivalent to a relative error of between - // 1/4,000,000,000,000,000 and 1/8,000,000,000,000,000. - if (ll_a > ll_b) - return (ll_a - ll_b <= maxUlps) ? EQUAL : LESS; - return (ll_b - ll_a <= maxUlps) ? EQUAL : MORE; - } -}; - -template <typename _fpt> -struct extened_exponent_fpt_traits; - -template <> -struct extened_exponent_fpt_traits<fpt64> { - public: - typedef int exp_type; - enum { - MAX_SIGNIFICANT_EXP_DIF = 54 - }; -}; - -// Floating point type wrapper. Allows to extend exponent boundaries to the -// integer type range. This class does not handle division by zero, subnormal -// numbers or NaNs. -template <typename _fpt, typename _traits = extened_exponent_fpt_traits<_fpt> > -class extended_exponent_fpt { - public: - typedef _fpt fpt_type; - typedef typename _traits::exp_type exp_type; - - explicit extended_exponent_fpt(fpt_type val) { - val_ = std::frexp(val, &exp_); - } - - extended_exponent_fpt(fpt_type val, exp_type exp) { - val_ = std::frexp(val, &exp_); - exp_ += exp; - } - - bool is_pos() const { - return val_ > 0; - } - - bool is_neg() const { - return val_ < 0; - } - - bool is_zero() const { - return val_ == 0; - } - - extended_exponent_fpt operator-() const { - return extended_exponent_fpt(-val_, exp_); - } - - extended_exponent_fpt operator+(const extended_exponent_fpt& that) const { - if (this->val_ == 0.0 || - that.exp_ > this->exp_ + _traits::MAX_SIGNIFICANT_EXP_DIF) { - return that; - } - if (that.val_ == 0.0 || - this->exp_ > that.exp_ + _traits::MAX_SIGNIFICANT_EXP_DIF) { - return *this; - } - if (this->exp_ >= that.exp_) { - exp_type exp_dif = this->exp_ - that.exp_; - fpt_type val = std::ldexp(this->val_, exp_dif) + that.val_; - return extended_exponent_fpt(val, that.exp_); - } else { - exp_type exp_dif = that.exp_ - this->exp_; - fpt_type val = std::ldexp(that.val_, exp_dif) + this->val_; - return extended_exponent_fpt(val, this->exp_); - } - } - - extended_exponent_fpt operator-(const extended_exponent_fpt& that) const { - if (this->val_ == 0.0 || - that.exp_ > this->exp_ + _traits::MAX_SIGNIFICANT_EXP_DIF) { - return extended_exponent_fpt(-that.val_, that.exp_); - } - if (that.val_ == 0.0 || - this->exp_ > that.exp_ + _traits::MAX_SIGNIFICANT_EXP_DIF) { - return *this; - } - if (this->exp_ >= that.exp_) { - exp_type exp_dif = this->exp_ - that.exp_; - fpt_type val = std::ldexp(this->val_, exp_dif) - that.val_; - return extended_exponent_fpt(val, that.exp_); - } else { - exp_type exp_dif = that.exp_ - this->exp_; - fpt_type val = std::ldexp(-that.val_, exp_dif) + this->val_; - return extended_exponent_fpt(val, this->exp_); - } - } - - extended_exponent_fpt operator*(const extended_exponent_fpt& that) const { - fpt_type val = this->val_ * that.val_; - exp_type exp = this->exp_ + that.exp_; - return extended_exponent_fpt(val, exp); - } - - extended_exponent_fpt operator/(const extended_exponent_fpt& that) const { - fpt_type val = this->val_ / that.val_; - exp_type exp = this->exp_ - that.exp_; - return extended_exponent_fpt(val, exp); - } - - extended_exponent_fpt& operator+=(const extended_exponent_fpt& that) { - return *this = *this + that; - } - - extended_exponent_fpt& operator-=(const extended_exponent_fpt& that) { - return *this = *this - that; - } - - extended_exponent_fpt& operator*=(const extended_exponent_fpt& that) { - return *this = *this * that; - } - - extended_exponent_fpt& operator/=(const extended_exponent_fpt& that) { - return *this = *this / that; - } - - extended_exponent_fpt sqrt() const { - fpt_type val = val_; - exp_type exp = exp_; - if (exp & 1) { - val *= 2.0; - --exp; - } - return extended_exponent_fpt(std::sqrt(val), exp >> 1); - } - - fpt_type d() const { - return std::ldexp(val_, exp_); - } - - private: - fpt_type val_; - exp_type exp_; -}; -typedef extended_exponent_fpt<double> efpt64; - -template <typename _fpt> -extended_exponent_fpt<_fpt> get_sqrt(const extended_exponent_fpt<_fpt>& that) { - return that.sqrt(); -} - -template <typename _fpt> -bool is_pos(const extended_exponent_fpt<_fpt>& that) { - return that.is_pos(); -} - -template <typename _fpt> -bool is_neg(const extended_exponent_fpt<_fpt>& that) { - return that.is_neg(); -} - -template <typename _fpt> -bool is_zero(const extended_exponent_fpt<_fpt>& that) { - return that.is_zero(); -} - -// Very efficient stack allocated big integer class. -// Supports next set of arithmetic operations: +, -, *. -template<std::size_t N> -class extended_int { - public: - extended_int() {} - - extended_int(int32 that) { - if (that > 0) { - this->chunks_[0] = that; - this->count_ = 1; - } else if (that < 0) { - this->chunks_[0] = -that; - this->count_ = -1; - } else { - this->count_ = 0; - } - } - - extended_int(int64 that) { - if (that > 0) { - this->chunks_[0] = static_cast<uint32>(that); - this->chunks_[1] = that >> 32; - this->count_ = this->chunks_[1] ? 2 : 1; - } else if (that < 0) { - that = -that; - this->chunks_[0] = static_cast<uint32>(that); - this->chunks_[1] = that >> 32; - this->count_ = this->chunks_[1] ? -2 : -1; - } else { - this->count_ = 0; - } - } - - extended_int(const std::vector<uint32>& chunks, bool plus = true) { - this->count_ = static_cast<int32>((std::min)(N, chunks.size())); - for (int i = 0; i < this->count_; ++i) - this->chunks_[i] = chunks[chunks.size() - i - 1]; - if (!plus) - this->count_ = -this->count_; - } - - template<std::size_t M> - extended_int(const extended_int<M>& that) { - this->count_ = that.count(); - std::memcpy(this->chunks_, that.chunks(), that.size() * sizeof(uint32)); - } - - extended_int& operator=(int32 that) { - if (that > 0) { - this->chunks_[0] = that; - this->count_ = 1; - } else if (that < 0) { - this->chunks_[0] = -that; - this->count_ = -1; - } else { - this->count_ = 0; - } - return *this; - } - - extended_int& operator=(int64 that) { - if (that > 0) { - this->chunks_[0] = static_cast<uint32>(that); - this->chunks_[1] = that >> 32; - this->count_ = this->chunks_[1] ? 2 : 1; - } else if (that < 0) { - that = -that; - this->chunks_[0] = static_cast<uint32>(that); - this->chunks_[1] = that >> 32; - this->count_ = this->chunks_[1] ? -2 : -1; - } else { - this->count_ = 0; - } - return *this; - } - - template<std::size_t M> - extended_int& operator=(const extended_int<M>& that) { - this->count_ = that.count(); - std::memcpy(this->chunks_, that.chunks(), that.size() * sizeof(uint32)); - return *this; - } - - bool is_pos() const { - return this->count_ > 0; - } - - bool is_neg() const { - return this->count_ < 0; - } - - bool is_zero() const { - return this->count_ == 0; - } - - bool operator==(const extended_int& that) const { - if (this->count_ != that.count()) - return false; - for (std::size_t i = 0; i < this->size(); ++i) - if (this->chunks_[i] != that.chunks()[i]) - return false; - return true; - } - - bool operator!=(const extended_int& that) const { - return !(*this == that); - } - - bool operator<(const extended_int& that) const { - if (this->count_ != that.count()) - return this->count_ < that.count(); - std::size_t i = this->size(); - if (!i) - return false; - do { - --i; - if (this->chunks_[i] != that.chunks()[i]) - return (this->chunks_[i] < that.chunks()[i]) ^ (this->count_ < 0); - } while (i); - return false; - } - - bool operator>(const extended_int& that) const { - return that < *this; - } - - bool operator<=(const extended_int& that) const { - return !(that < *this); - } - - bool operator>=(const extended_int& that) const { - return !(*this < that); - } - - extended_int operator-() const { - extended_int ret_val = *this; - ret_val.neg(); - return ret_val; - } - - void neg() { - this->count_ = -this->count_; - } - - extended_int operator+(const extended_int& that) const { - extended_int ret_val; - ret_val.add(*this, that); - return ret_val; - } - - void add(const extended_int& e1, const extended_int& e2) { - if (!e1.count()) { - *this = e2; - return; - } - if (!e2.count()) { - *this = e1; - return; - } - if ((e1.count() > 0) ^ (e2.count() > 0)) { - dif(e1.chunks(), e1.size(), e2.chunks(), e2.size()); - } else { - add(e1.chunks(), e1.size(), e2.chunks(), e2.size()); - } - if (e1.count() < 0) - this->count_ = -this->count_; - } - - extended_int operator-(const extended_int& that) const { - extended_int ret_val; - ret_val.dif(*this, that); - return ret_val; - } - - void dif(const extended_int& e1, const extended_int& e2) { - if (!e1.count()) { - *this = e2; - this->count_ = -this->count_; - return; - } - if (!e2.count()) { - *this = e1; - return; - } - if ((e1.count() > 0) ^ (e2.count() > 0)) { - add(e1.chunks(), e1.size(), e2.chunks(), e2.size()); - } else { - dif(e1.chunks(), e1.size(), e2.chunks(), e2.size()); - } - if (e1.count() < 0) - this->count_ = -this->count_; - } - - extended_int operator*(int32 that) const { - extended_int temp(that); - return (*this) * temp; - } - - extended_int operator*(int64 that) const { - extended_int temp(that); - return (*this) * temp; - } - - extended_int operator*(const extended_int& that) const { - extended_int ret_val; - ret_val.mul(*this, that); - return ret_val; - } - - void mul(const extended_int& e1, const extended_int& e2) { - if (!e1.count() || !e2.count()) { - this->count_ = 0; - return; - } - mul(e1.chunks(), e1.size(), e2.chunks(), e2.size()); - if ((e1.count() > 0) ^ (e2.count() > 0)) - this->count_ = -this->count_; - } - - const uint32* chunks() const { - return chunks_; - } - - int32 count() const { - return count_; - } - - std::size_t size() const { - return (std::abs)(count_); - } - - std::pair<fpt64, int> p() const { - std::pair<fpt64, int> ret_val(0, 0); - std::size_t sz = this->size(); - if (!sz) { - return ret_val; - } else { - if (sz == 1) { - ret_val.first = static_cast<fpt64>(this->chunks_[0]); - } else if (sz == 2) { - ret_val.first = static_cast<fpt64>(this->chunks_[1]) * - static_cast<fpt64>(0x100000000LL) + - static_cast<fpt64>(this->chunks_[0]); - } else { - for (std::size_t i = 1; i <= 3; ++i) { - ret_val.first *= static_cast<fpt64>(0x100000000LL); - ret_val.first += static_cast<fpt64>(this->chunks_[sz - i]); - } - ret_val.second = static_cast<int>((sz - 3) << 5); - } - } - if (this->count_ < 0) - ret_val.first = -ret_val.first; - return ret_val; - } - - fpt64 d() const { - std::pair<fpt64, int> p = this->p(); - return std::ldexp(p.first, p.second); - } - - private: - void add(const uint32* c1, std::size_t sz1, - const uint32* c2, std::size_t sz2) { - if (sz1 < sz2) { - add(c2, sz2, c1, sz1); - return; - } - this->count_ = static_cast<int32>(sz1); - uint64 temp = 0; - for (std::size_t i = 0; i < sz2; ++i) { - temp += static_cast<uint64>(c1[i]) + static_cast<uint64>(c2[i]); - this->chunks_[i] = static_cast<uint32>(temp); - temp >>= 32; - } - for (std::size_t i = sz2; i < sz1; ++i) { - temp += static_cast<uint64>(c1[i]); - this->chunks_[i] = static_cast<uint32>(temp); - temp >>= 32; - } - if (temp && (this->count_ != N)) { - this->chunks_[this->count_] = static_cast<uint32>(temp); - ++this->count_; - } - } - - void dif(const uint32* c1, std::size_t sz1, - const uint32* c2, std::size_t sz2, - bool rec = false) { - if (sz1 < sz2) { - dif(c2, sz2, c1, sz1, true); - this->count_ = -this->count_; - return; - } else if ((sz1 == sz2) && !rec) { - do { - --sz1; - if (c1[sz1] < c2[sz1]) { - ++sz1; - dif(c2, sz1, c1, sz1, true); - this->count_ = -this->count_; - return; - } else if (c1[sz1] > c2[sz1]) { - ++sz1; - break; - } - } while (sz1); - if (!sz1) { - this->count_ = 0; - return; - } - sz2 = sz1; - } - this->count_ = static_cast<int32>(sz1-1); - bool flag = false; - for (std::size_t i = 0; i < sz2; ++i) { - this->chunks_[i] = c1[i] - c2[i] - (flag?1:0); - flag = (c1[i] < c2[i]) || ((c1[i] == c2[i]) && flag); - } - for (std::size_t i = sz2; i < sz1; ++i) { - this->chunks_[i] = c1[i] - (flag?1:0); - flag = !c1[i] && flag; - } - if (this->chunks_[this->count_]) - ++this->count_; - } - - void mul(const uint32* c1, std::size_t sz1, - const uint32* c2, std::size_t sz2) { - uint64 cur = 0, nxt, tmp; - this->count_ = static_cast<int32>((std::min)(N, sz1 + sz2 - 1)); - for (std::size_t shift = 0; shift < static_cast<std::size_t>(this->count_); - ++shift) { - nxt = 0; - for (std::size_t first = 0; first <= shift; ++first) { - if (first >= sz1) - break; - std::size_t second = shift - first; - if (second >= sz2) - continue; - tmp = static_cast<uint64>(c1[first]) * static_cast<uint64>(c2[second]); - cur += static_cast<uint32>(tmp); - nxt += tmp >> 32; - } - this->chunks_[shift] = static_cast<uint32>(cur); - cur = nxt + (cur >> 32); - } - if (cur && (this->count_ != N)) { - this->chunks_[this->count_] = static_cast<uint32>(cur); - ++this->count_; - } - } - - uint32 chunks_[N]; - int32 count_; -}; - -template <std::size_t N> -bool is_pos(const extended_int<N>& that) { - return that.count() > 0; -} - -template <std::size_t N> -bool is_neg(const extended_int<N>& that) { - return that.count() < 0; -} - -template <std::size_t N> -bool is_zero(const extended_int<N>& that) { - return !that.count(); -} - -struct type_converter_fpt { - template <typename T> - fpt64 operator()(const T& that) const { - return static_cast<fpt64>(that); - } - - template <std::size_t N> - fpt64 operator()(const extended_int<N>& that) const { - return that.d(); - } - - fpt64 operator()(const extended_exponent_fpt<fpt64>& that) const { - return that.d(); - } -}; - -struct type_converter_efpt { - template <std::size_t N> - extended_exponent_fpt<fpt64> operator()(const extended_int<N>& that) const { - std::pair<fpt64, int> p = that.p(); - return extended_exponent_fpt<fpt64>(p.first, p.second); - } -}; - -// Voronoi coordinate type traits make it possible to extend algorithm -// input coordinate range to any user provided integer type and algorithm -// output coordinate range to any ieee-754 like floating point type. -template <typename T> -struct voronoi_ctype_traits; - -template <> -struct voronoi_ctype_traits<int32> { - typedef int32 int_type; - typedef int64 int_x2_type; - typedef uint64 uint_x2_type; - typedef extended_int<64> big_int_type; - typedef fpt64 fpt_type; - typedef extended_exponent_fpt<fpt_type> efpt_type; - typedef ulp_comparison<fpt_type> ulp_cmp_type; - typedef type_converter_fpt to_fpt_converter_type; - typedef type_converter_efpt to_efpt_converter_type; -}; -} // detail -} // polygon -} // boost - -#endif // BOOST_POLYGON_DETAIL_VORONOI_CTYPES diff --git a/contrib/restricted/boost/boost/polygon/detail/voronoi_predicates.hpp b/contrib/restricted/boost/boost/polygon/detail/voronoi_predicates.hpp deleted file mode 100644 index 783987972e..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/voronoi_predicates.hpp +++ /dev/null @@ -1,1532 +0,0 @@ -// Boost.Polygon library detail/voronoi_predicates.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_DETAIL_VORONOI_PREDICATES -#define BOOST_POLYGON_DETAIL_VORONOI_PREDICATES - -#include <utility> - -#include "voronoi_robust_fpt.hpp" - -namespace boost { -namespace polygon { -namespace detail { - -// Predicate utilities. Operates with the coordinate types that could -// be converted to the 32-bit signed integer without precision loss. -template <typename CTYPE_TRAITS> -class voronoi_predicates { - public: - typedef typename CTYPE_TRAITS::int_type int_type; - typedef typename CTYPE_TRAITS::int_x2_type int_x2_type; - typedef typename CTYPE_TRAITS::uint_x2_type uint_x2_type; - typedef typename CTYPE_TRAITS::big_int_type big_int_type; - typedef typename CTYPE_TRAITS::fpt_type fpt_type; - typedef typename CTYPE_TRAITS::efpt_type efpt_type; - typedef typename CTYPE_TRAITS::ulp_cmp_type ulp_cmp_type; - typedef typename CTYPE_TRAITS::to_fpt_converter_type to_fpt_converter; - typedef typename CTYPE_TRAITS::to_efpt_converter_type to_efpt_converter; - - enum { - ULPS = 64, - ULPSx2 = 128 - }; - - template <typename Point> - static bool is_vertical(const Point& point1, const Point& point2) { - return point1.x() == point2.x(); - } - - template <typename Site> - static bool is_vertical(const Site& site) { - return is_vertical(site.point0(), site.point1()); - } - - // Compute robust cross_product: a1 * b2 - b1 * a2. - // It was mathematically proven that the result is correct - // with epsilon relative error equal to 1EPS. - static fpt_type robust_cross_product(int_x2_type a1_, - int_x2_type b1_, - int_x2_type a2_, - int_x2_type b2_) { - static to_fpt_converter to_fpt; - uint_x2_type a1 = static_cast<uint_x2_type>(is_neg(a1_) ? -a1_ : a1_); - uint_x2_type b1 = static_cast<uint_x2_type>(is_neg(b1_) ? -b1_ : b1_); - uint_x2_type a2 = static_cast<uint_x2_type>(is_neg(a2_) ? -a2_ : a2_); - uint_x2_type b2 = static_cast<uint_x2_type>(is_neg(b2_) ? -b2_ : b2_); - - uint_x2_type l = a1 * b2; - uint_x2_type r = b1 * a2; - - if (is_neg(a1_) ^ is_neg(b2_)) { - if (is_neg(a2_) ^ is_neg(b1_)) - return (l > r) ? -to_fpt(l - r) : to_fpt(r - l); - else - return -to_fpt(l + r); - } else { - if (is_neg(a2_) ^ is_neg(b1_)) - return to_fpt(l + r); - else - return (l < r) ? -to_fpt(r - l) : to_fpt(l - r); - } - } - - typedef struct orientation_test { - public: - // Represents orientation test result. - enum Orientation { - RIGHT = -1, - COLLINEAR = 0, - LEFT = 1 - }; - - // Value is a determinant of two vectors (e.g. x1 * y2 - x2 * y1). - // Return orientation based on the sign of the determinant. - template <typename T> - static Orientation eval(T value) { - if (is_zero(value)) return COLLINEAR; - return (is_neg(value)) ? RIGHT : LEFT; - } - - static Orientation eval(int_x2_type dif_x1_, - int_x2_type dif_y1_, - int_x2_type dif_x2_, - int_x2_type dif_y2_) { - return eval(robust_cross_product(dif_x1_, dif_y1_, dif_x2_, dif_y2_)); - } - - template <typename Point> - static Orientation eval(const Point& point1, - const Point& point2, - const Point& point3) { - int_x2_type dx1 = static_cast<int_x2_type>(point1.x()) - - static_cast<int_x2_type>(point2.x()); - int_x2_type dx2 = static_cast<int_x2_type>(point2.x()) - - static_cast<int_x2_type>(point3.x()); - int_x2_type dy1 = static_cast<int_x2_type>(point1.y()) - - static_cast<int_x2_type>(point2.y()); - int_x2_type dy2 = static_cast<int_x2_type>(point2.y()) - - static_cast<int_x2_type>(point3.y()); - return eval(robust_cross_product(dx1, dy1, dx2, dy2)); - } - } ot; - - template <typename Point> - class point_comparison_predicate { - public: - typedef Point point_type; - - bool operator()(const point_type& lhs, const point_type& rhs) const { - if (lhs.x() == rhs.x()) - return lhs.y() < rhs.y(); - return lhs.x() < rhs.x(); - } - }; - - template <typename Site, typename Circle> - class event_comparison_predicate { - public: - typedef Site site_type; - typedef Circle circle_type; - - bool operator()(const site_type& lhs, const site_type& rhs) const { - if (lhs.x0() != rhs.x0()) - return lhs.x0() < rhs.x0(); - if (!lhs.is_segment()) { - if (!rhs.is_segment()) - return lhs.y0() < rhs.y0(); - if (is_vertical(rhs)) - return lhs.y0() <= rhs.y0(); - return true; - } else { - if (is_vertical(rhs)) { - if (is_vertical(lhs)) - return lhs.y0() < rhs.y0(); - return false; - } - if (is_vertical(lhs)) - return true; - if (lhs.y0() != rhs.y0()) - return lhs.y0() < rhs.y0(); - return ot::eval(lhs.point1(), lhs.point0(), rhs.point1()) == ot::LEFT; - } - } - - bool operator()(const site_type& lhs, const circle_type& rhs) const { - typename ulp_cmp_type::Result xCmp = - ulp_cmp(to_fpt(lhs.x0()), to_fpt(rhs.lower_x()), ULPS); - return xCmp == ulp_cmp_type::LESS; - } - - bool operator()(const circle_type& lhs, const site_type& rhs) const { - typename ulp_cmp_type::Result xCmp = - ulp_cmp(to_fpt(lhs.lower_x()), to_fpt(rhs.x0()), ULPS); - return xCmp == ulp_cmp_type::LESS; - } - - bool operator()(const circle_type& lhs, const circle_type& rhs) const { - if (lhs.lower_x() != rhs.lower_x()) { - return lhs.lower_x() < rhs.lower_x(); - } - return lhs.y() < rhs.y(); - } - - private: - ulp_cmp_type ulp_cmp; - to_fpt_converter to_fpt; - }; - - template <typename Site> - class distance_predicate { - public: - typedef Site site_type; - typedef typename site_type::point_type point_type; - - // Returns true if a horizontal line going through a new site intersects - // right arc at first, else returns false. If horizontal line goes - // through intersection point of the given two arcs returns false also. - bool operator()(const site_type& left_site, - const site_type& right_site, - const point_type& new_point) const { - if (!left_site.is_segment()) { - if (!right_site.is_segment()) { - return pp(left_site, right_site, new_point); - } else { - return ps(left_site, right_site, new_point, false); - } - } else { - if (!right_site.is_segment()) { - return ps(right_site, left_site, new_point, true); - } else { - return ss(left_site, right_site, new_point); - } - } - } - - private: - // Represents the result of the epsilon robust predicate. If the - // result is undefined some further processing is usually required. - enum kPredicateResult { - LESS = -1, - UNDEFINED = 0, - MORE = 1 - }; - - // Robust predicate, avoids using high-precision libraries. - // Returns true if a horizontal line going through the new point site - // intersects right arc at first, else returns false. If horizontal line - // goes through intersection point of the given two arcs returns false. - bool pp(const site_type& left_site, - const site_type& right_site, - const point_type& new_point) const { - const point_type& left_point = left_site.point0(); - const point_type& right_point = right_site.point0(); - if (left_point.x() > right_point.x()) { - if (new_point.y() <= left_point.y()) - return false; - } else if (left_point.x() < right_point.x()) { - if (new_point.y() >= right_point.y()) - return true; - } else { - return static_cast<int_x2_type>(left_point.y()) + - static_cast<int_x2_type>(right_point.y()) < - static_cast<int_x2_type>(new_point.y()) * 2; - } - - fpt_type dist1 = find_distance_to_point_arc(left_site, new_point); - fpt_type dist2 = find_distance_to_point_arc(right_site, new_point); - - // The undefined ulp range is equal to 3EPS + 3EPS <= 6ULP. - return dist1 < dist2; - } - - bool ps(const site_type& left_site, const site_type& right_site, - const point_type& new_point, bool reverse_order) const { - kPredicateResult fast_res = fast_ps( - left_site, right_site, new_point, reverse_order); - if (fast_res != UNDEFINED) { - return fast_res == LESS; - } - - fpt_type dist1 = find_distance_to_point_arc(left_site, new_point); - fpt_type dist2 = find_distance_to_segment_arc(right_site, new_point); - - // The undefined ulp range is equal to 3EPS + 7EPS <= 10ULP. - return reverse_order ^ (dist1 < dist2); - } - - bool ss(const site_type& left_site, - const site_type& right_site, - const point_type& new_point) const { - // Handle temporary segment sites. - if (left_site.sorted_index() == right_site.sorted_index()) { - return ot::eval( - left_site.point0(), left_site.point1(), new_point) == ot::LEFT; - } - - fpt_type dist1 = find_distance_to_segment_arc(left_site, new_point); - fpt_type dist2 = find_distance_to_segment_arc(right_site, new_point); - - // The undefined ulp range is equal to 7EPS + 7EPS <= 14ULP. - return dist1 < dist2; - } - - fpt_type find_distance_to_point_arc( - const site_type& site, const point_type& point) const { - fpt_type dx = to_fpt(site.x()) - to_fpt(point.x()); - fpt_type dy = to_fpt(site.y()) - to_fpt(point.y()); - // The relative error is at most 3EPS. - return (dx * dx + dy * dy) / (to_fpt(2.0) * dx); - } - - fpt_type find_distance_to_segment_arc( - const site_type& site, const point_type& point) const { - if (is_vertical(site)) { - return (to_fpt(site.x()) - to_fpt(point.x())) * to_fpt(0.5); - } else { - const point_type& segment0 = site.point0(); - const point_type& segment1 = site.point1(); - fpt_type a1 = to_fpt(segment1.x()) - to_fpt(segment0.x()); - fpt_type b1 = to_fpt(segment1.y()) - to_fpt(segment0.y()); - fpt_type k = get_sqrt(a1 * a1 + b1 * b1); - // Avoid subtraction while computing k. - if (!is_neg(b1)) { - k = to_fpt(1.0) / (b1 + k); - } else { - k = (k - b1) / (a1 * a1); - } - // The relative error is at most 7EPS. - return k * robust_cross_product( - static_cast<int_x2_type>(segment1.x()) - - static_cast<int_x2_type>(segment0.x()), - static_cast<int_x2_type>(segment1.y()) - - static_cast<int_x2_type>(segment0.y()), - static_cast<int_x2_type>(point.x()) - - static_cast<int_x2_type>(segment0.x()), - static_cast<int_x2_type>(point.y()) - - static_cast<int_x2_type>(segment0.y())); - } - } - - kPredicateResult fast_ps( - const site_type& left_site, const site_type& right_site, - const point_type& new_point, bool reverse_order) const { - const point_type& site_point = left_site.point0(); - const point_type& segment_start = right_site.point0(); - const point_type& segment_end = right_site.point1(); - - if (ot::eval(segment_start, segment_end, new_point) != ot::RIGHT) - return (!right_site.is_inverse()) ? LESS : MORE; - - fpt_type dif_x = to_fpt(new_point.x()) - to_fpt(site_point.x()); - fpt_type dif_y = to_fpt(new_point.y()) - to_fpt(site_point.y()); - fpt_type a = to_fpt(segment_end.x()) - to_fpt(segment_start.x()); - fpt_type b = to_fpt(segment_end.y()) - to_fpt(segment_start.y()); - - if (is_vertical(right_site)) { - if (new_point.y() < site_point.y() && !reverse_order) - return MORE; - else if (new_point.y() > site_point.y() && reverse_order) - return LESS; - return UNDEFINED; - } else { - typename ot::Orientation orientation = ot::eval( - static_cast<int_x2_type>(segment_end.x()) - - static_cast<int_x2_type>(segment_start.x()), - static_cast<int_x2_type>(segment_end.y()) - - static_cast<int_x2_type>(segment_start.y()), - static_cast<int_x2_type>(new_point.x()) - - static_cast<int_x2_type>(site_point.x()), - static_cast<int_x2_type>(new_point.y()) - - static_cast<int_x2_type>(site_point.y())); - if (orientation == ot::LEFT) { - if (!right_site.is_inverse()) - return reverse_order ? LESS : UNDEFINED; - return reverse_order ? UNDEFINED : MORE; - } - } - - fpt_type fast_left_expr = a * (dif_y + dif_x) * (dif_y - dif_x); - fpt_type fast_right_expr = (to_fpt(2.0) * b) * dif_x * dif_y; - typename ulp_cmp_type::Result expr_cmp = - ulp_cmp(fast_left_expr, fast_right_expr, 4); - if (expr_cmp != ulp_cmp_type::EQUAL) { - if ((expr_cmp == ulp_cmp_type::MORE) ^ reverse_order) - return reverse_order ? LESS : MORE; - return UNDEFINED; - } - return UNDEFINED; - } - - private: - ulp_cmp_type ulp_cmp; - to_fpt_converter to_fpt; - }; - - template <typename Node> - class node_comparison_predicate { - public: - typedef Node node_type; - typedef typename Node::site_type site_type; - typedef typename site_type::point_type point_type; - typedef typename point_type::coordinate_type coordinate_type; - typedef point_comparison_predicate<point_type> point_comparison_type; - typedef distance_predicate<site_type> distance_predicate_type; - - // Compares nodes in the balanced binary search tree. Nodes are - // compared based on the y coordinates of the arcs intersection points. - // Nodes with less y coordinate of the intersection point go first. - // Comparison is only called during the new site events processing. - // That's why one of the nodes will always lie on the sweepline and may - // be represented as a straight horizontal line. - bool operator() (const node_type& node1, - const node_type& node2) const { - // Get x coordinate of the rightmost site from both nodes. - const site_type& site1 = get_comparison_site(node1); - const site_type& site2 = get_comparison_site(node2); - const point_type& point1 = get_comparison_point(site1); - const point_type& point2 = get_comparison_point(site2); - - if (point1.x() < point2.x()) { - // The second node contains a new site. - return distance_predicate_( - node1.left_site(), node1.right_site(), point2); - } else if (point1.x() > point2.x()) { - // The first node contains a new site. - return !distance_predicate_( - node2.left_site(), node2.right_site(), point1); - } else { - // This checks were evaluated experimentally. - if (site1.sorted_index() == site2.sorted_index()) { - // Both nodes are new (inserted during same site event processing). - return get_comparison_y(node1) < get_comparison_y(node2); - } else if (site1.sorted_index() < site2.sorted_index()) { - std::pair<coordinate_type, int> y1 = get_comparison_y(node1, false); - std::pair<coordinate_type, int> y2 = get_comparison_y(node2, true); - if (y1.first != y2.first) return y1.first < y2.first; - return (!site1.is_segment()) ? (y1.second < 0) : false; - } else { - std::pair<coordinate_type, int> y1 = get_comparison_y(node1, true); - std::pair<coordinate_type, int> y2 = get_comparison_y(node2, false); - if (y1.first != y2.first) return y1.first < y2.first; - return (!site2.is_segment()) ? (y2.second > 0) : true; - } - } - } - - private: - // Get the newer site. - const site_type& get_comparison_site(const node_type& node) const { - if (node.left_site().sorted_index() > node.right_site().sorted_index()) { - return node.left_site(); - } - return node.right_site(); - } - - const point_type& get_comparison_point(const site_type& site) const { - return point_comparison_(site.point0(), site.point1()) ? - site.point0() : site.point1(); - } - - // Get comparison pair: y coordinate and direction of the newer site. - std::pair<coordinate_type, int> get_comparison_y( - const node_type& node, bool is_new_node = true) const { - if (node.left_site().sorted_index() == - node.right_site().sorted_index()) { - return std::make_pair(node.left_site().y0(), 0); - } - if (node.left_site().sorted_index() > node.right_site().sorted_index()) { - if (!is_new_node && - node.left_site().is_segment() && - is_vertical(node.left_site())) { - return std::make_pair(node.left_site().y0(), 1); - } - return std::make_pair(node.left_site().y1(), 1); - } - return std::make_pair(node.right_site().y0(), -1); - } - - point_comparison_type point_comparison_; - distance_predicate_type distance_predicate_; - }; - - template <typename Site> - class circle_existence_predicate { - public: - typedef typename Site::point_type point_type; - typedef Site site_type; - - bool ppp(const site_type& site1, - const site_type& site2, - const site_type& site3) const { - return ot::eval(site1.point0(), - site2.point0(), - site3.point0()) == ot::RIGHT; - } - - bool pps(const site_type& site1, - const site_type& site2, - const site_type& site3, - int segment_index) const { - if (segment_index != 2) { - typename ot::Orientation orient1 = ot::eval( - site1.point0(), site2.point0(), site3.point0()); - typename ot::Orientation orient2 = ot::eval( - site1.point0(), site2.point0(), site3.point1()); - if (segment_index == 1 && site1.x0() >= site2.x0()) { - if (orient1 != ot::RIGHT) - return false; - } else if (segment_index == 3 && site2.x0() >= site1.x0()) { - if (orient2 != ot::RIGHT) - return false; - } else if (orient1 != ot::RIGHT && orient2 != ot::RIGHT) { - return false; - } - } else { - return (site3.point0() != site1.point0()) || - (site3.point1() != site2.point0()); - } - return true; - } - - bool pss(const site_type& site1, - const site_type& site2, - const site_type& site3, - int point_index) const { - if (site2.sorted_index() == site3.sorted_index()) { - return false; - } - if (point_index == 2) { - if (!site2.is_inverse() && site3.is_inverse()) - return false; - if (site2.is_inverse() == site3.is_inverse() && - ot::eval(site2.point0(), - site1.point0(), - site3.point1()) != ot::RIGHT) - return false; - } - return true; - } - - bool sss(const site_type& site1, - const site_type& site2, - const site_type& site3) const { - return (site1.sorted_index() != site2.sorted_index()) && - (site2.sorted_index() != site3.sorted_index()); - } - }; - - template <typename Site, typename Circle> - class mp_circle_formation_functor { - public: - typedef typename Site::point_type point_type; - typedef Site site_type; - typedef Circle circle_type; - typedef robust_sqrt_expr<big_int_type, efpt_type, to_efpt_converter> - robust_sqrt_expr_type; - - void ppp(const site_type& site1, - const site_type& site2, - const site_type& site3, - circle_type& circle, - bool recompute_c_x = true, - bool recompute_c_y = true, - bool recompute_lower_x = true) { - big_int_type dif_x[3], dif_y[3], sum_x[2], sum_y[2]; - dif_x[0] = static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(site2.x()); - dif_x[1] = static_cast<int_x2_type>(site2.x()) - - static_cast<int_x2_type>(site3.x()); - dif_x[2] = static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(site3.x()); - dif_y[0] = static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(site2.y()); - dif_y[1] = static_cast<int_x2_type>(site2.y()) - - static_cast<int_x2_type>(site3.y()); - dif_y[2] = static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(site3.y()); - sum_x[0] = static_cast<int_x2_type>(site1.x()) + - static_cast<int_x2_type>(site2.x()); - sum_x[1] = static_cast<int_x2_type>(site2.x()) + - static_cast<int_x2_type>(site3.x()); - sum_y[0] = static_cast<int_x2_type>(site1.y()) + - static_cast<int_x2_type>(site2.y()); - sum_y[1] = static_cast<int_x2_type>(site2.y()) + - static_cast<int_x2_type>(site3.y()); - fpt_type inv_denom = to_fpt(0.5) / to_fpt(static_cast<big_int_type>( - dif_x[0] * dif_y[1] - dif_x[1] * dif_y[0])); - big_int_type numer1 = dif_x[0] * sum_x[0] + dif_y[0] * sum_y[0]; - big_int_type numer2 = dif_x[1] * sum_x[1] + dif_y[1] * sum_y[1]; - - if (recompute_c_x || recompute_lower_x) { - big_int_type c_x = numer1 * dif_y[1] - numer2 * dif_y[0]; - circle.x(to_fpt(c_x) * inv_denom); - - if (recompute_lower_x) { - // Evaluate radius of the circle. - big_int_type sqr_r = (dif_x[0] * dif_x[0] + dif_y[0] * dif_y[0]) * - (dif_x[1] * dif_x[1] + dif_y[1] * dif_y[1]) * - (dif_x[2] * dif_x[2] + dif_y[2] * dif_y[2]); - fpt_type r = get_sqrt(to_fpt(sqr_r)); - - // If c_x >= 0 then lower_x = c_x + r, - // else lower_x = (c_x * c_x - r * r) / (c_x - r). - // To guarantee epsilon relative error. - if (!is_neg(circle.x())) { - if (!is_neg(inv_denom)) { - circle.lower_x(circle.x() + r * inv_denom); - } else { - circle.lower_x(circle.x() - r * inv_denom); - } - } else { - big_int_type numer = c_x * c_x - sqr_r; - fpt_type lower_x = to_fpt(numer) * inv_denom / (to_fpt(c_x) + r); - circle.lower_x(lower_x); - } - } - } - - if (recompute_c_y) { - big_int_type c_y = numer2 * dif_x[0] - numer1 * dif_x[1]; - circle.y(to_fpt(c_y) * inv_denom); - } - } - - // Recompute parameters of the circle event using high-precision library. - void pps(const site_type& site1, - const site_type& site2, - const site_type& site3, - int segment_index, - circle_type& c_event, - bool recompute_c_x = true, - bool recompute_c_y = true, - bool recompute_lower_x = true) { - big_int_type cA[4], cB[4]; - big_int_type line_a = static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0()); - big_int_type line_b = static_cast<int_x2_type>(site3.x0()) - - static_cast<int_x2_type>(site3.x1()); - big_int_type segm_len = line_a * line_a + line_b * line_b; - big_int_type vec_x = static_cast<int_x2_type>(site2.y()) - - static_cast<int_x2_type>(site1.y()); - big_int_type vec_y = static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(site2.x()); - big_int_type sum_x = static_cast<int_x2_type>(site1.x()) + - static_cast<int_x2_type>(site2.x()); - big_int_type sum_y = static_cast<int_x2_type>(site1.y()) + - static_cast<int_x2_type>(site2.y()); - big_int_type teta = line_a * vec_x + line_b * vec_y; - big_int_type denom = vec_x * line_b - vec_y * line_a; - - big_int_type dif0 = static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site1.y()); - big_int_type dif1 = static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(site3.x1()); - big_int_type A = line_a * dif1 - line_b * dif0; - dif0 = static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site2.y()); - dif1 = static_cast<int_x2_type>(site2.x()) - - static_cast<int_x2_type>(site3.x1()); - big_int_type B = line_a * dif1 - line_b * dif0; - big_int_type sum_AB = A + B; - - if (is_zero(denom)) { - big_int_type numer = teta * teta - sum_AB * sum_AB; - denom = teta * sum_AB; - cA[0] = denom * sum_x * 2 + numer * vec_x; - cB[0] = segm_len; - cA[1] = denom * sum_AB * 2 + numer * teta; - cB[1] = 1; - cA[2] = denom * sum_y * 2 + numer * vec_y; - fpt_type inv_denom = to_fpt(1.0) / to_fpt(denom); - if (recompute_c_x) - c_event.x(to_fpt(0.25) * to_fpt(cA[0]) * inv_denom); - if (recompute_c_y) - c_event.y(to_fpt(0.25) * to_fpt(cA[2]) * inv_denom); - if (recompute_lower_x) { - c_event.lower_x(to_fpt(0.25) * to_fpt(sqrt_expr_.eval2(cA, cB)) * - inv_denom / get_sqrt(to_fpt(segm_len))); - } - return; - } - - big_int_type det = (teta * teta + denom * denom) * A * B * 4; - fpt_type inv_denom_sqr = to_fpt(1.0) / to_fpt(denom); - inv_denom_sqr *= inv_denom_sqr; - - if (recompute_c_x || recompute_lower_x) { - cA[0] = sum_x * denom * denom + teta * sum_AB * vec_x; - cB[0] = 1; - cA[1] = (segment_index == 2) ? -vec_x : vec_x; - cB[1] = det; - if (recompute_c_x) { - c_event.x(to_fpt(0.5) * to_fpt(sqrt_expr_.eval2(cA, cB)) * - inv_denom_sqr); - } - } - - if (recompute_c_y || recompute_lower_x) { - cA[2] = sum_y * denom * denom + teta * sum_AB * vec_y; - cB[2] = 1; - cA[3] = (segment_index == 2) ? -vec_y : vec_y; - cB[3] = det; - if (recompute_c_y) { - c_event.y(to_fpt(0.5) * to_fpt(sqrt_expr_.eval2(&cA[2], &cB[2])) * - inv_denom_sqr); - } - } - - if (recompute_lower_x) { - cB[0] = cB[0] * segm_len; - cB[1] = cB[1] * segm_len; - cA[2] = sum_AB * (denom * denom + teta * teta); - cB[2] = 1; - cA[3] = (segment_index == 2) ? -teta : teta; - cB[3] = det; - c_event.lower_x(to_fpt(0.5) * to_fpt(sqrt_expr_.eval4(cA, cB)) * - inv_denom_sqr / get_sqrt(to_fpt(segm_len))); - } - } - - // Recompute parameters of the circle event using high-precision library. - void pss(const site_type& site1, - const site_type& site2, - const site_type& site3, - int point_index, - circle_type& c_event, - bool recompute_c_x = true, - bool recompute_c_y = true, - bool recompute_lower_x = true) { - big_int_type a[2], b[2], c[2], cA[4], cB[4]; - const point_type& segm_start1 = site2.point1(); - const point_type& segm_end1 = site2.point0(); - const point_type& segm_start2 = site3.point0(); - const point_type& segm_end2 = site3.point1(); - a[0] = static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()); - b[0] = static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()); - a[1] = static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(segm_start2.x()); - b[1] = static_cast<int_x2_type>(segm_end2.y()) - - static_cast<int_x2_type>(segm_start2.y()); - big_int_type orientation = a[1] * b[0] - a[0] * b[1]; - if (is_zero(orientation)) { - fpt_type denom = to_fpt(2.0) * to_fpt( - static_cast<big_int_type>(a[0] * a[0] + b[0] * b[0])); - c[0] = b[0] * (static_cast<int_x2_type>(segm_start2.x()) - - static_cast<int_x2_type>(segm_start1.x())) - - a[0] * (static_cast<int_x2_type>(segm_start2.y()) - - static_cast<int_x2_type>(segm_start1.y())); - big_int_type dx = a[0] * (static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(segm_start1.y())) - - b[0] * (static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(segm_start1.x())); - big_int_type dy = b[0] * (static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(segm_start2.x())) - - a[0] * (static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(segm_start2.y())); - cB[0] = dx * dy; - cB[1] = 1; - - if (recompute_c_y) { - cA[0] = b[0] * ((point_index == 2) ? 2 : -2); - cA[1] = a[0] * a[0] * (static_cast<int_x2_type>(segm_start1.y()) + - static_cast<int_x2_type>(segm_start2.y())) - - a[0] * b[0] * (static_cast<int_x2_type>(segm_start1.x()) + - static_cast<int_x2_type>(segm_start2.x()) - - static_cast<int_x2_type>(site1.x()) * 2) + - b[0] * b[0] * (static_cast<int_x2_type>(site1.y()) * 2); - fpt_type c_y = to_fpt(sqrt_expr_.eval2(cA, cB)); - c_event.y(c_y / denom); - } - - if (recompute_c_x || recompute_lower_x) { - cA[0] = a[0] * ((point_index == 2) ? 2 : -2); - cA[1] = b[0] * b[0] * (static_cast<int_x2_type>(segm_start1.x()) + - static_cast<int_x2_type>(segm_start2.x())) - - a[0] * b[0] * (static_cast<int_x2_type>(segm_start1.y()) + - static_cast<int_x2_type>(segm_start2.y()) - - static_cast<int_x2_type>(site1.y()) * 2) + - a[0] * a[0] * (static_cast<int_x2_type>(site1.x()) * 2); - - if (recompute_c_x) { - fpt_type c_x = to_fpt(sqrt_expr_.eval2(cA, cB)); - c_event.x(c_x / denom); - } - - if (recompute_lower_x) { - cA[2] = is_neg(c[0]) ? -c[0] : c[0]; - cB[2] = a[0] * a[0] + b[0] * b[0]; - fpt_type lower_x = to_fpt(sqrt_expr_.eval3(cA, cB)); - c_event.lower_x(lower_x / denom); - } - } - return; - } - c[0] = b[0] * segm_end1.x() - a[0] * segm_end1.y(); - c[1] = a[1] * segm_end2.y() - b[1] * segm_end2.x(); - big_int_type ix = a[0] * c[1] + a[1] * c[0]; - big_int_type iy = b[0] * c[1] + b[1] * c[0]; - big_int_type dx = ix - orientation * site1.x(); - big_int_type dy = iy - orientation * site1.y(); - if (is_zero(dx) && is_zero(dy)) { - fpt_type denom = to_fpt(orientation); - fpt_type c_x = to_fpt(ix) / denom; - fpt_type c_y = to_fpt(iy) / denom; - c_event = circle_type(c_x, c_y, c_x); - return; - } - - big_int_type sign = ((point_index == 2) ? 1 : -1) * - (is_neg(orientation) ? 1 : -1); - cA[0] = a[1] * -dx + b[1] * -dy; - cA[1] = a[0] * -dx + b[0] * -dy; - cA[2] = sign; - cA[3] = 0; - cB[0] = a[0] * a[0] + b[0] * b[0]; - cB[1] = a[1] * a[1] + b[1] * b[1]; - cB[2] = a[0] * a[1] + b[0] * b[1]; - cB[3] = (a[0] * dy - b[0] * dx) * (a[1] * dy - b[1] * dx) * -2; - fpt_type temp = to_fpt( - sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB)); - fpt_type denom = temp * to_fpt(orientation); - - if (recompute_c_y) { - cA[0] = b[1] * (dx * dx + dy * dy) - iy * (dx * a[1] + dy * b[1]); - cA[1] = b[0] * (dx * dx + dy * dy) - iy * (dx * a[0] + dy * b[0]); - cA[2] = iy * sign; - fpt_type cy = to_fpt( - sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB)); - c_event.y(cy / denom); - } - - if (recompute_c_x || recompute_lower_x) { - cA[0] = a[1] * (dx * dx + dy * dy) - ix * (dx * a[1] + dy * b[1]); - cA[1] = a[0] * (dx * dx + dy * dy) - ix * (dx * a[0] + dy * b[0]); - cA[2] = ix * sign; - - if (recompute_c_x) { - fpt_type cx = to_fpt( - sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB)); - c_event.x(cx / denom); - } - - if (recompute_lower_x) { - cA[3] = orientation * (dx * dx + dy * dy) * (is_neg(temp) ? -1 : 1); - fpt_type lower_x = to_fpt( - sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB)); - c_event.lower_x(lower_x / denom); - } - } - } - - // Recompute parameters of the circle event using high-precision library. - void sss(const site_type& site1, - const site_type& site2, - const site_type& site3, - circle_type& c_event, - bool recompute_c_x = true, - bool recompute_c_y = true, - bool recompute_lower_x = true) { - big_int_type a[3], b[3], c[3], cA[4], cB[4]; - // cA - corresponds to the cross product. - // cB - corresponds to the squared length. - a[0] = static_cast<int_x2_type>(site1.x1()) - - static_cast<int_x2_type>(site1.x0()); - a[1] = static_cast<int_x2_type>(site2.x1()) - - static_cast<int_x2_type>(site2.x0()); - a[2] = static_cast<int_x2_type>(site3.x1()) - - static_cast<int_x2_type>(site3.x0()); - - b[0] = static_cast<int_x2_type>(site1.y1()) - - static_cast<int_x2_type>(site1.y0()); - b[1] = static_cast<int_x2_type>(site2.y1()) - - static_cast<int_x2_type>(site2.y0()); - b[2] = static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0()); - - c[0] = static_cast<int_x2_type>(site1.x0()) * - static_cast<int_x2_type>(site1.y1()) - - static_cast<int_x2_type>(site1.y0()) * - static_cast<int_x2_type>(site1.x1()); - c[1] = static_cast<int_x2_type>(site2.x0()) * - static_cast<int_x2_type>(site2.y1()) - - static_cast<int_x2_type>(site2.y0()) * - static_cast<int_x2_type>(site2.x1()); - c[2] = static_cast<int_x2_type>(site3.x0()) * - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0()) * - static_cast<int_x2_type>(site3.x1()); - - for (int i = 0; i < 3; ++i) - cB[i] = a[i] * a[i] + b[i] * b[i]; - - for (int i = 0; i < 3; ++i) { - int j = (i+1) % 3; - int k = (i+2) % 3; - cA[i] = a[j] * b[k] - a[k] * b[j]; - } - fpt_type denom = to_fpt(sqrt_expr_.eval3(cA, cB)); - - if (recompute_c_y) { - for (int i = 0; i < 3; ++i) { - int j = (i+1) % 3; - int k = (i+2) % 3; - cA[i] = b[j] * c[k] - b[k] * c[j]; - } - fpt_type c_y = to_fpt(sqrt_expr_.eval3(cA, cB)); - c_event.y(c_y / denom); - } - - if (recompute_c_x || recompute_lower_x) { - cA[3] = 0; - for (int i = 0; i < 3; ++i) { - int j = (i+1) % 3; - int k = (i+2) % 3; - cA[i] = a[j] * c[k] - a[k] * c[j]; - if (recompute_lower_x) { - cA[3] = cA[3] + cA[i] * b[i]; - } - } - - if (recompute_c_x) { - fpt_type c_x = to_fpt(sqrt_expr_.eval3(cA, cB)); - c_event.x(c_x / denom); - } - - if (recompute_lower_x) { - cB[3] = 1; - fpt_type lower_x = to_fpt(sqrt_expr_.eval4(cA, cB)); - c_event.lower_x(lower_x / denom); - } - } - } - - private: - // Evaluates A[3] + A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) + - // A[2] * sqrt(B[3] * (sqrt(B[0] * B[1]) + B[2])). - template <typename _int, typename _fpt> - _fpt sqrt_expr_evaluator_pss4(_int *A, _int *B) { - _int cA[4], cB[4]; - if (is_zero(A[3])) { - _fpt lh = sqrt_expr_.eval2(A, B); - cA[0] = 1; - cB[0] = B[0] * B[1]; - cA[1] = B[2]; - cB[1] = 1; - _fpt rh = sqrt_expr_.eval1(A+2, B+3) * - get_sqrt(sqrt_expr_.eval2(cA, cB)); - if ((!is_neg(lh) && !is_neg(rh)) || (!is_pos(lh) && !is_pos(rh))) - return lh + rh; - cA[0] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] - - A[2] * A[2] * B[3] * B[2]; - cB[0] = 1; - cA[1] = A[0] * A[1] * 2 - A[2] * A[2] * B[3]; - cB[1] = B[0] * B[1]; - _fpt numer = sqrt_expr_.eval2(cA, cB); - return numer / (lh - rh); - } - cA[0] = 1; - cB[0] = B[0] * B[1]; - cA[1] = B[2]; - cB[1] = 1; - _fpt rh = sqrt_expr_.eval1(A+2, B+3) * get_sqrt(sqrt_expr_.eval2(cA, cB)); - cA[0] = A[0]; - cB[0] = B[0]; - cA[1] = A[1]; - cB[1] = B[1]; - cA[2] = A[3]; - cB[2] = 1; - _fpt lh = sqrt_expr_.eval3(cA, cB); - if ((!is_neg(lh) && !is_neg(rh)) || (!is_pos(lh) && !is_pos(rh))) - return lh + rh; - cA[0] = A[3] * A[0] * 2; - cA[1] = A[3] * A[1] * 2; - cA[2] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] + - A[3] * A[3] - A[2] * A[2] * B[2] * B[3]; - cA[3] = A[0] * A[1] * 2 - A[2] * A[2] * B[3]; - cB[3] = B[0] * B[1]; - _fpt numer = sqrt_expr_evaluator_pss3<_int, _fpt>(cA, cB); - return numer / (lh - rh); - } - - template <typename _int, typename _fpt> - // Evaluates A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) + - // A[2] + A[3] * sqrt(B[0] * B[1]). - // B[3] = B[0] * B[1]. - _fpt sqrt_expr_evaluator_pss3(_int *A, _int *B) { - _int cA[2], cB[2]; - _fpt lh = sqrt_expr_.eval2(A, B); - _fpt rh = sqrt_expr_.eval2(A+2, B+2); - if ((!is_neg(lh) && !is_neg(rh)) || (!is_pos(lh) && !is_pos(rh))) - return lh + rh; - cA[0] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] - - A[2] * A[2] - A[3] * A[3] * B[0] * B[1]; - cB[0] = 1; - cA[1] = (A[0] * A[1] - A[2] * A[3]) * 2; - cB[1] = B[3]; - _fpt numer = sqrt_expr_.eval2(cA, cB); - return numer / (lh - rh); - } - - robust_sqrt_expr_type sqrt_expr_; - to_fpt_converter to_fpt; - }; - - template <typename Site, typename Circle> - class lazy_circle_formation_functor { - public: - typedef robust_fpt<fpt_type> robust_fpt_type; - typedef robust_dif<robust_fpt_type> robust_dif_type; - typedef typename Site::point_type point_type; - typedef Site site_type; - typedef Circle circle_type; - typedef mp_circle_formation_functor<site_type, circle_type> - exact_circle_formation_functor_type; - - void ppp(const site_type& site1, - const site_type& site2, - const site_type& site3, - circle_type& c_event) { - fpt_type dif_x1 = to_fpt(site1.x()) - to_fpt(site2.x()); - fpt_type dif_x2 = to_fpt(site2.x()) - to_fpt(site3.x()); - fpt_type dif_y1 = to_fpt(site1.y()) - to_fpt(site2.y()); - fpt_type dif_y2 = to_fpt(site2.y()) - to_fpt(site3.y()); - fpt_type orientation = robust_cross_product( - static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(site2.x()), - static_cast<int_x2_type>(site2.x()) - - static_cast<int_x2_type>(site3.x()), - static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(site2.y()), - static_cast<int_x2_type>(site2.y()) - - static_cast<int_x2_type>(site3.y())); - robust_fpt_type inv_orientation(to_fpt(0.5) / orientation, to_fpt(2.0)); - fpt_type sum_x1 = to_fpt(site1.x()) + to_fpt(site2.x()); - fpt_type sum_x2 = to_fpt(site2.x()) + to_fpt(site3.x()); - fpt_type sum_y1 = to_fpt(site1.y()) + to_fpt(site2.y()); - fpt_type sum_y2 = to_fpt(site2.y()) + to_fpt(site3.y()); - fpt_type dif_x3 = to_fpt(site1.x()) - to_fpt(site3.x()); - fpt_type dif_y3 = to_fpt(site1.y()) - to_fpt(site3.y()); - robust_dif_type c_x, c_y; - c_x += robust_fpt_type(dif_x1 * sum_x1 * dif_y2, to_fpt(2.0)); - c_x += robust_fpt_type(dif_y1 * sum_y1 * dif_y2, to_fpt(2.0)); - c_x -= robust_fpt_type(dif_x2 * sum_x2 * dif_y1, to_fpt(2.0)); - c_x -= robust_fpt_type(dif_y2 * sum_y2 * dif_y1, to_fpt(2.0)); - c_y += robust_fpt_type(dif_x2 * sum_x2 * dif_x1, to_fpt(2.0)); - c_y += robust_fpt_type(dif_y2 * sum_y2 * dif_x1, to_fpt(2.0)); - c_y -= robust_fpt_type(dif_x1 * sum_x1 * dif_x2, to_fpt(2.0)); - c_y -= robust_fpt_type(dif_y1 * sum_y1 * dif_x2, to_fpt(2.0)); - robust_dif_type lower_x(c_x); - lower_x -= robust_fpt_type(get_sqrt( - (dif_x1 * dif_x1 + dif_y1 * dif_y1) * - (dif_x2 * dif_x2 + dif_y2 * dif_y2) * - (dif_x3 * dif_x3 + dif_y3 * dif_y3)), to_fpt(5.0)); - c_event = circle_type( - c_x.dif().fpv() * inv_orientation.fpv(), - c_y.dif().fpv() * inv_orientation.fpv(), - lower_x.dif().fpv() * inv_orientation.fpv()); - bool recompute_c_x = c_x.dif().ulp() > ULPS; - bool recompute_c_y = c_y.dif().ulp() > ULPS; - bool recompute_lower_x = lower_x.dif().ulp() > ULPS; - if (recompute_c_x || recompute_c_y || recompute_lower_x) { - exact_circle_formation_functor_.ppp( - site1, site2, site3, c_event, - recompute_c_x, recompute_c_y, recompute_lower_x); - } - } - - void pps(const site_type& site1, - const site_type& site2, - const site_type& site3, - int segment_index, - circle_type& c_event) { - fpt_type line_a = to_fpt(site3.y1()) - to_fpt(site3.y0()); - fpt_type line_b = to_fpt(site3.x0()) - to_fpt(site3.x1()); - fpt_type vec_x = to_fpt(site2.y()) - to_fpt(site1.y()); - fpt_type vec_y = to_fpt(site1.x()) - to_fpt(site2.x()); - robust_fpt_type teta(robust_cross_product( - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0()), - static_cast<int_x2_type>(site3.x0()) - - static_cast<int_x2_type>(site3.x1()), - static_cast<int_x2_type>(site2.x()) - - static_cast<int_x2_type>(site1.x()), - static_cast<int_x2_type>(site2.y()) - - static_cast<int_x2_type>(site1.y())), to_fpt(1.0)); - robust_fpt_type A(robust_cross_product( - static_cast<int_x2_type>(site3.y0()) - - static_cast<int_x2_type>(site3.y1()), - static_cast<int_x2_type>(site3.x0()) - - static_cast<int_x2_type>(site3.x1()), - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site1.y()), - static_cast<int_x2_type>(site3.x1()) - - static_cast<int_x2_type>(site1.x())), to_fpt(1.0)); - robust_fpt_type B(robust_cross_product( - static_cast<int_x2_type>(site3.y0()) - - static_cast<int_x2_type>(site3.y1()), - static_cast<int_x2_type>(site3.x0()) - - static_cast<int_x2_type>(site3.x1()), - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site2.y()), - static_cast<int_x2_type>(site3.x1()) - - static_cast<int_x2_type>(site2.x())), to_fpt(1.0)); - robust_fpt_type denom(robust_cross_product( - static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(site2.y()), - static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(site2.x()), - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0()), - static_cast<int_x2_type>(site3.x1()) - - static_cast<int_x2_type>(site3.x0())), to_fpt(1.0)); - robust_fpt_type inv_segm_len(to_fpt(1.0) / - get_sqrt(line_a * line_a + line_b * line_b), to_fpt(3.0)); - robust_dif_type t; - if (ot::eval(denom) == ot::COLLINEAR) { - t += teta / (robust_fpt_type(to_fpt(8.0)) * A); - t -= A / (robust_fpt_type(to_fpt(2.0)) * teta); - } else { - robust_fpt_type det = ((teta * teta + denom * denom) * A * B).sqrt(); - if (segment_index == 2) { - t -= det / (denom * denom); - } else { - t += det / (denom * denom); - } - t += teta * (A + B) / (robust_fpt_type(to_fpt(2.0)) * denom * denom); - } - robust_dif_type c_x, c_y; - c_x += robust_fpt_type(to_fpt(0.5) * - (to_fpt(site1.x()) + to_fpt(site2.x()))); - c_x += robust_fpt_type(vec_x) * t; - c_y += robust_fpt_type(to_fpt(0.5) * - (to_fpt(site1.y()) + to_fpt(site2.y()))); - c_y += robust_fpt_type(vec_y) * t; - robust_dif_type r, lower_x(c_x); - r -= robust_fpt_type(line_a) * robust_fpt_type(site3.x0()); - r -= robust_fpt_type(line_b) * robust_fpt_type(site3.y0()); - r += robust_fpt_type(line_a) * c_x; - r += robust_fpt_type(line_b) * c_y; - if (r.pos().fpv() < r.neg().fpv()) - r = -r; - lower_x += r * inv_segm_len; - c_event = circle_type( - c_x.dif().fpv(), c_y.dif().fpv(), lower_x.dif().fpv()); - bool recompute_c_x = c_x.dif().ulp() > ULPS; - bool recompute_c_y = c_y.dif().ulp() > ULPS; - bool recompute_lower_x = lower_x.dif().ulp() > ULPS; - if (recompute_c_x || recompute_c_y || recompute_lower_x) { - exact_circle_formation_functor_.pps( - site1, site2, site3, segment_index, c_event, - recompute_c_x, recompute_c_y, recompute_lower_x); - } - } - - void pss(const site_type& site1, - const site_type& site2, - const site_type& site3, - int point_index, - circle_type& c_event) { - const point_type& segm_start1 = site2.point1(); - const point_type& segm_end1 = site2.point0(); - const point_type& segm_start2 = site3.point0(); - const point_type& segm_end2 = site3.point1(); - fpt_type a1 = to_fpt(segm_end1.x()) - to_fpt(segm_start1.x()); - fpt_type b1 = to_fpt(segm_end1.y()) - to_fpt(segm_start1.y()); - fpt_type a2 = to_fpt(segm_end2.x()) - to_fpt(segm_start2.x()); - fpt_type b2 = to_fpt(segm_end2.y()) - to_fpt(segm_start2.y()); - bool recompute_c_x, recompute_c_y, recompute_lower_x; - robust_fpt_type orientation(robust_cross_product( - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_end2.y()) - - static_cast<int_x2_type>(segm_start2.y()), - static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(segm_start2.x())), to_fpt(1.0)); - if (ot::eval(orientation) == ot::COLLINEAR) { - robust_fpt_type a(a1 * a1 + b1 * b1, to_fpt(2.0)); - robust_fpt_type c(robust_cross_product( - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_start2.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_start2.x()) - - static_cast<int_x2_type>(segm_start1.x())), to_fpt(1.0)); - robust_fpt_type det( - robust_cross_product( - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(segm_start1.y())) * - robust_cross_product( - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(site1.y()) - - static_cast<int_x2_type>(segm_start2.y()), - static_cast<int_x2_type>(site1.x()) - - static_cast<int_x2_type>(segm_start2.x())), - to_fpt(3.0)); - robust_dif_type t; - t -= robust_fpt_type(a1) * robust_fpt_type(( - to_fpt(segm_start1.x()) + to_fpt(segm_start2.x())) * to_fpt(0.5) - - to_fpt(site1.x())); - t -= robust_fpt_type(b1) * robust_fpt_type(( - to_fpt(segm_start1.y()) + to_fpt(segm_start2.y())) * to_fpt(0.5) - - to_fpt(site1.y())); - if (point_index == 2) { - t += det.sqrt(); - } else { - t -= det.sqrt(); - } - t /= a; - robust_dif_type c_x, c_y; - c_x += robust_fpt_type(to_fpt(0.5) * ( - to_fpt(segm_start1.x()) + to_fpt(segm_start2.x()))); - c_x += robust_fpt_type(a1) * t; - c_y += robust_fpt_type(to_fpt(0.5) * ( - to_fpt(segm_start1.y()) + to_fpt(segm_start2.y()))); - c_y += robust_fpt_type(b1) * t; - robust_dif_type lower_x(c_x); - if (is_neg(c)) { - lower_x -= robust_fpt_type(to_fpt(0.5)) * c / a.sqrt(); - } else { - lower_x += robust_fpt_type(to_fpt(0.5)) * c / a.sqrt(); - } - recompute_c_x = c_x.dif().ulp() > ULPS; - recompute_c_y = c_y.dif().ulp() > ULPS; - recompute_lower_x = lower_x.dif().ulp() > ULPS; - c_event = - circle_type(c_x.dif().fpv(), c_y.dif().fpv(), lower_x.dif().fpv()); - } else { - robust_fpt_type sqr_sum1(get_sqrt(a1 * a1 + b1 * b1), to_fpt(2.0)); - robust_fpt_type sqr_sum2(get_sqrt(a2 * a2 + b2 * b2), to_fpt(2.0)); - robust_fpt_type a(robust_cross_product( - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_start2.y()) - - static_cast<int_x2_type>(segm_end2.y()), - static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(segm_start2.x())), to_fpt(1.0)); - if (!is_neg(a)) { - a += sqr_sum1 * sqr_sum2; - } else { - a = (orientation * orientation) / (sqr_sum1 * sqr_sum2 - a); - } - robust_fpt_type or1(robust_cross_product( - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(site1.y()), - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(site1.x())), to_fpt(1.0)); - robust_fpt_type or2(robust_cross_product( - static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(segm_start2.x()), - static_cast<int_x2_type>(segm_end2.y()) - - static_cast<int_x2_type>(segm_start2.y()), - static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(site1.x()), - static_cast<int_x2_type>(segm_end2.y()) - - static_cast<int_x2_type>(site1.y())), to_fpt(1.0)); - robust_fpt_type det = robust_fpt_type(to_fpt(2.0)) * a * or1 * or2; - robust_fpt_type c1(robust_cross_product( - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_end1.y()), - static_cast<int_x2_type>(segm_end1.x())), to_fpt(1.0)); - robust_fpt_type c2(robust_cross_product( - static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(segm_start2.x()), - static_cast<int_x2_type>(segm_end2.y()) - - static_cast<int_x2_type>(segm_start2.y()), - static_cast<int_x2_type>(segm_end2.x()), - static_cast<int_x2_type>(segm_end2.y())), to_fpt(1.0)); - robust_fpt_type inv_orientation = - robust_fpt_type(to_fpt(1.0)) / orientation; - robust_dif_type t, b, ix, iy; - ix += robust_fpt_type(a2) * c1 * inv_orientation; - ix += robust_fpt_type(a1) * c2 * inv_orientation; - iy += robust_fpt_type(b1) * c2 * inv_orientation; - iy += robust_fpt_type(b2) * c1 * inv_orientation; - - b += ix * (robust_fpt_type(a1) * sqr_sum2); - b += ix * (robust_fpt_type(a2) * sqr_sum1); - b += iy * (robust_fpt_type(b1) * sqr_sum2); - b += iy * (robust_fpt_type(b2) * sqr_sum1); - b -= sqr_sum1 * robust_fpt_type(robust_cross_product( - static_cast<int_x2_type>(segm_end2.x()) - - static_cast<int_x2_type>(segm_start2.x()), - static_cast<int_x2_type>(segm_end2.y()) - - static_cast<int_x2_type>(segm_start2.y()), - static_cast<int_x2_type>(-site1.y()), - static_cast<int_x2_type>(site1.x())), to_fpt(1.0)); - b -= sqr_sum2 * robust_fpt_type(robust_cross_product( - static_cast<int_x2_type>(segm_end1.x()) - - static_cast<int_x2_type>(segm_start1.x()), - static_cast<int_x2_type>(segm_end1.y()) - - static_cast<int_x2_type>(segm_start1.y()), - static_cast<int_x2_type>(-site1.y()), - static_cast<int_x2_type>(site1.x())), to_fpt(1.0)); - t -= b; - if (point_index == 2) { - t += det.sqrt(); - } else { - t -= det.sqrt(); - } - t /= (a * a); - robust_dif_type c_x(ix), c_y(iy); - c_x += t * (robust_fpt_type(a1) * sqr_sum2); - c_x += t * (robust_fpt_type(a2) * sqr_sum1); - c_y += t * (robust_fpt_type(b1) * sqr_sum2); - c_y += t * (robust_fpt_type(b2) * sqr_sum1); - if (t.pos().fpv() < t.neg().fpv()) { - t = -t; - } - robust_dif_type lower_x(c_x); - if (is_neg(orientation)) { - lower_x -= t * orientation; - } else { - lower_x += t * orientation; - } - recompute_c_x = c_x.dif().ulp() > ULPS; - recompute_c_y = c_y.dif().ulp() > ULPS; - recompute_lower_x = lower_x.dif().ulp() > ULPS; - c_event = circle_type( - c_x.dif().fpv(), c_y.dif().fpv(), lower_x.dif().fpv()); - } - if (recompute_c_x || recompute_c_y || recompute_lower_x) { - exact_circle_formation_functor_.pss( - site1, site2, site3, point_index, c_event, - recompute_c_x, recompute_c_y, recompute_lower_x); - } - } - - void sss(const site_type& site1, - const site_type& site2, - const site_type& site3, - circle_type& c_event) { - robust_fpt_type a1(to_fpt(site1.x1()) - to_fpt(site1.x0())); - robust_fpt_type b1(to_fpt(site1.y1()) - to_fpt(site1.y0())); - robust_fpt_type c1(robust_cross_product( - site1.x0(), site1.y0(), - site1.x1(), site1.y1()), to_fpt(1.0)); - - robust_fpt_type a2(to_fpt(site2.x1()) - to_fpt(site2.x0())); - robust_fpt_type b2(to_fpt(site2.y1()) - to_fpt(site2.y0())); - robust_fpt_type c2(robust_cross_product( - site2.x0(), site2.y0(), - site2.x1(), site2.y1()), to_fpt(1.0)); - - robust_fpt_type a3(to_fpt(site3.x1()) - to_fpt(site3.x0())); - robust_fpt_type b3(to_fpt(site3.y1()) - to_fpt(site3.y0())); - robust_fpt_type c3(robust_cross_product( - site3.x0(), site3.y0(), - site3.x1(), site3.y1()), to_fpt(1.0)); - - robust_fpt_type len1 = (a1 * a1 + b1 * b1).sqrt(); - robust_fpt_type len2 = (a2 * a2 + b2 * b2).sqrt(); - robust_fpt_type len3 = (a3 * a3 + b3 * b3).sqrt(); - robust_fpt_type cross_12(robust_cross_product( - static_cast<int_x2_type>(site1.x1()) - - static_cast<int_x2_type>(site1.x0()), - static_cast<int_x2_type>(site1.y1()) - - static_cast<int_x2_type>(site1.y0()), - static_cast<int_x2_type>(site2.x1()) - - static_cast<int_x2_type>(site2.x0()), - static_cast<int_x2_type>(site2.y1()) - - static_cast<int_x2_type>(site2.y0())), to_fpt(1.0)); - robust_fpt_type cross_23(robust_cross_product( - static_cast<int_x2_type>(site2.x1()) - - static_cast<int_x2_type>(site2.x0()), - static_cast<int_x2_type>(site2.y1()) - - static_cast<int_x2_type>(site2.y0()), - static_cast<int_x2_type>(site3.x1()) - - static_cast<int_x2_type>(site3.x0()), - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0())), to_fpt(1.0)); - robust_fpt_type cross_31(robust_cross_product( - static_cast<int_x2_type>(site3.x1()) - - static_cast<int_x2_type>(site3.x0()), - static_cast<int_x2_type>(site3.y1()) - - static_cast<int_x2_type>(site3.y0()), - static_cast<int_x2_type>(site1.x1()) - - static_cast<int_x2_type>(site1.x0()), - static_cast<int_x2_type>(site1.y1()) - - static_cast<int_x2_type>(site1.y0())), to_fpt(1.0)); - - // denom = cross_12 * len3 + cross_23 * len1 + cross_31 * len2. - robust_dif_type denom; - denom += cross_12 * len3; - denom += cross_23 * len1; - denom += cross_31 * len2; - - // denom * r = (b2 * c_x - a2 * c_y - c2 * denom) / len2. - robust_dif_type r; - r -= cross_12 * c3; - r -= cross_23 * c1; - r -= cross_31 * c2; - - robust_dif_type c_x; - c_x += a1 * c2 * len3; - c_x -= a2 * c1 * len3; - c_x += a2 * c3 * len1; - c_x -= a3 * c2 * len1; - c_x += a3 * c1 * len2; - c_x -= a1 * c3 * len2; - - robust_dif_type c_y; - c_y += b1 * c2 * len3; - c_y -= b2 * c1 * len3; - c_y += b2 * c3 * len1; - c_y -= b3 * c2 * len1; - c_y += b3 * c1 * len2; - c_y -= b1 * c3 * len2; - - robust_dif_type lower_x = c_x + r; - - robust_fpt_type denom_dif = denom.dif(); - robust_fpt_type c_x_dif = c_x.dif() / denom_dif; - robust_fpt_type c_y_dif = c_y.dif() / denom_dif; - robust_fpt_type lower_x_dif = lower_x.dif() / denom_dif; - - bool recompute_c_x = c_x_dif.ulp() > ULPS; - bool recompute_c_y = c_y_dif.ulp() > ULPS; - bool recompute_lower_x = lower_x_dif.ulp() > ULPS; - c_event = circle_type(c_x_dif.fpv(), c_y_dif.fpv(), lower_x_dif.fpv()); - if (recompute_c_x || recompute_c_y || recompute_lower_x) { - exact_circle_formation_functor_.sss( - site1, site2, site3, c_event, - recompute_c_x, recompute_c_y, recompute_lower_x); - } - } - - private: - exact_circle_formation_functor_type exact_circle_formation_functor_; - to_fpt_converter to_fpt; - }; - - template <typename Site, - typename Circle, - typename CEP = circle_existence_predicate<Site>, - typename CFF = lazy_circle_formation_functor<Site, Circle> > - class circle_formation_predicate { - public: - typedef Site site_type; - typedef Circle circle_type; - typedef CEP circle_existence_predicate_type; - typedef CFF circle_formation_functor_type; - - // Create a circle event from the given three sites. - // Returns true if the circle event exists, else false. - // If exists circle event is saved into the c_event variable. - bool operator()(const site_type& site1, const site_type& site2, - const site_type& site3, circle_type& circle) { - if (!site1.is_segment()) { - if (!site2.is_segment()) { - if (!site3.is_segment()) { - // (point, point, point) sites. - if (!circle_existence_predicate_.ppp(site1, site2, site3)) - return false; - circle_formation_functor_.ppp(site1, site2, site3, circle); - } else { - // (point, point, segment) sites. - if (!circle_existence_predicate_.pps(site1, site2, site3, 3)) - return false; - circle_formation_functor_.pps(site1, site2, site3, 3, circle); - } - } else { - if (!site3.is_segment()) { - // (point, segment, point) sites. - if (!circle_existence_predicate_.pps(site1, site3, site2, 2)) - return false; - circle_formation_functor_.pps(site1, site3, site2, 2, circle); - } else { - // (point, segment, segment) sites. - if (!circle_existence_predicate_.pss(site1, site2, site3, 1)) - return false; - circle_formation_functor_.pss(site1, site2, site3, 1, circle); - } - } - } else { - if (!site2.is_segment()) { - if (!site3.is_segment()) { - // (segment, point, point) sites. - if (!circle_existence_predicate_.pps(site2, site3, site1, 1)) - return false; - circle_formation_functor_.pps(site2, site3, site1, 1, circle); - } else { - // (segment, point, segment) sites. - if (!circle_existence_predicate_.pss(site2, site1, site3, 2)) - return false; - circle_formation_functor_.pss(site2, site1, site3, 2, circle); - } - } else { - if (!site3.is_segment()) { - // (segment, segment, point) sites. - if (!circle_existence_predicate_.pss(site3, site1, site2, 3)) - return false; - circle_formation_functor_.pss(site3, site1, site2, 3, circle); - } else { - // (segment, segment, segment) sites. - if (!circle_existence_predicate_.sss(site1, site2, site3)) - return false; - circle_formation_functor_.sss(site1, site2, site3, circle); - } - } - } - if (lies_outside_vertical_segment(circle, site1) || - lies_outside_vertical_segment(circle, site2) || - lies_outside_vertical_segment(circle, site3)) { - return false; - } - return true; - } - - private: - bool lies_outside_vertical_segment( - const circle_type& c, const site_type& s) { - if (!s.is_segment() || !is_vertical(s)) { - return false; - } - fpt_type y0 = to_fpt(s.is_inverse() ? s.y1() : s.y0()); - fpt_type y1 = to_fpt(s.is_inverse() ? s.y0() : s.y1()); - return ulp_cmp(c.y(), y0, ULPS) == ulp_cmp_type::LESS || - ulp_cmp(c.y(), y1, ULPS) == ulp_cmp_type::MORE; - } - - private: - to_fpt_converter to_fpt; - ulp_cmp_type ulp_cmp; - circle_existence_predicate_type circle_existence_predicate_; - circle_formation_functor_type circle_formation_functor_; - }; -}; -} // detail -} // polygon -} // boost - -#endif // BOOST_POLYGON_DETAIL_VORONOI_PREDICATES diff --git a/contrib/restricted/boost/boost/polygon/detail/voronoi_robust_fpt.hpp b/contrib/restricted/boost/boost/polygon/detail/voronoi_robust_fpt.hpp deleted file mode 100644 index 09da1a72f9..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/voronoi_robust_fpt.hpp +++ /dev/null @@ -1,507 +0,0 @@ -// Boost.Polygon library detail/voronoi_robust_fpt.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_DETAIL_VORONOI_ROBUST_FPT -#define BOOST_POLYGON_DETAIL_VORONOI_ROBUST_FPT - -#include <algorithm> -#include <cmath> - -// Geometry predicates with floating-point variables usually require -// high-precision predicates to retrieve the correct result. -// Epsilon robust predicates give the result within some epsilon relative -// error, but are a lot faster than high-precision predicates. -// To make algorithm robust and efficient epsilon robust predicates are -// used at the first step. In case of the undefined result high-precision -// arithmetic is used to produce required robustness. This approach -// requires exact computation of epsilon intervals within which epsilon -// robust predicates have undefined value. -// There are two ways to measure an error of floating-point calculations: -// relative error and ULPs (units in the last place). -// Let EPS be machine epsilon, then next inequalities have place: -// 1 EPS <= 1 ULP <= 2 EPS (1), 0.5 ULP <= 1 EPS <= 1 ULP (2). -// ULPs are good for measuring rounding errors and comparing values. -// Relative errors are good for computation of general relative -// error of formulas or expressions. So to calculate epsilon -// interval within which epsilon robust predicates have undefined result -// next schema is used: -// 1) Compute rounding errors of initial variables using ULPs; -// 2) Transform ULPs to epsilons using upper bound of the (1); -// 3) Compute relative error of the formula using epsilon arithmetic; -// 4) Transform epsilon to ULPs using upper bound of the (2); -// In case two values are inside undefined ULP range use high-precision -// arithmetic to produce the correct result, else output the result. -// Look at almost_equal function to see how two floating-point variables -// are checked to fit in the ULP range. -// If A has relative error of r(A) and B has relative error of r(B) then: -// 1) r(A + B) <= max(r(A), r(B)), for A * B >= 0; -// 2) r(A - B) <= B*r(A)+A*r(B)/(A-B), for A * B >= 0; -// 2) r(A * B) <= r(A) + r(B); -// 3) r(A / B) <= r(A) + r(B); -// In addition rounding error should be added, that is always equal to -// 0.5 ULP or at most 1 epsilon. As you might see from the above formulas -// subtraction relative error may be extremely large, that's why -// epsilon robust comparator class is used to store floating point values -// and compute subtraction as the final step of the evaluation. -// For further information about relative errors and ULPs try this link: -// http://docs.sun.com/source/806-3568/ncg_goldberg.html - -namespace boost { -namespace polygon { -namespace detail { - -template <typename T> -T get_sqrt(const T& that) { - return (std::sqrt)(that); -} - -template <typename T> -bool is_pos(const T& that) { - return that > 0; -} - -template <typename T> -bool is_neg(const T& that) { - return that < 0; -} - -template <typename T> -bool is_zero(const T& that) { - return that == 0; -} - -template <typename _fpt> -class robust_fpt { - public: - typedef _fpt floating_point_type; - typedef _fpt relative_error_type; - - // Rounding error is at most 1 EPS. - enum { - ROUNDING_ERROR = 1 - }; - - robust_fpt() : fpv_(0.0), re_(0.0) {} - explicit robust_fpt(floating_point_type fpv) : - fpv_(fpv), re_(0.0) {} - robust_fpt(floating_point_type fpv, relative_error_type error) : - fpv_(fpv), re_(error) {} - - floating_point_type fpv() const { return fpv_; } - relative_error_type re() const { return re_; } - relative_error_type ulp() const { return re_; } - - robust_fpt& operator=(const robust_fpt& that) { - this->fpv_ = that.fpv_; - this->re_ = that.re_; - return *this; - } - - bool has_pos_value() const { - return is_pos(fpv_); - } - - bool has_neg_value() const { - return is_neg(fpv_); - } - - bool has_zero_value() const { - return is_zero(fpv_); - } - - robust_fpt operator-() const { - return robust_fpt(-fpv_, re_); - } - - robust_fpt& operator+=(const robust_fpt& that) { - floating_point_type fpv = this->fpv_ + that.fpv_; - if ((!is_neg(this->fpv_) && !is_neg(that.fpv_)) || - (!is_pos(this->fpv_) && !is_pos(that.fpv_))) { - this->re_ = (std::max)(this->re_, that.re_) + ROUNDING_ERROR; - } else { - floating_point_type temp = - (this->fpv_ * this->re_ - that.fpv_ * that.re_) / fpv; - if (is_neg(temp)) - temp = -temp; - this->re_ = temp + ROUNDING_ERROR; - } - this->fpv_ = fpv; - return *this; - } - - robust_fpt& operator-=(const robust_fpt& that) { - floating_point_type fpv = this->fpv_ - that.fpv_; - if ((!is_neg(this->fpv_) && !is_pos(that.fpv_)) || - (!is_pos(this->fpv_) && !is_neg(that.fpv_))) { - this->re_ = (std::max)(this->re_, that.re_) + ROUNDING_ERROR; - } else { - floating_point_type temp = - (this->fpv_ * this->re_ + that.fpv_ * that.re_) / fpv; - if (is_neg(temp)) - temp = -temp; - this->re_ = temp + ROUNDING_ERROR; - } - this->fpv_ = fpv; - return *this; - } - - robust_fpt& operator*=(const robust_fpt& that) { - this->re_ += that.re_ + ROUNDING_ERROR; - this->fpv_ *= that.fpv_; - return *this; - } - - robust_fpt& operator/=(const robust_fpt& that) { - this->re_ += that.re_ + ROUNDING_ERROR; - this->fpv_ /= that.fpv_; - return *this; - } - - robust_fpt operator+(const robust_fpt& that) const { - floating_point_type fpv = this->fpv_ + that.fpv_; - relative_error_type re; - if ((!is_neg(this->fpv_) && !is_neg(that.fpv_)) || - (!is_pos(this->fpv_) && !is_pos(that.fpv_))) { - re = (std::max)(this->re_, that.re_) + ROUNDING_ERROR; - } else { - floating_point_type temp = - (this->fpv_ * this->re_ - that.fpv_ * that.re_) / fpv; - if (is_neg(temp)) - temp = -temp; - re = temp + ROUNDING_ERROR; - } - return robust_fpt(fpv, re); - } - - robust_fpt operator-(const robust_fpt& that) const { - floating_point_type fpv = this->fpv_ - that.fpv_; - relative_error_type re; - if ((!is_neg(this->fpv_) && !is_pos(that.fpv_)) || - (!is_pos(this->fpv_) && !is_neg(that.fpv_))) { - re = (std::max)(this->re_, that.re_) + ROUNDING_ERROR; - } else { - floating_point_type temp = - (this->fpv_ * this->re_ + that.fpv_ * that.re_) / fpv; - if (is_neg(temp)) - temp = -temp; - re = temp + ROUNDING_ERROR; - } - return robust_fpt(fpv, re); - } - - robust_fpt operator*(const robust_fpt& that) const { - floating_point_type fpv = this->fpv_ * that.fpv_; - relative_error_type re = this->re_ + that.re_ + ROUNDING_ERROR; - return robust_fpt(fpv, re); - } - - robust_fpt operator/(const robust_fpt& that) const { - floating_point_type fpv = this->fpv_ / that.fpv_; - relative_error_type re = this->re_ + that.re_ + ROUNDING_ERROR; - return robust_fpt(fpv, re); - } - - robust_fpt sqrt() const { - return robust_fpt(get_sqrt(fpv_), - re_ * static_cast<relative_error_type>(0.5) + - ROUNDING_ERROR); - } - - private: - floating_point_type fpv_; - relative_error_type re_; -}; - -template <typename T> -robust_fpt<T> get_sqrt(const robust_fpt<T>& that) { - return that.sqrt(); -} - -template <typename T> -bool is_pos(const robust_fpt<T>& that) { - return that.has_pos_value(); -} - -template <typename T> -bool is_neg(const robust_fpt<T>& that) { - return that.has_neg_value(); -} - -template <typename T> -bool is_zero(const robust_fpt<T>& that) { - return that.has_zero_value(); -} - -// robust_dif consists of two not negative values: value1 and value2. -// The resulting expression is equal to the value1 - value2. -// Subtraction of a positive value is equivalent to the addition to value2 -// and subtraction of a negative value is equivalent to the addition to -// value1. The structure implicitly avoids difference computation. -template <typename T> -class robust_dif { - public: - robust_dif() : - positive_sum_(0), - negative_sum_(0) {} - - explicit robust_dif(const T& value) : - positive_sum_((value > 0)?value:0), - negative_sum_((value < 0)?-value:0) {} - - robust_dif(const T& pos, const T& neg) : - positive_sum_(pos), - negative_sum_(neg) {} - - T dif() const { - return positive_sum_ - negative_sum_; - } - - T pos() const { - return positive_sum_; - } - - T neg() const { - return negative_sum_; - } - - robust_dif<T> operator-() const { - return robust_dif(negative_sum_, positive_sum_); - } - - robust_dif<T>& operator+=(const T& val) { - if (!is_neg(val)) - positive_sum_ += val; - else - negative_sum_ -= val; - return *this; - } - - robust_dif<T>& operator+=(const robust_dif<T>& that) { - positive_sum_ += that.positive_sum_; - negative_sum_ += that.negative_sum_; - return *this; - } - - robust_dif<T>& operator-=(const T& val) { - if (!is_neg(val)) - negative_sum_ += val; - else - positive_sum_ -= val; - return *this; - } - - robust_dif<T>& operator-=(const robust_dif<T>& that) { - positive_sum_ += that.negative_sum_; - negative_sum_ += that.positive_sum_; - return *this; - } - - robust_dif<T>& operator*=(const T& val) { - if (!is_neg(val)) { - positive_sum_ *= val; - negative_sum_ *= val; - } else { - positive_sum_ *= -val; - negative_sum_ *= -val; - swap(); - } - return *this; - } - - robust_dif<T>& operator*=(const robust_dif<T>& that) { - T positive_sum = this->positive_sum_ * that.positive_sum_ + - this->negative_sum_ * that.negative_sum_; - T negative_sum = this->positive_sum_ * that.negative_sum_ + - this->negative_sum_ * that.positive_sum_; - positive_sum_ = positive_sum; - negative_sum_ = negative_sum; - return *this; - } - - robust_dif<T>& operator/=(const T& val) { - if (!is_neg(val)) { - positive_sum_ /= val; - negative_sum_ /= val; - } else { - positive_sum_ /= -val; - negative_sum_ /= -val; - swap(); - } - return *this; - } - - private: - void swap() { - (std::swap)(positive_sum_, negative_sum_); - } - - T positive_sum_; - T negative_sum_; -}; - -template<typename T> -robust_dif<T> operator+(const robust_dif<T>& lhs, - const robust_dif<T>& rhs) { - return robust_dif<T>(lhs.pos() + rhs.pos(), lhs.neg() + rhs.neg()); -} - -template<typename T> -robust_dif<T> operator+(const robust_dif<T>& lhs, const T& rhs) { - if (!is_neg(rhs)) { - return robust_dif<T>(lhs.pos() + rhs, lhs.neg()); - } else { - return robust_dif<T>(lhs.pos(), lhs.neg() - rhs); - } -} - -template<typename T> -robust_dif<T> operator+(const T& lhs, const robust_dif<T>& rhs) { - if (!is_neg(lhs)) { - return robust_dif<T>(lhs + rhs.pos(), rhs.neg()); - } else { - return robust_dif<T>(rhs.pos(), rhs.neg() - lhs); - } -} - -template<typename T> -robust_dif<T> operator-(const robust_dif<T>& lhs, - const robust_dif<T>& rhs) { - return robust_dif<T>(lhs.pos() + rhs.neg(), lhs.neg() + rhs.pos()); -} - -template<typename T> -robust_dif<T> operator-(const robust_dif<T>& lhs, const T& rhs) { - if (!is_neg(rhs)) { - return robust_dif<T>(lhs.pos(), lhs.neg() + rhs); - } else { - return robust_dif<T>(lhs.pos() - rhs, lhs.neg()); - } -} - -template<typename T> -robust_dif<T> operator-(const T& lhs, const robust_dif<T>& rhs) { - if (!is_neg(lhs)) { - return robust_dif<T>(lhs + rhs.neg(), rhs.pos()); - } else { - return robust_dif<T>(rhs.neg(), rhs.pos() - lhs); - } -} - -template<typename T> -robust_dif<T> operator*(const robust_dif<T>& lhs, - const robust_dif<T>& rhs) { - T res_pos = lhs.pos() * rhs.pos() + lhs.neg() * rhs.neg(); - T res_neg = lhs.pos() * rhs.neg() + lhs.neg() * rhs.pos(); - return robust_dif<T>(res_pos, res_neg); -} - -template<typename T> -robust_dif<T> operator*(const robust_dif<T>& lhs, const T& val) { - if (!is_neg(val)) { - return robust_dif<T>(lhs.pos() * val, lhs.neg() * val); - } else { - return robust_dif<T>(-lhs.neg() * val, -lhs.pos() * val); - } -} - -template<typename T> -robust_dif<T> operator*(const T& val, const robust_dif<T>& rhs) { - if (!is_neg(val)) { - return robust_dif<T>(val * rhs.pos(), val * rhs.neg()); - } else { - return robust_dif<T>(-val * rhs.neg(), -val * rhs.pos()); - } -} - -template<typename T> -robust_dif<T> operator/(const robust_dif<T>& lhs, const T& val) { - if (!is_neg(val)) { - return robust_dif<T>(lhs.pos() / val, lhs.neg() / val); - } else { - return robust_dif<T>(-lhs.neg() / val, -lhs.pos() / val); - } -} - -// Used to compute expressions that operate with sqrts with predefined -// relative error. Evaluates expressions of the next type: -// sum(i = 1 .. n)(A[i] * sqrt(B[i])), 1 <= n <= 4. -template <typename _int, typename _fpt, typename _converter> -class robust_sqrt_expr { - public: - enum MAX_RELATIVE_ERROR { - MAX_RELATIVE_ERROR_EVAL1 = 4, - MAX_RELATIVE_ERROR_EVAL2 = 7, - MAX_RELATIVE_ERROR_EVAL3 = 16, - MAX_RELATIVE_ERROR_EVAL4 = 25 - }; - - // Evaluates expression (re = 4 EPS): - // A[0] * sqrt(B[0]). - _fpt eval1(_int* A, _int* B) { - _fpt a = convert(A[0]); - _fpt b = convert(B[0]); - return a * get_sqrt(b); - } - - // Evaluates expression (re = 7 EPS): - // A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]). - _fpt eval2(_int* A, _int* B) { - _fpt a = eval1(A, B); - _fpt b = eval1(A + 1, B + 1); - if ((!is_neg(a) && !is_neg(b)) || - (!is_pos(a) && !is_pos(b))) - return a + b; - return convert(A[0] * A[0] * B[0] - A[1] * A[1] * B[1]) / (a - b); - } - - // Evaluates expression (re = 16 EPS): - // A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) + A[2] * sqrt(B[2]). - _fpt eval3(_int* A, _int* B) { - _fpt a = eval2(A, B); - _fpt b = eval1(A + 2, B + 2); - if ((!is_neg(a) && !is_neg(b)) || - (!is_pos(a) && !is_pos(b))) - return a + b; - tA[3] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] - A[2] * A[2] * B[2]; - tB[3] = 1; - tA[4] = A[0] * A[1] * 2; - tB[4] = B[0] * B[1]; - return eval2(tA + 3, tB + 3) / (a - b); - } - - - // Evaluates expression (re = 25 EPS): - // A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) + - // A[2] * sqrt(B[2]) + A[3] * sqrt(B[3]). - _fpt eval4(_int* A, _int* B) { - _fpt a = eval2(A, B); - _fpt b = eval2(A + 2, B + 2); - if ((!is_neg(a) && !is_neg(b)) || - (!is_pos(a) && !is_pos(b))) - return a + b; - tA[0] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] - - A[2] * A[2] * B[2] - A[3] * A[3] * B[3]; - tB[0] = 1; - tA[1] = A[0] * A[1] * 2; - tB[1] = B[0] * B[1]; - tA[2] = A[2] * A[3] * -2; - tB[2] = B[2] * B[3]; - return eval3(tA, tB) / (a - b); - } - - private: - _int tA[5]; - _int tB[5]; - _converter convert; -}; -} // detail -} // polygon -} // boost - -#endif // BOOST_POLYGON_DETAIL_VORONOI_ROBUST_FPT diff --git a/contrib/restricted/boost/boost/polygon/detail/voronoi_structures.hpp b/contrib/restricted/boost/boost/polygon/detail/voronoi_structures.hpp deleted file mode 100644 index f37a454e84..0000000000 --- a/contrib/restricted/boost/boost/polygon/detail/voronoi_structures.hpp +++ /dev/null @@ -1,450 +0,0 @@ -// Boost.Polygon library detail/voronoi_structures.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES -#define BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES - -#include <list> -#include <queue> -#include <vector> - -#include "boost/polygon/voronoi_geometry_type.hpp" - -namespace boost { -namespace polygon { -namespace detail { -// Cartesian 2D point data structure. -template <typename T> -class point_2d { - public: - typedef T coordinate_type; - - point_2d() {} - - point_2d(coordinate_type x, coordinate_type y) : - x_(x), - y_(y) {} - - bool operator==(const point_2d& that) const { - return (this->x_ == that.x()) && (this->y_ == that.y()); - } - - bool operator!=(const point_2d& that) const { - return (this->x_ != that.x()) || (this->y_ != that.y()); - } - - coordinate_type x() const { - return x_; - } - - coordinate_type y() const { - return y_; - } - - point_2d& x(coordinate_type x) { - x_ = x; - return *this; - } - - point_2d& y(coordinate_type y) { - y_ = y; - return *this; - } - - private: - coordinate_type x_; - coordinate_type y_; -}; - -// Site event type. -// Occurs when the sweepline sweeps over one of the initial sites: -// 1) point site -// 2) start-point of the segment site -// 3) endpoint of the segment site -// Implicit segment direction is defined: the start-point of -// the segment compares less than its endpoint. -// Each input segment is divided onto two site events: -// 1) One going from the start-point to the endpoint -// (is_inverse() = false) -// 2) Another going from the endpoint to the start-point -// (is_inverse() = true) -// In beach line data structure segment sites of the first -// type precede sites of the second type for the same segment. -// Members: -// point0_ - point site or segment's start-point -// point1_ - segment's endpoint if site is a segment -// sorted_index_ - the last bit encodes information if the site is inverse; -// the other bits encode site event index among the sorted site events -// initial_index_ - site index among the initial input set -// Note: for all sites is_inverse_ flag is equal to false by default. -template <typename T> -class site_event { - public: - typedef T coordinate_type; - typedef point_2d<T> point_type; - - site_event() : - point0_(0, 0), - point1_(0, 0), - sorted_index_(0), - flags_(0) {} - - site_event(coordinate_type x, coordinate_type y) : - point0_(x, y), - point1_(x, y), - sorted_index_(0), - flags_(0) {} - - explicit site_event(const point_type& point) : - point0_(point), - point1_(point), - sorted_index_(0), - flags_(0) {} - - site_event(coordinate_type x1, coordinate_type y1, - coordinate_type x2, coordinate_type y2): - point0_(x1, y1), - point1_(x2, y2), - sorted_index_(0), - flags_(0) {} - - site_event(const point_type& point1, const point_type& point2) : - point0_(point1), - point1_(point2), - sorted_index_(0), - flags_(0) {} - - bool operator==(const site_event& that) const { - return (this->point0_ == that.point0_) && - (this->point1_ == that.point1_); - } - - bool operator!=(const site_event& that) const { - return (this->point0_ != that.point0_) || - (this->point1_ != that.point1_); - } - - coordinate_type x() const { - return point0_.x(); - } - - coordinate_type y() const { - return point0_.y(); - } - - coordinate_type x0() const { - return point0_.x(); - } - - coordinate_type y0() const { - return point0_.y(); - } - - coordinate_type x1() const { - return point1_.x(); - } - - coordinate_type y1() const { - return point1_.y(); - } - - const point_type& point0() const { - return point0_; - } - - const point_type& point1() const { - return point1_; - } - - std::size_t sorted_index() const { - return sorted_index_; - } - - site_event& sorted_index(std::size_t index) { - sorted_index_ = index; - return *this; - } - - std::size_t initial_index() const { - return initial_index_; - } - - site_event& initial_index(std::size_t index) { - initial_index_ = index; - return *this; - } - - bool is_inverse() const { - return (flags_ & IS_INVERSE) ? true : false; - } - - site_event& inverse() { - std::swap(point0_, point1_); - flags_ ^= IS_INVERSE; - return *this; - } - - SourceCategory source_category() const { - return static_cast<SourceCategory>(flags_ & SOURCE_CATEGORY_BITMASK); - } - - site_event& source_category(SourceCategory source_category) { - flags_ |= source_category; - return *this; - } - - bool is_point() const { - return (point0_.x() == point1_.x()) && (point0_.y() == point1_.y()); - } - - bool is_segment() const { - return (point0_.x() != point1_.x()) || (point0_.y() != point1_.y()); - } - - private: - enum Bits { - IS_INVERSE = 0x20 // 32 - }; - - point_type point0_; - point_type point1_; - std::size_t sorted_index_; - std::size_t initial_index_; - std::size_t flags_; -}; - -// Circle event type. -// Occurs when the sweepline sweeps over the rightmost point of the Voronoi -// circle (with the center at the intersection point of the bisectors). -// Circle event is made of the two consecutive nodes in the beach line data -// structure. In case another node was inserted during algorithm execution -// between the given two nodes circle event becomes inactive. -// Variables: -// center_x_ - center x-coordinate; -// center_y_ - center y-coordinate; -// lower_x_ - leftmost x-coordinate; -// is_active_ - states whether circle event is still active. -// NOTE: lower_y coordinate is always equal to center_y. -template <typename T> -class circle_event { - public: - typedef T coordinate_type; - - circle_event() : is_active_(true) {} - - circle_event(coordinate_type c_x, - coordinate_type c_y, - coordinate_type lower_x) : - center_x_(c_x), - center_y_(c_y), - lower_x_(lower_x), - is_active_(true) {} - - coordinate_type x() const { - return center_x_; - } - - circle_event& x(coordinate_type center_x) { - center_x_ = center_x; - return *this; - } - - coordinate_type y() const { - return center_y_; - } - - circle_event& y(coordinate_type center_y) { - center_y_ = center_y; - return *this; - } - - coordinate_type lower_x() const { - return lower_x_; - } - - circle_event& lower_x(coordinate_type lower_x) { - lower_x_ = lower_x; - return *this; - } - - coordinate_type lower_y() const { - return center_y_; - } - - bool is_active() const { - return is_active_; - } - - circle_event& deactivate() { - is_active_ = false; - return *this; - } - - private: - coordinate_type center_x_; - coordinate_type center_y_; - coordinate_type lower_x_; - bool is_active_; -}; - -// Event queue data structure, holds circle events. -// During algorithm run, some of the circle events disappear (become -// inactive). Priority queue data structure doesn't support -// iterators (there is no direct ability to modify its elements). -// Instead list is used to store all the circle events and priority queue -// of the iterators to the list elements is used to keep the correct circle -// events ordering. -template <typename T, typename Predicate> -class ordered_queue { - public: - ordered_queue() {} - - bool empty() const { - return c_.empty(); - } - - const T &top() const { - return *c_.top(); - } - - void pop() { - list_iterator_type it = c_.top(); - c_.pop(); - c_list_.erase(it); - } - - T &push(const T &e) { - c_list_.push_front(e); - c_.push(c_list_.begin()); - return c_list_.front(); - } - - void clear() { - while (!c_.empty()) - c_.pop(); - c_list_.clear(); - } - - private: - typedef typename std::list<T>::iterator list_iterator_type; - - struct comparison { - bool operator() (const list_iterator_type &it1, - const list_iterator_type &it2) const { - return cmp_(*it1, *it2); - } - Predicate cmp_; - }; - - std::priority_queue< list_iterator_type, - std::vector<list_iterator_type>, - comparison > c_; - std::list<T> c_list_; - - // Disallow copy constructor and operator= - ordered_queue(const ordered_queue&); - void operator=(const ordered_queue&); -}; - -// Represents a bisector node made by two arcs that correspond to the left -// and right sites. Arc is defined as a curve with points equidistant from -// the site and from the sweepline. If the site is a point then arc is -// a parabola, otherwise it's a line segment. A segment site event will -// produce different bisectors based on its direction. -// In general case two sites will create two opposite bisectors. That's -// why the order of the sites is important to define the unique bisector. -// The one site is considered to be newer than the other one if it was -// processed by the algorithm later (has greater index). -template <typename Site> -class beach_line_node_key { - public: - typedef Site site_type; - - // Constructs degenerate bisector, used to search an arc that is above - // the given site. The input to the constructor is the new site point. - explicit beach_line_node_key(const site_type &new_site) : - left_site_(new_site), - right_site_(new_site) {} - - // Constructs a new bisector. The input to the constructor is the two - // sites that create the bisector. The order of sites is important. - beach_line_node_key(const site_type &left_site, - const site_type &right_site) : - left_site_(left_site), - right_site_(right_site) {} - - const site_type &left_site() const { - return left_site_; - } - - site_type &left_site() { - return left_site_; - } - - beach_line_node_key& left_site(const site_type &site) { - left_site_ = site; - return *this; - } - - const site_type &right_site() const { - return right_site_; - } - - site_type &right_site() { - return right_site_; - } - - beach_line_node_key& right_site(const site_type &site) { - right_site_ = site; - return *this; - } - - private: - site_type left_site_; - site_type right_site_; -}; - -// Represents edge data structure from the Voronoi output, that is -// associated as a value with beach line bisector in the beach -// line. Contains pointer to the circle event in the circle event -// queue if the edge corresponds to the right bisector of the circle event. -template <typename Edge, typename Circle> -class beach_line_node_data { - public: - explicit beach_line_node_data(Edge* new_edge) : - circle_event_(NULL), - edge_(new_edge) {} - - Circle* circle_event() const { - return circle_event_; - } - - beach_line_node_data& circle_event(Circle* circle_event) { - circle_event_ = circle_event; - return *this; - } - - Edge* edge() const { - return edge_; - } - - beach_line_node_data& edge(Edge* new_edge) { - edge_ = new_edge; - return *this; - } - - private: - Circle* circle_event_; - Edge* edge_; -}; -} // detail -} // polygon -} // boost - -#endif // BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES diff --git a/contrib/restricted/boost/boost/polygon/gmp_override.hpp b/contrib/restricted/boost/boost/polygon/gmp_override.hpp deleted file mode 100644 index 322e05d02d..0000000000 --- a/contrib/restricted/boost/boost/polygon/gmp_override.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - 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_GMP_OVERRIDE_HPP -#define BOOST_POLYGON_GMP_OVERRIDE_HPP -#include <gmpxx.h> -namespace boost { namespace polygon { - - class gmp_int { - private: - inline gmp_int(const mpq_class& input) : v_(input) {} - public: - inline gmp_int() {} - explicit inline gmp_int(long input) : v_(input) {} - inline gmp_int(const gmp_int& input) : v_(input.v_) {} - inline gmp_int& operator=(const gmp_int& that) { - v_ = that.v_; - return (*this); - } - inline gmp_int& operator=(long that) { - v_ = that; - return (*this); - } - inline operator int() const { - std::cout << "cast\n"; - mpz_class num = v_.get_num(); - mpz_class den = v_.get_den(); - num /= den; - return num.get_si(); - } - inline double get_d() const { - return v_.get_d(); - } - inline int get_num() const { - return v_.get_num().get_si(); - } - inline int get_den() const { - return v_.get_den().get_si(); - } - inline bool operator==(const gmp_int& that) const { - return v_ == that.v_; - } - inline bool operator!=(const gmp_int& that) const { - return v_ != that.v_; - } - inline bool operator<(const gmp_int& that) const { - bool retval = v_ < that.v_; - return retval; - } - inline bool operator<=(const gmp_int& that) const { - return v_ <= that.v_; - } - inline bool operator>(const gmp_int& that) const { - return v_ > that.v_; - } - inline bool operator>=(const gmp_int& that) const { - return v_ >= that.v_; - } - inline gmp_int operator+(const gmp_int& b) { - return gmp_int((*this).v_ + b.v_); - } - inline gmp_int operator-(const gmp_int& b) { - return gmp_int((*this).v_ - b.v_); - } - inline gmp_int operator*(const gmp_int& b) { - return gmp_int((*this).v_ * b.v_); - } - inline gmp_int operator/(const gmp_int& b) { - return gmp_int((*this).v_ / b.v_); - } - inline gmp_int& operator+=(const gmp_int& b) { - (*this).v_ += b.v_; - return (*this); - } - inline gmp_int& operator-=(const gmp_int& b) { - (*this).v_ -= b.v_; - return (*this); - } - inline gmp_int& operator*=(const gmp_int& b) { - (*this).v_ *= b.v_; - return (*this); - } - inline gmp_int& operator/=(const gmp_int& b) { - (*this).v_ /= b.v_; - return (*this); - } - inline gmp_int& operator++() { - ++v_; - return (*this); - } - inline gmp_int& operator--() { - --v_; - return (*this); - } - inline gmp_int operator++(int) { - gmp_int retval(*this); - ++(*this); - return retval; - } - inline gmp_int operator--(int) { - gmp_int retval(*this); - --(*this); - return retval; - } - private: - mpq_class v_; - }; - - template <> - struct high_precision_type<int> { - typedef mpq_class type; - }; - - template <> - int convert_high_precision_type<int>(const mpq_class& v) { - mpz_class num = v.get_num(); - mpz_class den = v.get_den(); - num /= den; - return num.get_si(); - }; - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/gtl.hpp b/contrib/restricted/boost/boost/polygon/gtl.hpp deleted file mode 100644 index 1fc1a574d4..0000000000 --- a/contrib/restricted/boost/boost/polygon/gtl.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - 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 GTL_GTL_HPP -#define GTL_GTL_HPP - -#ifdef __ICC -#pragma warning (push) -#pragma warning (disable:1125) -#endif - -#ifdef WIN32 -#pragma warning (push) -#pragma warning( disable: 4996 ) -#pragma warning( disable: 4800 ) -#endif - -#define BOOST_POLYGON_NO_DEPS -#include "polygon.hpp" -namespace gtl = boost::polygon; -using namespace boost::polygon::operators; - -#ifdef WIN32 -#pragma warning (pop) -#endif - -#ifdef __ICC -#pragma warning (pop) -#endif - -#endif diff --git a/contrib/restricted/boost/boost/polygon/interval_concept.hpp b/contrib/restricted/boost/boost/polygon/interval_concept.hpp deleted file mode 100644 index 3eeec0ffbb..0000000000 --- a/contrib/restricted/boost/boost/polygon/interval_concept.hpp +++ /dev/null @@ -1,934 +0,0 @@ -// Boost.Polygon library interval_concept.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_INTERVAL_CONCEPT_HPP -#define BOOST_POLYGON_INTERVAL_CONCEPT_HPP - -#include "isotropy.hpp" -#include "interval_traits.hpp" - -namespace boost { -namespace polygon { - -struct interval_concept {}; - -template <typename ConceptType> -struct is_interval_concept { - typedef gtl_no type; -}; - -template <> -struct is_interval_concept<interval_concept> { - typedef gtl_yes type; -}; - -template <typename ConceptType> -struct is_mutable_interval_concept { - typedef gtl_no type; -}; - -template <> -struct is_mutable_interval_concept<interval_concept> { - typedef gtl_yes type; -}; - -template <typename GeometryType, typename BoolType> -struct interval_coordinate_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct interval_coordinate_type_by_concept<GeometryType, gtl_yes> { - typedef typename interval_traits<GeometryType>::coordinate_type type; -}; - -template <typename GeometryType> -struct interval_coordinate_type { - typedef typename interval_coordinate_type_by_concept< - GeometryType, - typename is_interval_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -template <typename GeometryType, typename BoolType> -struct interval_difference_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct interval_difference_type_by_concept<GeometryType, gtl_yes> { - typedef typename coordinate_traits< - typename interval_traits<GeometryType>::coordinate_type - >::coordinate_difference type; -}; - -template <typename GeometryType> -struct interval_difference_type { - typedef typename interval_difference_type_by_concept< - GeometryType, - typename is_interval_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -struct y_i_get : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_get, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - typename interval_coordinate_type<IntervalType>::type ->::type get(const IntervalType& interval, direction_1d dir) { - return interval_traits<IntervalType>::get(interval, dir); -} - -struct y_i_set : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_set, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - void ->::type set(IntervalType& interval, direction_1d dir, - typename interval_mutable_traits<IntervalType>::coordinate_type value) { - interval_mutable_traits<IntervalType>::set(interval, dir, value); -} - -struct y_i_construct : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_construct, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type construct( - typename interval_mutable_traits<IntervalType>::coordinate_type low, - typename interval_mutable_traits<IntervalType>::coordinate_type high) { - if (low > high) { - (std::swap)(low, high); - } - return interval_mutable_traits<IntervalType>::construct(low, high); -} - -struct y_i_copy_construct : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_copy_construct, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type copy_construct(const IntervalType2& interval) { - return construct<IntervalType1>(get(interval, LOW), get(interval, HIGH)); -} - -struct y_i_assign : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_assign, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type& assign(IntervalType1& lvalue, const IntervalType2& rvalue) { - set(lvalue, LOW, get(rvalue, LOW)); - set(lvalue, HIGH, get(rvalue, HIGH)); - return lvalue; -} - -struct y_i_low : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_low, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - typename interval_coordinate_type<IntervalType>::type ->::type low(const IntervalType& interval) { - return get(interval, LOW); -} - -struct y_i_high : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_high, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - typename interval_coordinate_type<IntervalType>::type ->::type high(const IntervalType& interval) { - return get(interval, HIGH); -} - -struct y_i_low2 : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_low2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - void ->::type low(IntervalType& interval, - typename interval_mutable_traits<IntervalType>::coordinate_type value) { - set(interval, LOW, value); -} - -struct y_i_high2 : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_high2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - void ->::type high(IntervalType& interval, - typename interval_mutable_traits<IntervalType>::coordinate_type value) { - set(interval, HIGH, value); -} - -struct y_i_equivalence : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_equivalence, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type equivalence( - const IntervalType1& interval1, - const IntervalType2& interval2) { - return (get(interval1, LOW) == get(interval2, LOW)) && - (get(interval1, HIGH) == get(interval2, HIGH)); -} - -struct y_i_contains : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_contains, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - bool ->::type contains( - const IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type value, - bool consider_touch = true ) { - if (consider_touch) { - return value <= high(interval) && value >= low(interval); - } else { - return value < high(interval) && value > low(interval); - } -} - -struct y_i_contains2 : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_contains2, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type contains( - const IntervalType1& interval1, - const IntervalType2& interval2, - bool consider_touch = true) { - return contains(interval1, get(interval2, LOW), consider_touch) && - contains(interval1, get(interval2, HIGH), consider_touch); -} - -struct y_i_center : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_center, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - typename interval_coordinate_type<IntervalType>::type ->::type center(const IntervalType& interval) { - return (high(interval) + low(interval)) / 2; -} - -struct y_i_delta : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_delta, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - typename interval_difference_type<IntervalType>::type ->::type delta(const IntervalType& interval) { - typedef typename interval_difference_type<IntervalType>::type diff_type; - return static_cast<diff_type>(high(interval)) - - static_cast<diff_type>(low(interval)); -} - -struct y_i_flip : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_flip, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, -IntervalType>::type& flip( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type axis = 0) { - typename interval_coordinate_type<IntervalType>::type newLow, newHigh; - newLow = 2 * axis - high(interval); - newHigh = 2 * axis - low(interval); - low(interval, newLow); - high(interval, newHigh); - return interval; -} - -struct y_i_scale_up : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_scale_up, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& scale_up( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type factor) { - typename interval_coordinate_type<IntervalType>::type newHigh = - high(interval) * factor; - low(interval, low(interval) * factor); - high(interval, (newHigh)); - return interval; -} - -struct y_i_scale_down : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_scale_down, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& scale_down( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type factor) { - typename interval_coordinate_type<IntervalType>::type newHigh = - high(interval) / factor; - low(interval, low(interval) / factor); - high(interval, (newHigh)); - return interval; -} - -// TODO(asydorchuk): Deprecated. -struct y_i_scale : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_scale, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& scale(IntervalType& interval, double factor) { - typedef typename interval_coordinate_type<IntervalType>::type Unit; - Unit newHigh = scaling_policy<Unit>::round( - static_cast<double>(high(interval)) * factor); - low(interval, scaling_policy<Unit>::round( - static_cast<double>(low(interval)) * factor)); - high(interval, (newHigh)); - return interval; -} - -struct y_i_move : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_move, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& move( - IntervalType& interval, - typename interval_difference_type<IntervalType>::type displacement) { - typedef typename interval_coordinate_type<IntervalType>::type ctype; - typedef typename coordinate_traits<ctype>::coordinate_difference Unit; - low(interval, static_cast<ctype>( - static_cast<Unit>(low(interval)) + displacement)); - high(interval, static_cast<ctype>( - static_cast<Unit>(high(interval)) + displacement)); - return interval; -} - -struct y_i_convolve : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_convolve, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& convolve( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type value) { - typedef typename interval_coordinate_type<IntervalType>::type Unit; - Unit newLow = low(interval) + value; - Unit newHigh = high(interval) + value; - low(interval, newLow); - high(interval, newHigh); - return interval; -} - -struct y_i_deconvolve : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_deconvolve, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& deconvolve( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type value) { - typedef typename interval_coordinate_type<IntervalType>::type Unit; - Unit newLow = low(interval) - value; - Unit newHigh = high(interval) - value; - low(interval, newLow); - high(interval, newHigh); - return interval; -} - -struct y_i_convolve2 : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_convolve2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type& convolve(IntervalType1& lvalue, const IntervalType2& rvalue) { - typedef typename interval_coordinate_type<IntervalType1>::type Unit; - Unit newLow = low(lvalue) + low(rvalue); - Unit newHigh = high(lvalue) + high(rvalue); - low(lvalue, newLow); - high(lvalue, newHigh); - return lvalue; -} - -struct y_i_deconvolve2 : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_deconvolve2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type& deconvolve(IntervalType1& lvalue, const IntervalType2& rvalue) { - typedef typename interval_coordinate_type<IntervalType1>::type Unit; - Unit newLow = low(lvalue) - low(rvalue); - Unit newHigh = high(lvalue) - high(rvalue); - low(lvalue, newLow); - high(lvalue, newHigh); - return lvalue; -} - -struct y_i_reconvolve : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_reconvolve, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type& reflected_convolve( - IntervalType1& lvalue, - const IntervalType2& rvalue) { - typedef typename interval_coordinate_type<IntervalType1>::type Unit; - Unit newLow = low(lvalue) - high(rvalue); - Unit newHigh = high(lvalue) - low(rvalue); - low(lvalue, newLow); - high(lvalue, newHigh); - return lvalue; -} - -struct y_i_redeconvolve : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_redeconvolve, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type& reflected_deconvolve( - IntervalType1& lvalue, - const IntervalType2& rvalue) { - typedef typename interval_coordinate_type<IntervalType1>::type Unit; - Unit newLow = low(lvalue) + high(rvalue); - Unit newHigh = high(lvalue) + low(rvalue); - low(lvalue, newLow); - high(lvalue, newHigh); - return lvalue; -} - -struct y_i_e_dist1 : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and<y_i_e_dist1, - typename is_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - typename interval_difference_type<IntervalType>::type ->::type euclidean_distance( - const IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type position) { - typedef typename interval_difference_type<IntervalType>::type Unit; - Unit dist[3] = { - 0, - (Unit)low(interval) - (Unit)position, - (Unit)position - (Unit)high(interval) - }; - return dist[(dist[1] > 0) + ((dist[2] > 0) << 1)]; -} - -struct y_i_e_dist2 : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_e_dist2, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - typename interval_difference_type<IntervalType1>::type ->::type euclidean_distance( - const IntervalType1& interval1, - const IntervalType2& interval2) { - typedef typename interval_difference_type<IntervalType1>::type Unit; - Unit dist[3] = { - 0, - (Unit)low(interval1) - (Unit)high(interval2), - (Unit)low(interval2) - (Unit)high(interval1) - }; - return dist[(dist[1] > 0) + ((dist[2] > 0) << 1)]; -} - -struct y_i_e_intersects : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_e_intersects, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type intersects( - const IntervalType1& interval1, - const IntervalType2& interval2, - bool consider_touch = true) { - return consider_touch ? - (low(interval1) <= high(interval2)) && - (high(interval1) >= low(interval2)) : - (low(interval1) < high(interval2)) && - (high(interval1) > low(interval2)); -} - -struct y_i_e_bintersect : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_e_bintersect, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type boundaries_intersect( - const IntervalType1& interval1, - const IntervalType2& interval2, - bool consider_touch = true) { - return (contains(interval1, low(interval2), consider_touch) || - contains(interval1, high(interval2), consider_touch)) && - (contains(interval2, low(interval1), consider_touch) || - contains(interval2, high(interval1), consider_touch)); -} - -struct y_i_intersect : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_intersect, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type intersect( - IntervalType1& lvalue, - const IntervalType2& rvalue, - bool consider_touch = true) { - typedef typename interval_coordinate_type<IntervalType1>::type Unit; - Unit lowVal = (std::max)(low(lvalue), low(rvalue)); - Unit highVal = (std::min)(high(lvalue), high(rvalue)); - bool valid = consider_touch ? lowVal <= highVal : lowVal < highVal; - if (valid) { - low(lvalue, lowVal); - high(lvalue, highVal); - } - return valid; -} - -struct y_i_g_intersect : gtl_yes {}; - -// TODO(asydorchuk): Deprecated. -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_g_intersect, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - IntervalType1 ->::type& generalized_intersect( - IntervalType1& lvalue, - const IntervalType2& rvalue) { - typedef typename interval_coordinate_type<IntervalType1>::type Unit; - Unit coords[4] = {low(lvalue), high(lvalue), low(rvalue), high(rvalue)}; - // TODO(asydorchuk): consider implementing faster sorting of small - // fixed length range. - polygon_sort(coords, coords+4); - low(lvalue, coords[1]); - high(lvalue, coords[2]); - return lvalue; -} - -struct y_i_abuts1 : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_abuts1, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type abuts( - const IntervalType1& interval1, - const IntervalType2& interval2, - direction_1d dir) { - return dir.to_int() ? low(interval2) == high(interval1) : - low(interval1) == high(interval2); -} - -struct y_i_abuts2 : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_abuts2, - typename is_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type abuts( - const IntervalType1& interval1, - const IntervalType2& interval2) { - return abuts(interval1, interval2, HIGH) || - abuts(interval1, interval2, LOW); -} - -struct y_i_bloat : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_bloat, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& bloat( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type bloating) { - low(interval, low(interval) - bloating); - high(interval, high(interval) + bloating); - return interval; -} - -struct y_i_bloat2 : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_bloat2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& bloat( - IntervalType& interval, - direction_1d dir, - typename interval_coordinate_type<IntervalType>::type bloating) { - set(interval, dir, get(interval, dir) + dir.get_sign() * bloating); - return interval; -} - -struct y_i_shrink : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_shrink, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& shrink( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type shrinking) { - return bloat(interval, -shrinking); -} - -struct y_i_shrink2 : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_shrink2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type& shrink( - IntervalType& interval, - direction_1d dir, - typename interval_coordinate_type<IntervalType>::type shrinking) { - return bloat(interval, dir, -shrinking); -} - -struct y_i_encompass : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_encompass, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type - >::type, - bool ->::type encompass(IntervalType1& interval1, const IntervalType2& interval2) { - bool retval = !contains(interval1, interval2, true); - low(interval1, (std::min)(low(interval1), low(interval2))); - high(interval1, (std::max)(high(interval1), high(interval2))); - return retval; -} - -struct y_i_encompass2 : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_encompass2, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - bool ->::type encompass( - IntervalType& interval, - typename interval_coordinate_type<IntervalType>::type value) { - bool retval = !contains(interval, value, true); - low(interval, (std::min)(low(interval), value)); - high(interval, (std::max)(high(interval), value)); - return retval; -} - -struct y_i_get_half : gtl_yes {}; - -template <typename IntervalType> -typename enable_if< - typename gtl_and< - y_i_get_half, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType>::type - >::type - >::type, - IntervalType ->::type get_half(const IntervalType& interval, direction_1d dir) { - typedef typename interval_coordinate_type<IntervalType>::type Unit; - Unit c = (get(interval, LOW) + get(interval, HIGH)) / 2; - return construct<IntervalType>( - (dir == LOW) ? get(interval, LOW) : c, - (dir == LOW) ? c : get(interval, HIGH)); -} - -struct y_i_join_with : gtl_yes {}; - -template <typename IntervalType1, typename IntervalType2> -typename enable_if< - typename gtl_and_3< - y_i_join_with, - typename is_mutable_interval_concept< - typename geometry_concept<IntervalType1>::type - >::type, - typename is_interval_concept< - typename geometry_concept<IntervalType2>::type - >::type>::type, - bool ->::type join_with(IntervalType1& interval1, const IntervalType2& interval2) { - if (abuts(interval1, interval2)) { - encompass(interval1, interval2); - return true; - } - return false; -} -} // polygon -} // boost - -#endif // BOOST_POLYGON_INTERVAL_CONCEPT_HPP diff --git a/contrib/restricted/boost/boost/polygon/interval_data.hpp b/contrib/restricted/boost/boost/polygon/interval_data.hpp deleted file mode 100644 index b297624dc2..0000000000 --- a/contrib/restricted/boost/boost/polygon/interval_data.hpp +++ /dev/null @@ -1,118 +0,0 @@ -// Boost.Polygon library interval_data.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_INTERVAL_DATA_HPP -#define BOOST_POLYGON_INTERVAL_DATA_HPP - -#include "isotropy.hpp" -#include "interval_concept.hpp" - -namespace boost { -namespace polygon { - -template <typename T> -class interval_data { - public: - typedef T coordinate_type; - - interval_data() -#ifndef BOOST_POLYGON_MSVC - : coords_() -#endif - {} - - interval_data(coordinate_type low, coordinate_type high) { - coords_[LOW] = low; - coords_[HIGH] = high; - } - - interval_data(const interval_data& that) { - coords_[0] = that.coords_[0]; - coords_[1] = that.coords_[1]; - } - - interval_data& operator=(const interval_data& that) { - coords_[0] = that.coords_[0]; - coords_[1] = that.coords_[1]; - return *this; - } - - template <typename IntervalType> - interval_data& operator=(const IntervalType& that) { - assign(*this, that); - return *this; - } - - coordinate_type get(direction_1d dir) const { - return coords_[dir.to_int()]; - } - - void set(direction_1d dir, coordinate_type value) { - coords_[dir.to_int()] = value; - } - - coordinate_type low() const { - return coords_[0]; - } - - interval_data& low(coordinate_type value) { - coords_[LOW] = value; - return *this; - } - - coordinate_type high() const { - return coords_[1]; - } - - interval_data& high(coordinate_type value) { - coords_[HIGH] = value; - return *this; - } - - bool operator==(const interval_data& that) const { - return low() == that.low() && high() == that.high(); - } - - bool operator!=(const interval_data& that) const { - return low() != that.low() || high() != that.high(); - } - - bool operator<(const interval_data& that) const { - if (coords_[0] != that.coords_[0]) { - return coords_[0] < that.coords_[0]; - } - return coords_[1] < that.coords_[1]; - } - - bool operator<=(const interval_data& that) const { - return !(that < *this); - } - - bool operator>(const interval_data& that) const { - return that < *this; - } - - bool operator>=(const interval_data& that) const { - return !((*this) < that); - } - - private: - coordinate_type coords_[2]; -}; - -template <typename CType> -struct geometry_concept< interval_data<CType> > { - typedef interval_concept type; -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_INTERVAL_DATA_HPP diff --git a/contrib/restricted/boost/boost/polygon/interval_traits.hpp b/contrib/restricted/boost/boost/polygon/interval_traits.hpp deleted file mode 100644 index 9c9062f456..0000000000 --- a/contrib/restricted/boost/boost/polygon/interval_traits.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Boost.Polygon library interval_traits.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_INTERVAL_TRAITS_HPP -#define BOOST_POLYGON_INTERVAL_TRAITS_HPP - -#include "isotropy.hpp" - -namespace boost { -namespace polygon { - -template <typename Interval> -struct interval_traits { - typedef Interval interval_type; - typedef typename interval_type::coordinate_type coordinate_type; - - static coordinate_type get(const interval_type& interval, direction_1d dir) { - return interval.get(dir); - } -}; - -template <typename Interval> -struct interval_mutable_traits { - typedef Interval interval_type; - typedef typename interval_type::coordinate_type coordinate_type; - - static void set( - interval_type& interval, direction_1d dir, coordinate_type value) { - interval.set(dir, value); - } - - static interval_type construct(coordinate_type low, coordinate_type high) { - return interval_type(low, high); - } -}; -} // polygon -} // boost - -#endif // BOOST_POLICY_INTERVAL_TRAITS_HPP diff --git a/contrib/restricted/boost/boost/polygon/isotropy.hpp b/contrib/restricted/boost/boost/polygon/isotropy.hpp deleted file mode 100644 index 117d6a55d6..0000000000 --- a/contrib/restricted/boost/boost/polygon/isotropy.hpp +++ /dev/null @@ -1,584 +0,0 @@ -/* - 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_ISOTROPY_HPP -#define BOOST_POLYGON_ISOTROPY_HPP - -//external -#include <cmath> -#include <cstddef> -#include <cstdlib> -#include <vector> -#include <deque> -#include <map> -#include <set> -#include <list> -//#include <iostream> -#include <algorithm> -#include <limits> -#include <iterator> -#include <string> - -#ifndef BOOST_POLYGON_NO_DEPS - -#include <boost/config.hpp> -#ifdef BOOST_MSVC -#define BOOST_POLYGON_MSVC -#endif -#ifdef BOOST_INTEL -#define BOOST_POLYGON_ICC -#endif -#ifdef BOOST_HAS_LONG_LONG -#define BOOST_POLYGON_USE_LONG_LONG -typedef boost::long_long_type polygon_long_long_type; -typedef boost::ulong_long_type polygon_ulong_long_type; -//typedef long long polygon_long_long_type; -//typedef unsigned long long polygon_ulong_long_type; -#endif -#include <boost/mpl/size_t.hpp> -#include <boost/mpl/protect.hpp> -#include <boost/utility/enable_if.hpp> -#include <boost/mpl/bool.hpp> -#include <boost/mpl/and.hpp> -#include <boost/mpl/or.hpp> -#else - -#ifdef _WIN32 -#define BOOST_POLYGON_MSVC -#endif -#ifdef __ICC -#define BOOST_POLYGON_ICC -#endif -#define BOOST_POLYGON_USE_LONG_LONG -typedef long long polygon_long_long_type; -typedef unsigned long long polygon_ulong_long_type; - - namespace boost { - template <bool B, class T = void> - struct enable_if_c { - typedef T type; - }; - - template <class T> - struct enable_if_c<false, T> {}; - - template <class Cond, class T = void> - struct enable_if : public enable_if_c<Cond::value, T> {}; - - template <bool B, class T> - struct lazy_enable_if_c { - typedef typename T::type type; - }; - - template <class T> - struct lazy_enable_if_c<false, T> {}; - - template <class Cond, class T> - struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {}; - - - template <bool B, class T = void> - struct disable_if_c { - typedef T type; - }; - - template <class T> - struct disable_if_c<true, T> {}; - - template <class Cond, class T = void> - struct disable_if : public disable_if_c<Cond::value, T> {}; - - template <bool B, class T> - struct lazy_disable_if_c { - typedef typename T::type type; - }; - - template <class T> - struct lazy_disable_if_c<true, T> {}; - - template <class Cond, class T> - struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {}; - } - -#endif - -namespace boost { namespace polygon{ - - enum GEOMETRY_CONCEPT_ID { - COORDINATE_CONCEPT, - INTERVAL_CONCEPT, - POINT_CONCEPT, - POINT_3D_CONCEPT, - RECTANGLE_CONCEPT, - POLYGON_90_CONCEPT, - POLYGON_90_WITH_HOLES_CONCEPT, - POLYGON_45_CONCEPT, - POLYGON_45_WITH_HOLES_CONCEPT, - POLYGON_CONCEPT, - POLYGON_WITH_HOLES_CONCEPT, - POLYGON_90_SET_CONCEPT, - POLYGON_45_SET_CONCEPT, - POLYGON_SET_CONCEPT - }; - - struct undefined_concept {}; - - template <typename T> - struct geometry_concept { typedef undefined_concept type; }; - - template <typename GCT, typename T> - struct view_of {}; - - template <typename T1, typename T2> - view_of<T1, T2> view_as(const T2& obj) { return view_of<T1, T2>(obj); } - - template <typename T, bool /*enable*/ = true> - struct coordinate_traits {}; - - //used to override long double with an infinite precision datatype - template <typename T> - struct high_precision_type { - typedef long double type; - }; - - template <typename T> - T convert_high_precision_type(const typename high_precision_type<T>::type& v) { - return T(v); - } - - //used to override std::sort with an alternative (parallel) algorithm - template <typename iter_type> - void polygon_sort(iter_type _b_, iter_type _e_); - - template <typename iter_type, typename pred_type> - void polygon_sort(iter_type _b_, iter_type _e_, const pred_type& _pred_); - - - template <> - struct coordinate_traits<int> { - typedef int coordinate_type; - typedef long double area_type; -#ifdef BOOST_POLYGON_USE_LONG_LONG - typedef polygon_long_long_type manhattan_area_type; - typedef polygon_ulong_long_type unsigned_area_type; - typedef polygon_long_long_type coordinate_difference; -#else - typedef long manhattan_area_type; - typedef unsigned long unsigned_area_type; - typedef long coordinate_difference; -#endif - typedef long double coordinate_distance; - }; - - template<> - struct coordinate_traits<long, sizeof(long) == sizeof(int)> { - typedef coordinate_traits<int> cT_; - typedef cT_::coordinate_type coordinate_type; - typedef cT_::area_type area_type; - typedef cT_::manhattan_area_type manhattan_area_type; - typedef cT_::unsigned_area_type unsigned_area_type; - typedef cT_::coordinate_difference coordinate_difference; - typedef cT_::coordinate_distance coordinate_distance; - }; - -#ifdef BOOST_POLYGON_USE_LONG_LONG - template <> - struct coordinate_traits<polygon_long_long_type> { - typedef polygon_long_long_type coordinate_type; - typedef long double area_type; - typedef polygon_long_long_type manhattan_area_type; - typedef polygon_ulong_long_type unsigned_area_type; - typedef polygon_long_long_type coordinate_difference; - typedef long double coordinate_distance; - }; - - template<> - struct coordinate_traits<long, sizeof(long) == sizeof(polygon_long_long_type)> { - typedef coordinate_traits<polygon_long_long_type> cT_; - typedef cT_::coordinate_type coordinate_type; - typedef cT_::area_type area_type; - typedef cT_::manhattan_area_type manhattan_area_type; - typedef cT_::unsigned_area_type unsigned_area_type; - typedef cT_::coordinate_difference coordinate_difference; - typedef cT_::coordinate_distance coordinate_distance; - }; -#endif - - template <> - struct coordinate_traits<float> { - typedef float coordinate_type; - typedef float area_type; - typedef float manhattan_area_type; - typedef float unsigned_area_type; - typedef float coordinate_difference; - typedef float coordinate_distance; - }; - - template <> - struct coordinate_traits<double> { - typedef double coordinate_type; - typedef double area_type; - typedef double manhattan_area_type; - typedef double unsigned_area_type; - typedef double coordinate_difference; - typedef double coordinate_distance; - }; - - template <> - struct coordinate_traits<long double> { - typedef long double coordinate_type; - typedef long double area_type; - typedef long double manhattan_area_type; - typedef long double unsigned_area_type; - typedef long double coordinate_difference; - typedef long double coordinate_distance; - }; - - template <typename T> - struct scaling_policy { - template <typename T2> - static inline T round(T2 t2) { - return (T)std::floor(t2+0.5); - } - - static inline T round(T t2) { - return t2; - } - }; - - struct coordinate_concept {}; - - template <> - struct geometry_concept<int> { typedef coordinate_concept type; }; -#ifdef BOOST_POLYGON_USE_LONG_LONG - template <> - struct geometry_concept<polygon_long_long_type> { typedef coordinate_concept type; }; -#endif - template <> - struct geometry_concept<float> { typedef coordinate_concept type; }; - template <> - struct geometry_concept<double> { typedef coordinate_concept type; }; - template <> - struct geometry_concept<long double> { typedef coordinate_concept type; }; - -#ifndef BOOST_POLYGON_NO_DEPS - struct gtl_no : mpl::bool_<false> {}; - struct gtl_yes : mpl::bool_<true> {}; - template <typename T, typename T2> - struct gtl_and : mpl::and_<T, T2> {}; - template <typename T, typename T2, typename T3> - struct gtl_and_3 : mpl::and_<T, T2, T3> {}; - template <typename T, typename T2, typename T3, typename T4> - struct gtl_and_4 : mpl::and_<T, T2, T3, T4> {}; -// template <typename T, typename T2> -// struct gtl_or : mpl::or_<T, T2> {}; -// template <typename T, typename T2, typename T3> -// struct gtl_or_3 : mpl::or_<T, T2, T3> {}; -// template <typename T, typename T2, typename T3, typename T4> -// struct gtl_or_4 : mpl::or_<T, T2, T3, T4> {}; -#else - struct gtl_no { static const bool value = false; }; - struct gtl_yes { typedef gtl_yes type; - static const bool value = true; }; - - template <bool T, bool T2> - struct gtl_and_c { typedef gtl_no type; }; - template <> - struct gtl_and_c<true, true> { typedef gtl_yes type; }; - - template <typename T, typename T2> - struct gtl_and : gtl_and_c<T::value, T2::value> {}; - template <typename T, typename T2, typename T3> - struct gtl_and_3 { typedef typename gtl_and< - T, typename gtl_and<T2, T3>::type>::type type; }; - - template <typename T, typename T2, typename T3, typename T4> - struct gtl_and_4 { typedef typename gtl_and_3< - T, T2, typename gtl_and<T3, T4>::type>::type type; }; -#endif - template <typename T, typename T2> - struct gtl_or { typedef gtl_yes type; }; - template <typename T> - struct gtl_or<T, T> { typedef T type; }; - - template <typename T, typename T2, typename T3> - struct gtl_or_3 { typedef typename gtl_or< - T, typename gtl_or<T2, T3>::type>::type type; }; - - template <typename T, typename T2, typename T3, typename T4> - struct gtl_or_4 { typedef typename gtl_or< - T, typename gtl_or_3<T2, T3, T4>::type>::type type; }; - - template <typename T> - struct gtl_not { typedef gtl_no type; }; - template <> - struct gtl_not<gtl_no> { typedef gtl_yes type; }; - - template <typename T> - struct gtl_if { -#ifdef BOOST_POLYGON_MSVC - typedef gtl_no type; -#endif - }; - template <> - struct gtl_if<gtl_yes> { typedef gtl_yes type; }; - - template <typename T, typename T2> - struct gtl_same_type { typedef gtl_no type; }; - template <typename T> - struct gtl_same_type<T, T> { typedef gtl_yes type; }; - template <typename T, typename T2> - struct gtl_different_type { typedef typename gtl_not<typename gtl_same_type<T, T2>::type>::type type; }; - - struct manhattan_domain {}; - struct forty_five_domain {}; - struct general_domain {}; - - template <typename T> - struct geometry_domain { typedef general_domain type; }; - - template <typename domain_type, typename coordinate_type> - struct area_type_by_domain { typedef typename coordinate_traits<coordinate_type>::area_type type; }; - template <typename coordinate_type> - struct area_type_by_domain<manhattan_domain, coordinate_type> { - typedef typename coordinate_traits<coordinate_type>::manhattan_area_type type; }; - - struct y_c_edist : gtl_yes {}; - - template <typename coordinate_type_1, typename coordinate_type_2> - typename enable_if< - typename gtl_and_3<y_c_edist, typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type, - typename coordinate_traits<coordinate_type_1>::coordinate_difference>::type - euclidean_distance(const coordinate_type_1& lvalue, const coordinate_type_2& rvalue) { - typedef typename coordinate_traits<coordinate_type_1>::coordinate_difference Unit; - return (lvalue < rvalue) ? (Unit)rvalue - (Unit)lvalue : (Unit)lvalue - (Unit)rvalue; - } - - - - // predicated_swap swaps a and b if pred is true - - // predicated_swap is guarenteed to behave the same as - // if(pred){ - // T tmp = a; - // a = b; - // b = tmp; - // } - // but will not generate a branch instruction. - // predicated_swap always creates a temp copy of a, but does not - // create more than one temp copy of an input. - // predicated_swap can be used to optimize away branch instructions in C++ - template <class T> - inline bool predicated_swap(const bool& pred, - T& a, - T& b) { - const T tmp = a; - const T* input[2] = {&b, &tmp}; - a = *input[!pred]; - b = *input[pred]; - return pred; - } - - enum direction_1d_enum { LOW = 0, HIGH = 1, - LEFT = 0, RIGHT = 1, - CLOCKWISE = 0, COUNTERCLOCKWISE = 1, - REVERSE = 0, FORWARD = 1, - NEGATIVE = 0, POSITIVE = 1 }; - enum orientation_2d_enum { HORIZONTAL = 0, VERTICAL = 1 }; - enum direction_2d_enum { WEST = 0, EAST = 1, SOUTH = 2, NORTH = 3 }; - enum orientation_3d_enum { PROXIMAL = 2 }; - enum direction_3d_enum { DOWN = 4, UP = 5 }; - enum winding_direction { - clockwise_winding = 0, - counterclockwise_winding = 1, - unknown_winding = 2 - }; - - class direction_2d; - class direction_3d; - class orientation_2d; - - class direction_1d { - private: - unsigned int val_; - explicit direction_1d(int d); - public: - inline direction_1d() : val_(LOW) {} - inline direction_1d(const direction_1d& that) : val_(that.val_) {} - inline direction_1d(const direction_1d_enum val) : val_(val) {} - explicit inline direction_1d(const direction_2d& that); - explicit inline direction_1d(const direction_3d& that); - inline direction_1d& operator = (const direction_1d& d) { - val_ = d.val_; return * this; } - inline bool operator==(direction_1d d) const { return (val_ == d.val_); } - inline bool operator!=(direction_1d d) const { return !((*this) == d); } - inline unsigned int to_int(void) const { return val_; } - inline direction_1d& backward() { val_ ^= 1; return *this; } - inline int get_sign() const { return val_ * 2 - 1; } - }; - - class direction_2d; - - class orientation_2d { - private: - unsigned int val_; - explicit inline orientation_2d(int o); - public: - inline orientation_2d() : val_(HORIZONTAL) {} - inline orientation_2d(const orientation_2d& ori) : val_(ori.val_) {} - inline orientation_2d(const orientation_2d_enum val) : val_(val) {} - explicit inline orientation_2d(const direction_2d& that); - inline orientation_2d& operator=(const orientation_2d& ori) { - val_ = ori.val_; return * this; } - inline bool operator==(orientation_2d that) const { return (val_ == that.val_); } - inline bool operator!=(orientation_2d that) const { return (val_ != that.val_); } - inline unsigned int to_int() const { return (val_); } - inline void turn_90() { val_ = val_^ 1; } - inline orientation_2d get_perpendicular() const { - orientation_2d retval = *this; - retval.turn_90(); - return retval; - } - inline direction_2d get_direction(direction_1d dir) const; - }; - - class direction_2d { - private: - int val_; - - public: - - inline direction_2d() : val_(WEST) {} - - inline direction_2d(const direction_2d& that) : val_(that.val_) {} - - inline direction_2d(const direction_2d_enum val) : val_(val) {} - - inline direction_2d& operator=(const direction_2d& d) { - val_ = d.val_; - return * this; - } - - inline ~direction_2d() { } - - inline bool operator==(direction_2d d) const { return (val_ == d.val_); } - inline bool operator!=(direction_2d d) const { return !((*this) == d); } - inline bool operator< (direction_2d d) const { return (val_ < d.val_); } - inline bool operator<=(direction_2d d) const { return (val_ <= d.val_); } - inline bool operator> (direction_2d d) const { return (val_ > d.val_); } - inline bool operator>=(direction_2d d) const { return (val_ >= d.val_); } - - // Casting to int - inline unsigned int to_int(void) const { return val_; } - - inline direction_2d backward() const { - // flip the LSB, toggles 0 - 1 and 2 - 3 - return direction_2d(direction_2d_enum(val_ ^ 1)); - } - - // Returns a direction 90 degree left (LOW) or right(HIGH) to this one - inline direction_2d turn(direction_1d t) const { - return direction_2d(direction_2d_enum(val_ ^ 3 ^ (val_ >> 1) ^ t.to_int())); - } - - // Returns a direction 90 degree left to this one - inline direction_2d left() const {return turn(HIGH);} - - // Returns a direction 90 degree right to this one - inline direction_2d right() const {return turn(LOW);} - - // N, E are positive, S, W are negative - inline bool is_positive() const {return (val_ & 1);} - inline bool is_negative() const {return !is_positive();} - inline int get_sign() const {return ((is_positive()) << 1) -1;} - - }; - - direction_1d::direction_1d(const direction_2d& that) : val_(that.to_int() & 1) {} - - orientation_2d::orientation_2d(const direction_2d& that) : val_(that.to_int() >> 1) {} - - direction_2d orientation_2d::get_direction(direction_1d dir) const { - return direction_2d(direction_2d_enum((val_ << 1) + dir.to_int())); - } - - class orientation_3d { - private: - unsigned int val_; - explicit inline orientation_3d(int o); - public: - inline orientation_3d() : val_((int)HORIZONTAL) {} - inline orientation_3d(const orientation_3d& ori) : val_(ori.val_) {} - inline orientation_3d(orientation_2d ori) : val_(ori.to_int()) {} - inline orientation_3d(const orientation_3d_enum val) : val_(val) {} - explicit inline orientation_3d(const direction_2d& that); - explicit inline orientation_3d(const direction_3d& that); - inline ~orientation_3d() { } - inline orientation_3d& operator=(const orientation_3d& ori) { - val_ = ori.val_; return * this; } - inline bool operator==(orientation_3d that) const { return (val_ == that.val_); } - inline bool operator!=(orientation_3d that) const { return (val_ != that.val_); } - inline unsigned int to_int() const { return (val_); } - inline direction_3d get_direction(direction_1d dir) const; - }; - - class direction_3d { - private: - int val_; - - public: - - inline direction_3d() : val_(WEST) {} - - inline direction_3d(direction_2d that) : val_(that.to_int()) {} - inline direction_3d(const direction_3d& that) : val_(that.val_) {} - - inline direction_3d(const direction_2d_enum val) : val_(val) {} - inline direction_3d(const direction_3d_enum val) : val_(val) {} - - inline direction_3d& operator=(direction_3d d) { - val_ = d.val_; - return * this; - } - - inline ~direction_3d() { } - - inline bool operator==(direction_3d d) const { return (val_ == d.val_); } - inline bool operator!=(direction_3d d) const { return !((*this) == d); } - inline bool operator< (direction_3d d) const { return (val_ < d.val_); } - inline bool operator<=(direction_3d d) const { return (val_ <= d.val_); } - inline bool operator> (direction_3d d) const { return (val_ > d.val_); } - inline bool operator>=(direction_3d d) const { return (val_ >= d.val_); } - - // Casting to int - inline unsigned int to_int(void) const { return val_; } - - inline direction_3d backward() const { - // flip the LSB, toggles 0 - 1 and 2 - 3 and 4 - 5 - return direction_2d(direction_2d_enum(val_ ^ 1)); - } - - // N, E, U are positive, S, W, D are negative - inline bool is_positive() const {return (val_ & 1);} - inline bool is_negative() const {return !is_positive();} - inline int get_sign() const {return ((is_positive()) << 1) -1;} - - }; - - direction_1d::direction_1d(const direction_3d& that) : val_(that.to_int() & 1) {} - orientation_3d::orientation_3d(const direction_3d& that) : val_(that.to_int() >> 1) {} - orientation_3d::orientation_3d(const direction_2d& that) : val_(that.to_int() >> 1) {} - - direction_3d orientation_3d::get_direction(direction_1d dir) const { - return direction_3d(direction_3d_enum((val_ << 1) + dir.to_int())); - } - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/point_concept.hpp b/contrib/restricted/boost/boost/polygon/point_concept.hpp deleted file mode 100644 index 4d4c1dd207..0000000000 --- a/contrib/restricted/boost/boost/polygon/point_concept.hpp +++ /dev/null @@ -1,469 +0,0 @@ -// Boost.Polygon library point_concept.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_POINT_CONCEPT_HPP -#define BOOST_POLYGON_POINT_CONCEPT_HPP - -#include "isotropy.hpp" -#include "point_traits.hpp" - -namespace boost { -namespace polygon { - -struct point_concept {}; - -template <typename ConceptType> -struct is_point_concept { - typedef gtl_no type; -}; - -template <> -struct is_point_concept<point_concept> { - typedef gtl_yes type; -}; - -template <typename ConceptType> -struct is_mutable_point_concept { - typedef gtl_no type; -}; - -template <> -struct is_mutable_point_concept<point_concept> { - typedef gtl_yes type; -}; - -template <typename GeometryType, typename BoolType> -struct point_coordinate_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct point_coordinate_type_by_concept<GeometryType, gtl_yes> { - typedef typename point_traits<GeometryType>::coordinate_type type; -}; - -template <typename GeometryType> -struct point_coordinate_type { - typedef typename point_coordinate_type_by_concept< - GeometryType, - typename is_point_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -template <typename GeometryType, typename BoolType> -struct point_difference_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct point_difference_type_by_concept<GeometryType, gtl_yes> { - typedef typename coordinate_traits< - typename point_traits<GeometryType>::coordinate_type - >::coordinate_difference type; -}; - -template <typename GeometryType> -struct point_difference_type { - typedef typename point_difference_type_by_concept< - GeometryType, - typename is_point_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -template <typename GeometryType, typename BoolType> -struct point_distance_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct point_distance_type_by_concept<GeometryType, gtl_yes> { - typedef typename coordinate_traits< - typename point_coordinate_type<GeometryType>::type - >::coordinate_distance type; -}; - -template <typename GeometryType> -struct point_distance_type { - typedef typename point_distance_type_by_concept< - GeometryType, - typename is_point_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -struct y_pt_get : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_pt_get, - typename is_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, - typename point_coordinate_type<PointType>::type ->::type get(const PointType& point, orientation_2d orient) { - return point_traits<PointType>::get(point, orient); -} - -struct y_pt_set : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_pt_set, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, - void ->::type set(PointType& point, orientation_2d orient, - typename point_mutable_traits<PointType>::coordinate_type value) { - point_mutable_traits<PointType>::set(point, orient, value); -} - -struct y_pt_construct : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_pt_construct, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -PointType>::type construct( - typename point_mutable_traits<PointType>::coordinate_type x, - typename point_mutable_traits<PointType>::coordinate_type y) { - return point_mutable_traits<PointType>::construct(x, y); -} - -struct y_pt_assign : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_assign, - typename is_mutable_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type ->::type, -PointType1>::type& assign(PointType1& lvalue, const PointType2& rvalue) { - set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); - set(lvalue, VERTICAL, get(rvalue, VERTICAL)); - return lvalue; -} - -struct y_p_x : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_p_x, - typename is_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, - typename point_coordinate_type<PointType>::type ->::type x(const PointType& point) { - return get(point, HORIZONTAL); -} - -struct y_p_y : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_p_y, - typename is_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, - typename point_coordinate_type<PointType>::type ->::type y(const PointType& point) { - return get(point, VERTICAL); -} - -struct y_p_sx : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_p_sx, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -void>::type x(PointType& point, - typename point_mutable_traits<PointType>::coordinate_type value) { - set(point, HORIZONTAL, value); -} - -struct y_p_sy : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_p_sy, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -void>::type y(PointType& point, - typename point_mutable_traits<PointType>::coordinate_type value) { - set(point, VERTICAL, value); -} - -struct y_pt_equiv : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_equiv, - typename is_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -bool>::type equivalence( - const PointType1& point1, const PointType2& point2) { - return (x(point1) == x(point2)) && (y(point1) == y(point2)); -} - -struct y_pt_man_dist : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_man_dist, - typename is_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -typename point_difference_type<PointType1>::type>::type -manhattan_distance(const PointType1& point1, const PointType2& point2) { - return euclidean_distance(point1, point2, HORIZONTAL) + - euclidean_distance(point1, point2, VERTICAL); -} - -struct y_pt_ed1 : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_ed1, - typename is_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -typename point_difference_type<PointType1>::type>::type -euclidean_distance( - const PointType1& point1, - const PointType2& point2, - orientation_2d orient) { - typename point_difference_type<PointType1>::type dif = - get(point1, orient) - get(point2, orient); - return (dif < 0) ? -dif : dif; -} - -struct y_pt_eds : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_eds, - typename is_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -typename point_difference_type<PointType1>::type>::type -distance_squared(const PointType1& point1, const PointType2& point2) { - typename point_difference_type<PointType1>::type dx = - euclidean_distance(point1, point2, HORIZONTAL); - typename point_difference_type<PointType1>::type dy = - euclidean_distance(point1, point2, VERTICAL); - dx *= dx; - dy *= dy; - return dx + dy; -} - -struct y_pt_ed2 : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_ed2, - typename is_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -typename point_distance_type<PointType1>::type>::type -euclidean_distance(const PointType1& point1, const PointType2& point2) { - return (std::sqrt)( - static_cast<double>(distance_squared(point1, point2))); -} - -struct y_pt_convolve : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_convolve, - typename is_mutable_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -PointType1>::type& convolve(PointType1& lvalue, const PointType2& rvalue) { - x(lvalue, x(lvalue) + x(rvalue)); - y(lvalue, y(lvalue) + y(rvalue)); - return lvalue; -} - -struct y_pt_deconvolve : gtl_yes {}; - -template <typename PointType1, typename PointType2> -typename enable_if< - typename gtl_and_3< - y_pt_deconvolve, - typename is_mutable_point_concept< - typename geometry_concept<PointType1>::type - >::type, - typename is_point_concept< - typename geometry_concept<PointType2>::type - >::type - >::type, -PointType1>::type& deconvolve(PointType1& lvalue, const PointType2& rvalue) { - x(lvalue, x(lvalue) - x(rvalue)); - y(lvalue, y(lvalue) - y(rvalue)); - return lvalue; -} - -struct y_pt_scale_up : gtl_yes {}; - -template <typename PointType, typename CType> -typename enable_if< - typename gtl_and< - y_pt_scale_up, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -PointType>::type& scale_up(PointType& point, CType factor) { - typedef typename point_coordinate_type<PointType>::type Unit; - x(point, x(point) * (Unit)factor); - y(point, y(point) * (Unit)factor); - return point; -} - -struct y_pt_scale_down : gtl_yes {}; - -template <typename PointType, typename CType> -typename enable_if< - typename gtl_and< - y_pt_scale_down, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -PointType>::type& scale_down(PointType& point, CType factor) { - typedef typename point_coordinate_type<PointType>::type Unit; - typedef typename coordinate_traits<Unit>::coordinate_distance dt; - x(point, scaling_policy<Unit>::round((dt)(x(point)) / (dt)factor)); - y(point, scaling_policy<Unit>::round((dt)(y(point)) / (dt)factor)); - return point; -} - -struct y_pt_scale : gtl_yes {}; - -template <typename PointType, typename ScaleType> -typename enable_if< - typename gtl_and< - y_pt_scale, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -PointType>::type& scale(PointType& point, const ScaleType& scaling) { - typedef typename point_coordinate_type<PointType>::type Unit; - Unit x_coord(x(point)); - Unit y_coord(y(point)); - scaling.scale(x_coord, y_coord); - x(point, x_coord); - y(point, y_coord); - return point; -} - -struct y_pt_transform : gtl_yes {}; - -template <typename PointType, typename TransformType> -typename enable_if< - typename gtl_and< - y_pt_transform, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -PointType>::type& transform(PointType& point, const TransformType& transform) { - typedef typename point_coordinate_type<PointType>::type Unit; - Unit x_coord(x(point)); - Unit y_coord(y(point)); - transform.transform(x_coord, y_coord); - x(point, x_coord); - y(point, y_coord); - return point; -} - -struct y_pt_move : gtl_yes {}; - -template <typename PointType> -typename enable_if< - typename gtl_and< - y_pt_move, - typename is_mutable_point_concept< - typename geometry_concept<PointType>::type - >::type - >::type, -PointType>::type& move(PointType& point, orientation_2d orient, - typename point_coordinate_type<PointType>::type displacement) { - typedef typename point_coordinate_type<PointType>::type Unit; - Unit coord = get(point, orient); - set(point, orient, coord + displacement); - return point; -} -} // polygon -} // boost - -#endif // BOOST_POLYGON_POINT_CONCEPT_HPP diff --git a/contrib/restricted/boost/boost/polygon/point_data.hpp b/contrib/restricted/boost/boost/polygon/point_data.hpp deleted file mode 100644 index deda14d5d4..0000000000 --- a/contrib/restricted/boost/boost/polygon/point_data.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// Boost.Polygon library point_data.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_POINT_DATA_HPP -#define BOOST_POLYGON_POINT_DATA_HPP - -#include "isotropy.hpp" -#include "point_concept.hpp" - -namespace boost { -namespace polygon { - -template <typename T> -class point_data { - public: - typedef T coordinate_type; - - point_data() -#ifndef BOOST_POLYGON_MSVC - : coords_() -#endif - {} - - point_data(coordinate_type x, coordinate_type y) { - coords_[HORIZONTAL] = x; - coords_[VERTICAL] = y; - } - - explicit point_data(const point_data& that) { - coords_[0] = that.coords_[0]; - coords_[1] = that.coords_[1]; - } - - point_data& operator=(const point_data& that) { - coords_[0] = that.coords_[0]; - coords_[1] = that.coords_[1]; - return *this; - } - -#if defined(__GNUC__) && __GNUC__ < 6 - // "explicit" to work around a bug in GCC < 6: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63356 - template <typename PointType> - explicit point_data(const PointType& that) { - *this = that; - } -#else // __GNUC__ < 6 - template <typename PointType> - point_data(const PointType& that) { - *this = that; - } -#endif // __GNUC__ < 6 - - template <typename PointType> - point_data& operator=(const PointType& that) { - assign(*this, that); - return *this; - } - - // TODO(asydorchuk): Deprecated. - template <typename CT> - point_data(const point_data<CT>& that) { - coords_[HORIZONTAL] = (coordinate_type)that.x(); - coords_[VERTICAL] = (coordinate_type)that.y(); - } - - coordinate_type get(orientation_2d orient) const { - return coords_[orient.to_int()]; - } - - void set(orientation_2d orient, coordinate_type value) { - coords_[orient.to_int()] = value; - } - - coordinate_type x() const { - return coords_[HORIZONTAL]; - } - - point_data& x(coordinate_type value) { - coords_[HORIZONTAL] = value; - return *this; - } - - coordinate_type y() const { - return coords_[VERTICAL]; - } - - point_data& y(coordinate_type value) { - coords_[VERTICAL] = value; - return *this; - } - - bool operator==(const point_data& that) const { - return (coords_[0] == that.coords_[0]) && - (coords_[1] == that.coords_[1]); - } - - bool operator!=(const point_data& that) const { - return !(*this == that); - } - - bool operator<(const point_data& that) const { - return (coords_[0] < that.coords_[0]) || - ((coords_[0] == that.coords_[0]) && - (coords_[1] < that.coords_[1])); - } - - bool operator<=(const point_data& that) const { - return !(that < *this); - } - - bool operator>(const point_data& that) const { - return that < *this; - } - - bool operator>=(const point_data& that) const { - return !(*this < that); - } - - private: - coordinate_type coords_[2]; -}; - -template <typename CType> -struct geometry_concept< point_data<CType> > { - typedef point_concept type; -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_POINT_DATA_HPP diff --git a/contrib/restricted/boost/boost/polygon/point_traits.hpp b/contrib/restricted/boost/boost/polygon/point_traits.hpp deleted file mode 100644 index 5bc43d1514..0000000000 --- a/contrib/restricted/boost/boost/polygon/point_traits.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Boost.Polygon library point_traits.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_POINT_TRAITS_HPP -#define BOOST_POLYGON_POINT_TRAITS_HPP - -#include "isotropy.hpp" - -namespace boost { -namespace polygon { - -template <typename PointType> -struct point_traits { - typedef PointType point_type; - typedef typename point_type::coordinate_type coordinate_type; - - static coordinate_type get( - const point_type& point, orientation_2d orient) { - return point.get(orient); - } -}; - -template <typename PointType> -struct point_mutable_traits { - typedef PointType point_type; - typedef typename point_type::coordinate_type coordinate_type; - - static void set( - point_type& point, orientation_2d orient, coordinate_type value) { - point.set(orient, value); - } - - static point_type construct(coordinate_type x, coordinate_type y) { - return point_type(x, y); - } -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_POINT_TRAITS_HPP diff --git a/contrib/restricted/boost/boost/polygon/polygon.hpp b/contrib/restricted/boost/boost/polygon/polygon.hpp deleted file mode 100644 index 90a7c1f81a..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - 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_POLYGON_HPP -#define BOOST_POLYGON_POLYGON_HPP -#define BOOST_POLYGON_VERSION 014401 - -#include "isotropy.hpp" - -//point -#include "point_data.hpp" -#include "point_traits.hpp" -#include "point_concept.hpp" - -#include "transform.hpp" - -//interval -#include "interval_data.hpp" -#include "interval_traits.hpp" -#include "interval_concept.hpp" - -//rectangle -#include "rectangle_data.hpp" -#include "rectangle_traits.hpp" -#include "rectangle_concept.hpp" - -//segment -#include "segment_data.hpp" -#include "segment_traits.hpp" -#include "segment_concept.hpp" - -//algorithms needed by polygon types -#include "detail/iterator_points_to_compact.hpp" -#include "detail/iterator_compact_to_points.hpp" - -//polygons -#include "polygon_45_data.hpp" -#include "polygon_data.hpp" -#include "polygon_90_data.hpp" -#include "polygon_90_with_holes_data.hpp" -#include "polygon_45_with_holes_data.hpp" -#include "polygon_with_holes_data.hpp" -#include "polygon_traits.hpp" - -//manhattan boolean algorithms -#include "detail/boolean_op.hpp" -#include "detail/polygon_formation.hpp" -#include "detail/rectangle_formation.hpp" -#include "detail/max_cover.hpp" -#include "detail/property_merge.hpp" -#include "detail/polygon_90_touch.hpp" -#include "detail/iterator_geometry_to_set.hpp" - -//45 boolean op algorithms -#include "detail/boolean_op_45.hpp" -#include "detail/polygon_45_formation.hpp" - -//polygon set data types -#include "polygon_90_set_data.hpp" -//polygon set trait types -#include "polygon_90_set_traits.hpp" -//polygon set concepts -#include "polygon_90_set_concept.hpp" -//boolean operator syntax -#include "detail/polygon_90_set_view.hpp" - -//45 boolean op algorithms -#include "detail/polygon_45_touch.hpp" -#include "detail/property_merge_45.hpp" -#include "polygon_45_set_data.hpp" -#include "polygon_45_set_traits.hpp" -#include "polygon_45_set_concept.hpp" -#include "detail/polygon_45_set_view.hpp" - -//arbitrary polygon algorithms -#include "detail/polygon_arbitrary_formation.hpp" -#include "polygon_set_data.hpp" - -//general scanline -#include "detail/scan_arbitrary.hpp" -#include "polygon_set_traits.hpp" -#include "detail/polygon_set_view.hpp" - -#include "polygon_set_concept.hpp" - -#include "segment_utils.hpp" - -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_45_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_45_data.hpp deleted file mode 100644 index cdd5c2498b..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_45_data.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - 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_POLYGON_45_DATA_HPP -#define BOOST_POLYGON_POLYGON_45_DATA_HPP -#include "isotropy.hpp" -namespace boost { namespace polygon{ -struct polygon_45_concept; -template <typename T> class polygon_data; -template <typename T> -class polygon_45_data { -public: - typedef polygon_45_concept geometry_type; - typedef T coordinate_type; - typedef typename std::vector<point_data<coordinate_type> >::const_iterator iterator_type; - typedef typename coordinate_traits<T>::coordinate_distance area_type; - typedef point_data<T> point_type; - - inline polygon_45_data() : coords_() {} //do nothing default constructor - - template<class iT> - inline polygon_45_data(iT input_begin, iT input_end) : coords_(input_begin, input_end) {} - - template<class iT> - inline polygon_45_data& set(iT input_begin, iT input_end) { - coords_.clear(); //just in case there was some old data there - coords_.insert(coords_.end(), input_begin, input_end); - return *this; - } - - // copy constructor (since we have dynamic memory) - inline polygon_45_data(const polygon_45_data& that) : coords_(that.coords_) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline polygon_45_data& operator=(const polygon_45_data& that) { - coords_ = that.coords_; - return *this; - } - - template <typename T2> - inline polygon_45_data& operator=(const T2& rvalue); - - inline bool operator==(const polygon_45_data& that) const { - if(coords_.size() != that.coords_.size()) return false; - for(std::size_t i = 0; i < coords_.size(); ++i) { - if(coords_[i] != that.coords_[i]) return false; - } - return true; - } - - inline bool operator!=(const polygon_45_data& that) const { return !((*this) == that); } - - // get begin iterator, returns a pointer to a const Unit - inline iterator_type begin() const { return coords_.begin(); } - - // get end iterator, returns a pointer to a const Unit - inline iterator_type end() const { return coords_.end(); } - - inline std::size_t size() const { return coords_.size(); } - -public: - std::vector<point_data<coordinate_type> > coords_; -}; - - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_45_set_concept.hpp b/contrib/restricted/boost/boost/polygon/polygon_45_set_concept.hpp deleted file mode 100644 index 623415fb59..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_45_set_concept.hpp +++ /dev/null @@ -1,441 +0,0 @@ -/* - 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_POLYGON_45_SET_CONCEPT_HPP -#define BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP -#include "polygon_45_set_data.hpp" -#include "polygon_45_set_traits.hpp" -#include "detail/polygon_45_touch.hpp" -namespace boost { namespace polygon{ - - template <typename T, typename T2> - struct is_either_polygon_45_set_type { - typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_45_set_type<T2>::type >::type type; - }; - - template <typename T> - struct is_polygon_45_or_90_set_type { - typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_90_set_type<T>::type >::type type; - }; - - template <typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type, - typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type - begin_45_set_data(const polygon_set_type& polygon_set) { - return polygon_45_set_traits<polygon_set_type>::begin(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type, - typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type - end_45_set_data(const polygon_set_type& polygon_set) { - return polygon_45_set_traits<polygon_set_type>::end(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type, - bool>::type - clean(const polygon_set_type& polygon_set) { - return polygon_45_set_traits<polygon_set_type>::clean(polygon_set); - } - - //assign - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type, - typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type>::type, - polygon_set_type_1>::type & - assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { - polygon_45_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_45_set_data(rvalue), end_45_set_data(rvalue)); - return lvalue; - } - - //get trapezoids - template <typename output_container_type, typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type, - void>::type - get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) { - clean(polygon_set); - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.get_trapezoids(output); - } - - //get trapezoids - template <typename output_container_type, typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type, - void>::type - get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) { - clean(polygon_set); - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.get_trapezoids(output, slicing_orientation); - } - - //equivalence - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3<typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_1>::type>::type, - typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type, - typename gtl_if<typename is_either_polygon_45_set_type<polygon_set_type_1, - polygon_set_type_2>::type>::type>::type, - bool>::type - equivalence(const polygon_set_type_1& lvalue, - const polygon_set_type_2& rvalue) { - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type> ps1; - assign(ps1, lvalue); - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_2>::coordinate_type> ps2; - assign(ps2, rvalue); - return ps1 == ps2; - } - - //clear - template <typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type, - void>::type - clear(polygon_set_type& polygon_set) { - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps; - assign(polygon_set, ps); - } - - //empty - template <typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type, - bool>::type - empty(const polygon_set_type& polygon_set) { - if(clean(polygon_set)) return begin_45_set_data(polygon_set) == end_45_set_data(polygon_set); - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.clean(); - return ps.empty(); - } - - //extents - template <typename polygon_set_type, typename rectangle_type> - typename enable_if< - typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - bool>::type - extents(rectangle_type& extents_rectangle, - const polygon_set_type& polygon_set) { - clean(polygon_set); - polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - return ps.extents(extents_rectangle); - } - - //area - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type>::type - area(const polygon_set_type& polygon_set) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - typedef polygon_45_with_holes_data<Unit> p_type; - typedef typename coordinate_traits<Unit>::area_type area_type; - std::vector<p_type> polys; - assign(polys, polygon_set); - area_type retval = (area_type)0; - for(std::size_t i = 0; i < polys.size(); ++i) { - retval += area(polys[i]); - } - return retval; - } - - //interact - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if < - typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type, - typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type >::type, - polygon_set_type_1>::type& - interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { - typedef typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type Unit; - std::vector<polygon_45_data<Unit> > polys; - assign(polys, polygon_set_1); - std::vector<std::set<int> > graph(polys.size()+1, std::set<int>()); - connectivity_extraction_45<Unit> ce; - ce.insert(polygon_set_2); - for(std::size_t i = 0; i < polys.size(); ++i){ - ce.insert(polys[i]); - } - ce.extract(graph); - clear(polygon_set_1); - polygon_45_set_data<Unit> ps; - for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){ - ps.insert(polys[(*itr)-1]); - } - assign(polygon_set_1, ps); - return polygon_set_1; - } - -// //self_intersect -// template <typename polygon_set_type> -// typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type, -// polygon_set_type>::type & -// self_intersect(polygon_set_type& polygon_set) { -// typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; -// //TODO -// } - - template <typename polygon_set_type, typename coord_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - resize(polygon_set_type& polygon_set, coord_type resizing, - RoundingOption rounding = CLOSEST, CornerOption corner = INTERSECTION) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.resize(resizing, rounding, corner); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - return resize(polygon_set, static_cast<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>(bloating)); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { - return resize(polygon_set, -(typename polygon_45_set_traits<polygon_set_type>::coordinate_type)shrinking); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - grow_and(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - std::vector<polygon_45_data<Unit> > polys; - assign(polys, polygon_set); - clear(polygon_set); - polygon_45_set_data<Unit> ps; - for(std::size_t i = 0; i < polys.size(); ++i) { - polygon_45_set_data<Unit> tmpPs; - tmpPs.insert(polys[i]); - bloat(tmpPs, bloating); - tmpPs.clean(); //apply implicit OR on tmp polygon set - ps.insert(tmpPs); - } - ps.self_intersect(); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale_up(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale_up(factor); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale_down(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale_down(factor); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale(polygon_set_type& polygon_set, double factor) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale(factor); - assign(polygon_set, ps); - return polygon_set; - } - - //self_intersect - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - self_intersect(polygon_set_type& polygon_set) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.self_intersect(); - assign(polygon_set, ps); - return polygon_set; - } - - //self_xor - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - self_xor(polygon_set_type& polygon_set) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.self_xor(); - assign(polygon_set, ps); - return polygon_set; - } - - //transform - template <typename polygon_set_type, typename transformation_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - transform(polygon_set_type& polygon_set, - const transformation_type& transformation) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_45_set_data<Unit> ps; - assign(ps, polygon_set); - ps.transform(transformation); - assign(polygon_set, ps); - return polygon_set; - } - - //keep - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type, - polygon_set_type>::type & - keep(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type min_area, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type max_area, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height, - typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) { - typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit; - typedef typename coordinate_traits<Unit>::unsigned_area_type uat; - std::list<polygon_45_data<Unit> > polys; - assign(polys, polygon_set); - typename std::list<polygon_45_data<Unit> >::iterator itr_nxt; - for(typename std::list<polygon_45_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ - itr_nxt = itr; - ++itr_nxt; - rectangle_data<Unit> bbox; - extents(bbox, *itr); - uat pwidth = delta(bbox, HORIZONTAL); - if(pwidth > min_width && pwidth <= max_width){ - uat pheight = delta(bbox, VERTICAL); - if(pheight > min_height && pheight <= max_height){ - typename coordinate_traits<Unit>::area_type parea = area(*itr); - if(parea <= max_area && parea >= min_area) { - continue; - } - } - } - polys.erase(itr); - } - assign(polygon_set, polys); - return polygon_set; - } - - template <typename T> - struct view_of<polygon_90_set_concept, T> { - typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; - T* tp; - std::vector<polygon_90_with_holes_data<coordinate_type> > polys; - view_of(T& obj) : tp(&obj), polys() { - std::vector<polygon_with_holes_data<coordinate_type> > gpolys; - assign(gpolys, obj); - for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); - itr != gpolys.end(); ++itr) { - polys.push_back(polygon_90_with_holes_data<coordinate_type>()); - assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr)); - } - } - view_of(const T& obj) : tp(), polys() { - std::vector<polygon_with_holes_data<coordinate_type> > gpolys; - assign(gpolys, obj); - for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); - itr != gpolys.end(); ++itr) { - polys.push_back(polygon_90_with_holes_data<coordinate_type>()); - assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr)); - } - } - - typedef typename std::vector<polygon_90_with_holes_data<coordinate_type> >::const_iterator iterator_type; - typedef view_of operator_arg_type; - - inline iterator_type begin() const { - return polys.begin(); - } - - inline iterator_type end() const { - return polys.end(); - } - - inline orientation_2d orient() const { return HORIZONTAL; } - - inline bool clean() const { return false; } - - inline bool sorted() const { return false; } - - inline T& get() { return *tp; } - - }; - - template <typename T> - struct polygon_90_set_traits<view_of<polygon_90_set_concept, T> > { - typedef typename view_of<polygon_90_set_concept, T>::coordinate_type coordinate_type; - typedef typename view_of<polygon_90_set_concept, T>::iterator_type iterator_type; - typedef view_of<polygon_90_set_concept, T> operator_arg_type; - - static inline iterator_type begin(const view_of<polygon_90_set_concept, T>& polygon_set) { - return polygon_set.begin(); - } - - static inline iterator_type end(const view_of<polygon_90_set_concept, T>& polygon_set) { - return polygon_set.end(); - } - - static inline orientation_2d orient(const view_of<polygon_90_set_concept, T>& polygon_set) { - return polygon_set.orient(); } - - static inline bool clean(const view_of<polygon_90_set_concept, T>& polygon_set) { - return polygon_set.clean(); } - - static inline bool sorted(const view_of<polygon_90_set_concept, T>& polygon_set) { - return polygon_set.sorted(); } - - }; - - template <typename T> - struct geometry_concept<view_of<polygon_90_set_concept, T> > { - typedef polygon_90_set_concept type; - }; - - template <typename T> - struct get_coordinate_type<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> { - typedef typename view_of<polygon_90_set_concept, T>::coordinate_type type; - }; - template <typename T> - struct get_iterator_type_2<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> { - typedef typename view_of<polygon_90_set_concept, T>::iterator_type type; - static type begin(const view_of<polygon_90_set_concept, T>& t) { return t.begin(); } - static type end(const view_of<polygon_90_set_concept, T>& t) { return t.end(); } - }; - -} -} -#include "detail/polygon_45_set_view.hpp" -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_45_set_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_45_set_data.hpp deleted file mode 100644 index 97585f6dad..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_45_set_data.hpp +++ /dev/null @@ -1,1880 +0,0 @@ -/* - 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_POLYGON_45_SET_DATA_HPP -#define BOOST_POLYGON_POLYGON_45_SET_DATA_HPP -#include "polygon_90_set_data.hpp" -#include "detail/boolean_op_45.hpp" -#include "detail/polygon_45_formation.hpp" -#include "detail/polygon_45_touch.hpp" -#include "detail/property_merge_45.hpp" -namespace boost { namespace polygon{ - - enum RoundingOption { CLOSEST = 0, OVERSIZE = 1, UNDERSIZE = 2, SQRT2 = 3, SQRT1OVER2 = 4 }; - enum CornerOption { INTERSECTION = 0, ORTHOGONAL = 1, UNFILLED = 2 }; - - template <typename ltype, typename rtype, int op_type> - class polygon_45_set_view; - - struct polygon_45_set_concept {}; - - template <typename Unit> - class polygon_45_set_data { - public: - typedef typename polygon_45_formation<Unit>::Vertex45Compact Vertex45Compact; - typedef std::vector<Vertex45Compact> Polygon45VertexData; - - typedef Unit coordinate_type; - typedef Polygon45VertexData value_type; - typedef typename value_type::const_iterator iterator_type; - typedef polygon_45_set_data operator_arg_type; - - // default constructor - inline polygon_45_set_data() : error_data_(), data_(), dirty_(false), unsorted_(false), is_manhattan_(true) {} - - // constructor from a geometry object - template <typename geometry_type> - inline polygon_45_set_data(const geometry_type& that) : error_data_(), data_(), dirty_(false), unsorted_(false), is_manhattan_(true) { - insert(that); - } - - // copy constructor - inline polygon_45_set_data(const polygon_45_set_data& that) : - error_data_(that.error_data_), data_(that.data_), dirty_(that.dirty_), - unsorted_(that.unsorted_), is_manhattan_(that.is_manhattan_) {} - - template <typename ltype, typename rtype, int op_type> - inline polygon_45_set_data(const polygon_45_set_view<ltype, rtype, op_type>& that) : - error_data_(), data_(), dirty_(false), unsorted_(false), is_manhattan_(true) { - (*this) = that.value(); - } - - // destructor - inline ~polygon_45_set_data() {} - - // assignement operator - inline polygon_45_set_data& operator=(const polygon_45_set_data& that) { - if(this == &that) return *this; - error_data_ = that.error_data_; - data_ = that.data_; - dirty_ = that.dirty_; - unsorted_ = that.unsorted_; - is_manhattan_ = that.is_manhattan_; - return *this; - } - - template <typename ltype, typename rtype, int op_type> - inline polygon_45_set_data& operator=(const polygon_45_set_view<ltype, rtype, op_type>& that) { - (*this) = that.value(); - return *this; - } - - template <typename geometry_object> - inline polygon_45_set_data& operator=(const geometry_object& geometry) { - data_.clear(); - insert(geometry); - return *this; - } - - // insert iterator range - inline void insert(iterator_type input_begin, iterator_type input_end, bool is_hole = false) { - if(input_begin == input_end || (!data_.empty() && &(*input_begin) == &(*(data_.begin())))) return; - dirty_ = true; - unsorted_ = true; - while(input_begin != input_end) { - insert(*input_begin, is_hole); - ++input_begin; - } - } - - // insert iterator range - template <typename iT> - inline void insert(iT input_begin, iT input_end, bool is_hole = false) { - if(input_begin == input_end) return; - dirty_ = true; - unsorted_ = true; - while(input_begin != input_end) { - insert(*input_begin, is_hole); - ++input_begin; - } - } - - inline void insert(const polygon_45_set_data& polygon_set, bool is_hole = false); - template <typename coord_type> - inline void insert(const polygon_45_set_data<coord_type>& polygon_set, bool is_hole = false); - - template <typename geometry_type> - inline void insert(const geometry_type& geometry_object, bool is_hole = false) { - insert_dispatch(geometry_object, is_hole, typename geometry_concept<geometry_type>::type()); - } - - inline void insert_clean(const Vertex45Compact& vertex_45, bool is_hole = false) { - if(vertex_45.count.is_45()) is_manhattan_ = false; - data_.push_back(vertex_45); - if(is_hole) data_.back().count.invert(); - } - - inline void insert(const Vertex45Compact& vertex_45, bool is_hole = false) { - dirty_ = true; - unsorted_ = true; - insert_clean(vertex_45, is_hole); - } - - template <typename coordinate_type_2> - inline void insert(const polygon_90_set_data<coordinate_type_2>& polygon_set, bool is_hole = false) { - if(polygon_set.orient() == VERTICAL) { - for(typename polygon_90_set_data<coordinate_type_2>::iterator_type itr = polygon_set.begin(); - itr != polygon_set.end(); ++itr) { - Vertex45Compact vertex_45(point_data<Unit>((*itr).first, (*itr).second.first), 2, (*itr).second.second); - vertex_45.count[1] = (*itr).second.second; - if(is_hole) vertex_45.count[1] *= - 1; - insert_clean(vertex_45, is_hole); - } - } else { - for(typename polygon_90_set_data<coordinate_type_2>::iterator_type itr = polygon_set.begin(); - itr != polygon_set.end(); ++itr) { - Vertex45Compact vertex_45(point_data<Unit>((*itr).second.first, (*itr).first), 2, (*itr).second.second); - vertex_45.count[1] = (*itr).second.second; - if(is_hole) vertex_45.count[1] *= - 1; - insert_clean(vertex_45, is_hole); - } - } - dirty_ = true; - unsorted_ = true; - } - - template <typename output_container> - inline void get(output_container& output) const { - get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type()); - } - - inline bool has_error_data() const { return !error_data_.empty(); } - inline std::size_t error_count() const { return error_data_.size() / 4; } - inline void get_error_data(polygon_45_set_data& p) const { - p.data_.insert(p.data_.end(), error_data_.begin(), error_data_.end()); - } - - // equivalence operator - inline bool operator==(const polygon_45_set_data& p) const { - clean(); - p.clean(); - return data_ == p.data_; - } - - // inequivalence operator - inline bool operator!=(const polygon_45_set_data& p) const { - return !((*this) == p); - } - - // get iterator to begin vertex data - inline iterator_type begin() const { - return data_.begin(); - } - - // get iterator to end vertex data - inline iterator_type end() const { - return data_.end(); - } - - const value_type& value() const { - return data_; - } - - // clear the contents of the polygon_45_set_data - inline void clear() { data_.clear(); error_data_.clear(); dirty_ = unsorted_ = false; is_manhattan_ = true; } - - // find out if Polygon set is empty - inline bool empty() const { return data_.empty(); } - - // get the Polygon set size in vertices - inline std::size_t size() const { clean(); return data_.size(); } - - // get the current Polygon set capacity in vertices - inline std::size_t capacity() const { return data_.capacity(); } - - // reserve size of polygon set in vertices - inline void reserve(std::size_t size) { return data_.reserve(size); } - - // find out if Polygon set is sorted - inline bool sorted() const { return !unsorted_; } - - // find out if Polygon set is clean - inline bool dirty() const { return dirty_; } - - // find out if Polygon set is clean - inline bool is_manhattan() const { return is_manhattan_; } - - bool clean() const; - - void sort() const{ - if(unsorted_) { - polygon_sort(data_.begin(), data_.end()); - unsorted_ = false; - } - } - - template <typename input_iterator_type> - void set(input_iterator_type input_begin, input_iterator_type input_end) { - data_.clear(); - reserve(std::distance(input_begin, input_end)); - insert(input_begin, input_end); - dirty_ = true; - unsorted_ = true; - } - - void set_clean(const value_type& value) { - data_ = value; - dirty_ = false; - unsorted_ = false; - } - - void set(const value_type& value) { - data_ = value; - dirty_ = true; - unsorted_ = true; - } - - // append to the container cT with polygons (holes will be fractured vertically) - template <class cT> - void get_polygons(cT& container) const { - get_dispatch(container, polygon_45_concept()); - } - - // append to the container cT with PolygonWithHoles objects - template <class cT> - void get_polygons_with_holes(cT& container) const { - get_dispatch(container, polygon_45_with_holes_concept()); - } - - // append to the container cT with polygons of three or four verticies - // slicing orientation is vertical - template <class cT> - void get_trapezoids(cT& container) const { - clean(); - typename polygon_45_formation<Unit>::Polygon45Tiling pf; - //std::cout << "FORMING POLYGONS\n"; - pf.scan(container, data_.begin(), data_.end()); - //std::cout << "DONE FORMING POLYGONS\n"; - } - - // append to the container cT with polygons of three or four verticies - template <class cT> - void get_trapezoids(cT& container, orientation_2d slicing_orientation) const { - if(slicing_orientation == VERTICAL) { - get_trapezoids(container); - } else { - polygon_45_set_data<Unit> ps(*this); - ps.transform(axis_transformation(axis_transformation::SWAP_XY)); - cT result; - ps.get_trapezoids(result); - for(typename cT::iterator itr = result.begin(); itr != result.end(); ++itr) { - ::boost::polygon::transform(*itr, axis_transformation(axis_transformation::SWAP_XY)); - } - container.insert(container.end(), result.begin(), result.end()); - } - } - - // insert vertex sequence - template <class iT> - void insert_vertex_sequence(iT begin_vertex, iT end_vertex, - direction_1d winding, bool is_hole = false); - - // get the external boundary rectangle - template <typename rectangle_type> - bool extents(rectangle_type& rect) const; - - // snap verticies of set to even,even or odd,odd coordinates - void snap() const; - - // |= &= += *= -= ^= binary operators - polygon_45_set_data& operator|=(const polygon_45_set_data& b); - polygon_45_set_data& operator&=(const polygon_45_set_data& b); - polygon_45_set_data& operator+=(const polygon_45_set_data& b); - polygon_45_set_data& operator*=(const polygon_45_set_data& b); - polygon_45_set_data& operator-=(const polygon_45_set_data& b); - polygon_45_set_data& operator^=(const polygon_45_set_data& b); - - // resizing operations - polygon_45_set_data& operator+=(Unit delta); - polygon_45_set_data& operator-=(Unit delta); - - // shrink the Polygon45Set by shrinking - polygon_45_set_data& resize(coordinate_type resizing, RoundingOption rounding = CLOSEST, - CornerOption corner = INTERSECTION); - - // transform set - template <typename transformation_type> - polygon_45_set_data& transform(const transformation_type& tr); - - // scale set - polygon_45_set_data& scale_up(typename coordinate_traits<Unit>::unsigned_area_type factor); - polygon_45_set_data& scale_down(typename coordinate_traits<Unit>::unsigned_area_type factor); - polygon_45_set_data& scale(double scaling); - - // self_intersect - polygon_45_set_data& self_intersect() { - sort(); - applyAdaptiveUnary_<1>(); //1 = AND - dirty_ = false; - return *this; - } - - // self_xor - polygon_45_set_data& self_xor() { - sort(); - applyAdaptiveUnary_<3>(); //3 = XOR - dirty_ = false; - return *this; - } - - // accumulate the bloated polygon - template <typename geometry_type> - polygon_45_set_data& insert_with_resize(const geometry_type& poly, - coordinate_type resizing, RoundingOption rounding = CLOSEST, - CornerOption corner = INTERSECTION, - bool hole = false) { - return insert_with_resize_dispatch(poly, resizing, rounding, corner, hole, typename geometry_concept<geometry_type>::type()); - } - - private: - mutable value_type error_data_; - mutable value_type data_; - mutable bool dirty_; - mutable bool unsorted_; - mutable bool is_manhattan_; - - private: - //functions - template <typename output_container> - void get_dispatch(output_container& output, polygon_45_concept tag) const { - get_fracture(output, true, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_45_with_holes_concept tag) const { - get_fracture(output, false, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_concept tag) const { - get_fracture(output, true, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_with_holes_concept tag) const { - get_fracture(output, false, tag); - } - template <typename output_container, typename concept_type> - void get_fracture(output_container& container, bool fracture_holes, concept_type ) const { - clean(); - typename polygon_45_formation<Unit>::Polygon45Formation pf(fracture_holes); - //std::cout << "FORMING POLYGONS\n"; - pf.scan(container, data_.begin(), data_.end()); - } - - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, undefined_concept) { - insert(geometry_object.begin(), geometry_object.end(), is_hole); - } - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, rectangle_concept tag); - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, polygon_90_concept ) { - insert_vertex_sequence(begin_points(geometry_object), end_points(geometry_object), winding(geometry_object), is_hole); - } - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, polygon_90_with_holes_concept ) { - insert_vertex_sequence(begin_points(geometry_object), end_points(geometry_object), winding(geometry_object), is_hole); - for(typename polygon_with_holes_traits<geometry_type>::iterator_holes_type itr = - begin_holes(geometry_object); itr != end_holes(geometry_object); - ++itr) { - insert_vertex_sequence(begin_points(*itr), end_points(*itr), winding(*itr), !is_hole); - } - } - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, polygon_45_concept ) { - insert_vertex_sequence(begin_points(geometry_object), end_points(geometry_object), winding(geometry_object), is_hole); - } - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, polygon_45_with_holes_concept ) { - insert_vertex_sequence(begin_points(geometry_object), end_points(geometry_object), winding(geometry_object), is_hole); - for(typename polygon_with_holes_traits<geometry_type>::iterator_holes_type itr = - begin_holes(geometry_object); itr != end_holes(geometry_object); - ++itr) { - insert_vertex_sequence(begin_points(*itr), end_points(*itr), winding(*itr), !is_hole); - } - } - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, polygon_45_set_concept ) { - polygon_45_set_data ps; - assign(ps, geometry_object); - insert(ps, is_hole); - } - template <typename geometry_type> - void insert_dispatch(const geometry_type& geometry_object, bool is_hole, polygon_90_set_concept ) { - std::list<polygon_90_data<coordinate_type> > pl; - assign(pl, geometry_object); - insert(pl.begin(), pl.end(), is_hole); - } - - void insert_vertex_half_edge_45_pair(const point_data<Unit>& pt1, point_data<Unit>& pt2, - const point_data<Unit>& pt3, direction_1d wdir); - - template <typename geometry_type> - polygon_45_set_data& insert_with_resize_dispatch(const geometry_type& poly, - coordinate_type resizing, RoundingOption rounding, - CornerOption corner, bool hole, polygon_45_concept tag); - - // accumulate the bloated polygon with holes - template <typename geometry_type> - polygon_45_set_data& insert_with_resize_dispatch(const geometry_type& poly, - coordinate_type resizing, RoundingOption rounding, - CornerOption corner, bool hole, polygon_45_with_holes_concept tag); - - static void snap_vertex_45(Vertex45Compact& vertex); - - public: - template <int op> - void applyAdaptiveBoolean_(const polygon_45_set_data& rvalue) const; - template <int op> - void applyAdaptiveBoolean_(polygon_45_set_data& result, const polygon_45_set_data& rvalue) const; - template <int op> - void applyAdaptiveUnary_() const; - }; - - template <typename T> - struct geometry_concept<polygon_45_set_data<T> > { - typedef polygon_45_set_concept type; - }; - - template <typename iT, typename T> - void scale_up_vertex_45_compact_range(iT beginr, iT endr, T factor) { - for( ; beginr != endr; ++beginr) { - scale_up((*beginr).pt, factor); - } - } - template <typename iT, typename T> - void scale_down_vertex_45_compact_range_blindly(iT beginr, iT endr, T factor) { - for( ; beginr != endr; ++beginr) { - scale_down((*beginr).pt, factor); - } - } - - template <typename Unit> - inline std::pair<int, int> characterizeEdge45(const point_data<Unit>& pt1, const point_data<Unit>& pt2) { - std::pair<int, int> retval(0, 1); - if(pt1.x() == pt2.x()) { - retval.first = 3; - retval.second = -1; - return retval; - } - //retval.second = pt1.x() < pt2.x() ? -1 : 1; - retval.second = 1; - if(pt1.y() == pt2.y()) { - retval.first = 1; - } else if(pt1.x() < pt2.x()) { - if(pt1.y() < pt2.y()) { - retval.first = 2; - } else { - retval.first = 0; - } - } else { - if(pt1.y() < pt2.y()) { - retval.first = 0; - } else { - retval.first = 2; - } - } - return retval; - } - - template <typename cT, typename pT> - bool insert_vertex_half_edge_45_pair_into_vector(cT& output, - const pT& pt1, pT& pt2, - const pT& pt3, - direction_1d wdir) { - int multiplier = wdir == LOW ? -1 : 1; - typename cT::value_type vertex(pt2, 0, 0); - //std::cout << pt1 << " " << pt2 << " " << pt3 << std::endl; - std::pair<int, int> check; - check = characterizeEdge45(pt1, pt2); - //std::cout << "index " << check.first << " " << check.second * -multiplier << std::endl; - vertex.count[check.first] += check.second * -multiplier; - check = characterizeEdge45(pt2, pt3); - //std::cout << "index " << check.first << " " << check.second * multiplier << std::endl; - vertex.count[check.first] += check.second * multiplier; - output.push_back(vertex); - return vertex.count.is_45(); - } - - template <typename Unit> - inline void polygon_45_set_data<Unit>::insert_vertex_half_edge_45_pair(const point_data<Unit>& pt1, point_data<Unit>& pt2, - const point_data<Unit>& pt3, - direction_1d wdir) { - if(insert_vertex_half_edge_45_pair_into_vector(data_, pt1, pt2, pt3, wdir)) is_manhattan_ = false; - } - - template <typename Unit> - template <class iT> - inline void polygon_45_set_data<Unit>::insert_vertex_sequence(iT begin_vertex, iT end_vertex, - direction_1d winding, bool is_hole) { - if(begin_vertex == end_vertex) return; - if(is_hole) winding = winding.backward(); - iT itr = begin_vertex; - if(itr == end_vertex) return; - point_data<Unit> firstPt = *itr; - ++itr; - point_data<Unit> secondPt(firstPt); - //skip any duplicate points - do { - if(itr == end_vertex) return; - secondPt = *itr; - ++itr; - } while(secondPt == firstPt); - point_data<Unit> prevPt = secondPt; - point_data<Unit> prevPrevPt = firstPt; - while(itr != end_vertex) { - point_data<Unit> pt = *itr; - //skip any duplicate points - if(pt == prevPt) { - ++itr; - continue; - } - //operate on the three points - insert_vertex_half_edge_45_pair(prevPrevPt, prevPt, pt, winding); - prevPrevPt = prevPt; - prevPt = pt; - ++itr; - } - if(prevPt != firstPt) { - insert_vertex_half_edge_45_pair(prevPrevPt, prevPt, firstPt, winding); - insert_vertex_half_edge_45_pair(prevPt, firstPt, secondPt, winding); - } else { - insert_vertex_half_edge_45_pair(prevPrevPt, firstPt, secondPt, winding); - } - dirty_ = true; - unsorted_ = true; - } - - // insert polygon set - template <typename Unit> - inline void polygon_45_set_data<Unit>::insert(const polygon_45_set_data<Unit>& polygon_set, bool is_hole) { - std::size_t count = data_.size(); - data_.insert(data_.end(), polygon_set.data_.begin(), polygon_set.data_.end()); - error_data_.insert(error_data_.end(), polygon_set.error_data_.begin(), - polygon_set.error_data_.end()); - if(is_hole) { - for(std::size_t i = count; i < data_.size(); ++i) { - data_[i].count = data_[i].count.invert(); - } - } - dirty_ = true; - unsorted_ = true; - if(polygon_set.is_manhattan_ == false) is_manhattan_ = false; - return; - } - // insert polygon set - template <typename Unit> - template <typename coord_type> - inline void polygon_45_set_data<Unit>::insert(const polygon_45_set_data<coord_type>& polygon_set, bool is_hole) { - std::size_t count = data_.size(); - for(typename polygon_45_set_data<coord_type>::iterator_type itr = polygon_set.begin(); - itr != polygon_set.end(); ++itr) { - const typename polygon_45_set_data<coord_type>::Vertex45Compact& v = *itr; - typename polygon_45_set_data<Unit>::Vertex45Compact v2; - v2.pt.x(static_cast<Unit>(v.pt.x())); - v2.pt.y(static_cast<Unit>(v.pt.y())); - v2.count = typename polygon_45_formation<Unit>::Vertex45Count(v.count[0], v.count[1], v.count[2], v.count[3]); - data_.push_back(v2); - } - polygon_45_set_data<coord_type> tmp; - polygon_set.get_error_data(tmp); - for(typename polygon_45_set_data<coord_type>::iterator_type itr = tmp.begin(); - itr != tmp.end(); ++itr) { - const typename polygon_45_set_data<coord_type>::Vertex45Compact& v = *itr; - typename polygon_45_set_data<Unit>::Vertex45Compact v2; - v2.pt.x(static_cast<Unit>(v.pt.x())); - v2.pt.y(static_cast<Unit>(v.pt.y())); - v2.count = typename polygon_45_formation<Unit>::Vertex45Count(v.count[0], v.count[1], v.count[2], v.count[3]); - error_data_.push_back(v2); - } - if(is_hole) { - for(std::size_t i = count; i < data_.size(); ++i) { - data_[i].count = data_[i].count.invert(); - } - } - dirty_ = true; - unsorted_ = true; - if(polygon_set.is_manhattan() == false) is_manhattan_ = false; - return; - } - - template <typename cT, typename rT> - void insert_rectangle_into_vector_45(cT& output, const rT& rect, bool is_hole) { - point_data<typename rectangle_traits<rT>::coordinate_type> - llpt = ll(rect), lrpt = lr(rect), ulpt = ul(rect), urpt = ur(rect); - direction_1d dir = COUNTERCLOCKWISE; - if(is_hole) dir = CLOCKWISE; - insert_vertex_half_edge_45_pair_into_vector(output, llpt, lrpt, urpt, dir); - insert_vertex_half_edge_45_pair_into_vector(output, lrpt, urpt, ulpt, dir); - insert_vertex_half_edge_45_pair_into_vector(output, urpt, ulpt, llpt, dir); - insert_vertex_half_edge_45_pair_into_vector(output, ulpt, llpt, lrpt, dir); - } - - template <typename Unit> - template <typename geometry_type> - inline void polygon_45_set_data<Unit>::insert_dispatch(const geometry_type& geometry_object, - bool is_hole, rectangle_concept ) { - dirty_ = true; - unsorted_ = true; - insert_rectangle_into_vector_45(data_, geometry_object, is_hole); - } - - // get the external boundary rectangle - template <typename Unit> - template <typename rectangle_type> - inline bool polygon_45_set_data<Unit>::extents(rectangle_type& rect) const{ - clean(); - if(empty()) { - return false; - } - Unit low = (std::numeric_limits<Unit>::max)(); - Unit high = (std::numeric_limits<Unit>::min)(); - interval_data<Unit> xivl(low, high); - interval_data<Unit> yivl(low, high); - for(typename value_type::const_iterator itr = data_.begin(); - itr != data_.end(); ++ itr) { - if((*itr).pt.x() > xivl.get(HIGH)) - xivl.set(HIGH, (*itr).pt.x()); - if((*itr).pt.x() < xivl.get(LOW)) - xivl.set(LOW, (*itr).pt.x()); - if((*itr).pt.y() > yivl.get(HIGH)) - yivl.set(HIGH, (*itr).pt.y()); - if((*itr).pt.y() < yivl.get(LOW)) - yivl.set(LOW, (*itr).pt.y()); - } - rect = construct<rectangle_type>(xivl, yivl); - return true; - } - - //this function snaps the vertex and two half edges - //to be both even or both odd coordinate values if one of the edges is 45 - //and throws an excpetion if an edge is non-manhattan, non-45. - template <typename Unit> - inline void polygon_45_set_data<Unit>::snap_vertex_45(typename polygon_45_set_data<Unit>::Vertex45Compact& vertex) { - bool plus45 = vertex.count[2] != 0; - bool minus45 = vertex.count[0] != 0; - if(plus45 || minus45) { - if(local_abs(vertex.pt.x()) % 2 != local_abs(vertex.pt.y()) % 2) { - if(vertex.count[1] != 0 || - (plus45 && minus45)) { - //move right - vertex.pt.x(vertex.pt.x() + 1); - } else { - //assert that vertex.count[3] != 0 - Unit modifier = plus45 ? -1 : 1; - vertex.pt.y(vertex.pt.y() + modifier); - } - } - } - } - - template <typename Unit> - inline void polygon_45_set_data<Unit>::snap() const { - for(typename value_type::iterator itr = data_.begin(); - itr != data_.end(); ++itr) { - snap_vertex_45(*itr); - } - } - - // |= &= += *= -= ^= binary operators - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator|=(const polygon_45_set_data<Unit>& b) { - insert(b); - return *this; - } - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator&=(const polygon_45_set_data<Unit>& b) { - //b.sort(); - //sort(); - applyAdaptiveBoolean_<1>(b); - dirty_ = false; - unsorted_ = false; - return *this; - } - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator+=(const polygon_45_set_data<Unit>& b) { - return (*this) |= b; - } - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator*=(const polygon_45_set_data<Unit>& b) { - return (*this) &= b; - } - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator-=(const polygon_45_set_data<Unit>& b) { - //b.sort(); - //sort(); - applyAdaptiveBoolean_<2>(b); - dirty_ = false; - unsorted_ = false; - return *this; - } - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator^=(const polygon_45_set_data<Unit>& b) { - //b.sort(); - //sort(); - applyAdaptiveBoolean_<3>(b); - dirty_ = false; - unsorted_ = false; - return *this; - } - - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator+=(Unit delta) { - return resize(delta); - } - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::operator-=(Unit delta) { - return (*this) += -delta; - } - - template <typename Unit> - inline polygon_45_set_data<Unit>& - polygon_45_set_data<Unit>::resize(Unit resizing, RoundingOption rounding, CornerOption corner) { - if(resizing == 0) return *this; - std::list<polygon_45_with_holes_data<Unit> > pl; - get_polygons_with_holes(pl); - clear(); - for(typename std::list<polygon_45_with_holes_data<Unit> >::iterator itr = pl.begin(); itr != pl.end(); ++itr) { - insert_with_resize(*itr, resizing, rounding, corner); - } - clean(); - //perterb 45 edges to prevent non-integer intersection errors upon boolean op - //snap(); - return *this; - } - - //distance is assumed to be positive - inline int roundClosest(double distance) { - int f = (int)distance; - if(distance - (double)f < 0.5) return f; - return f+1; - } - - //distance is assumed to be positive - template <typename Unit> - inline Unit roundWithOptions(double distance, RoundingOption rounding) { - if(rounding == CLOSEST) { - return roundClosest(distance); - } else if(rounding == OVERSIZE) { - return (Unit)distance + 1; - } else { //UNDERSIZE - return (Unit)distance; - } - } - - // 0 is east, 1 is northeast, 2 is north, 3 is northwest, 4 is west, 5 is southwest, 6 is south - // 7 is southwest - template <typename Unit> - inline point_data<Unit> bloatVertexInDirWithOptions(const point_data<Unit>& point, unsigned int dir, - Unit bloating, RoundingOption rounding) { - const double sqrt2 = 1.4142135623730950488016887242097; - if(dir & 1) { - Unit unitDistance = (Unit)bloating; - if(rounding != SQRT2) { - //45 degree bloating - double distance = (double)bloating; - distance /= sqrt2; // multiply by 1/sqrt2 - unitDistance = roundWithOptions<Unit>(distance, rounding); - } - int xMultiplier = 1; - int yMultiplier = 1; - if(dir == 3 || dir == 5) xMultiplier = -1; - if(dir == 5 || dir == 7) yMultiplier = -1; - return point_data<Unit>(point.x()+xMultiplier*unitDistance, - point.y()+yMultiplier*unitDistance); - } else { - if(dir == 0) - return point_data<Unit>(point.x()+bloating, point.y()); - if(dir == 2) - return point_data<Unit>(point.x(), point.y()+bloating); - if(dir == 4) - return point_data<Unit>(point.x()-bloating, point.y()); - if(dir == 6) - return point_data<Unit>(point.x(), point.y()-bloating); - return point_data<Unit>(); - } - } - - template <typename Unit> - inline unsigned int getEdge45Direction(const point_data<Unit>& pt1, const point_data<Unit>& pt2) { - if(pt1.x() == pt2.x()) { - if(pt1.y() < pt2.y()) return 2; - return 6; - } - if(pt1.y() == pt2.y()) { - if(pt1.x() < pt2.x()) return 0; - return 4; - } - if(pt2.y() > pt1.y()) { - if(pt2.x() > pt1.x()) return 1; - return 3; - } - if(pt2.x() > pt1.x()) return 7; - return 5; - } - - inline unsigned int getEdge45NormalDirection(unsigned int dir, int multiplier) { - if(multiplier < 0) - return (dir + 2) % 8; - return (dir + 4 + 2) % 8; - } - - template <typename Unit> - inline point_data<Unit> getIntersectionPoint(const point_data<Unit>& pt1, unsigned int slope1, - const point_data<Unit>& pt2, unsigned int slope2) { - //the intention here is to use all integer arithmetic without causing overflow - //turncation error or divide by zero error - //I don't use floating point arithmetic because its precision may not be high enough - //at the extremes of the integer range - typedef typename coordinate_traits<Unit>::area_type LongUnit; - const Unit rises[8] = {0, 1, 1, 1, 0, -1, -1, -1}; - const Unit runs[8] = {1, 1, 0, -1, -1, -1, 0, 1}; - LongUnit rise1 = rises[slope1]; - LongUnit rise2 = rises[slope2]; - LongUnit run1 = runs[slope1]; - LongUnit run2 = runs[slope2]; - LongUnit x1 = (LongUnit)pt1.x(); - LongUnit x2 = (LongUnit)pt2.x(); - LongUnit y1 = (LongUnit)pt1.y(); - LongUnit y2 = (LongUnit)pt2.y(); - Unit x = 0; - Unit y = 0; - if(run1 == 0) { - x = pt1.x(); - y = (Unit)(((x1 - x2) * rise2) / run2) + pt2.y(); - } else if(run2 == 0) { - x = pt2.x(); - y = (Unit)(((x2 - x1) * rise1) / run1) + pt1.y(); - } else { - // y - y1 = (rise1/run1)(x - x1) - // y - y2 = (rise2/run2)(x - x2) - // y = (rise1/run1)(x - x1) + y1 = (rise2/run2)(x - x2) + y2 - // (rise1/run1 - rise2/run2)x = y2 - y1 + rise1/run1 x1 - rise2/run2 x2 - // x = (y2 - y1 + rise1/run1 x1 - rise2/run2 x2)/(rise1/run1 - rise2/run2) - // x = (y2 - y1 + rise1/run1 x1 - rise2/run2 x2)(rise1 run2 - rise2 run1)/(run1 run2) - x = (Unit)((y2 - y1 + ((rise1 * x1) / run1) - ((rise2 * x2) / run2)) * - (run1 * run2) / (rise1 * run2 - rise2 * run1)); - if(rise1 == 0) { - y = pt1.y(); - } else if(rise2 == 0) { - y = pt2.y(); - } else { - // y - y1 = (rise1/run1)(x - x1) - // (run1/rise1)(y - y1) = x - x1 - // x = (run1/rise1)(y - y1) + x1 = (run2/rise2)(y - y2) + x2 - y = (Unit)((x2 - x1 + ((run1 * y1) / rise1) - ((run2 * y2) / rise2)) * - (rise1 * rise2) / (run1 * rise2 - run2 * rise1)); - } - } - return point_data<Unit>(x, y); - } - - template <typename Unit> - inline - void handleResizingEdge45_SQRT1OVER2(polygon_45_set_data<Unit>& sizingSet, point_data<Unit> first, - point_data<Unit> second, Unit resizing, CornerOption corner) { - if(first.x() == second.x()) { - sizingSet.insert(rectangle_data<Unit>(first.x() - resizing, first.y(), first.x() + resizing, second.y())); - return; - } - if(first.y() == second.y()) { - sizingSet.insert(rectangle_data<Unit>(first.x(), first.y() - resizing, second.x(), first.y() + resizing)); - return; - } - std::vector<point_data<Unit> > pts; - Unit bloating = resizing < 0 ? -resizing : resizing; - if(corner == UNFILLED) { - //we have to round up - bloating = bloating / 2 + bloating % 2 ; //round up - if(second.x() < first.x()) std::swap(first, second); - if(first.y() < second.y()) { //upward sloping - pts.push_back(point_data<Unit>(first.x() + bloating, first.y() - bloating)); - pts.push_back(point_data<Unit>(first.x() - bloating, first.y() + bloating)); - pts.push_back(point_data<Unit>(second.x() - bloating, second.y() + bloating)); - pts.push_back(point_data<Unit>(second.x() + bloating, second.y() - bloating)); - sizingSet.insert_vertex_sequence(pts.begin(), pts.end(), CLOCKWISE, false); - } else { //downward sloping - pts.push_back(point_data<Unit>(first.x() + bloating, first.y() + bloating)); - pts.push_back(point_data<Unit>(first.x() - bloating, first.y() - bloating)); - pts.push_back(point_data<Unit>(second.x() - bloating, second.y() - bloating)); - pts.push_back(point_data<Unit>(second.x() + bloating, second.y() + bloating)); - sizingSet.insert_vertex_sequence(pts.begin(), pts.end(), COUNTERCLOCKWISE, false); - } - return; - } - if(second.x() < first.x()) std::swap(first, second); - if(first.y() < second.y()) { //upward sloping - pts.push_back(point_data<Unit>(first.x(), first.y() - bloating)); - pts.push_back(point_data<Unit>(first.x() - bloating, first.y())); - pts.push_back(point_data<Unit>(second.x(), second.y() + bloating)); - pts.push_back(point_data<Unit>(second.x() + bloating, second.y())); - sizingSet.insert_vertex_sequence(pts.begin(), pts.end(), CLOCKWISE, false); - } else { //downward sloping - pts.push_back(point_data<Unit>(first.x() - bloating, first.y())); - pts.push_back(point_data<Unit>(first.x(), first.y() + bloating)); - pts.push_back(point_data<Unit>(second.x() + bloating, second.y())); - pts.push_back(point_data<Unit>(second.x(), second.y() - bloating)); - sizingSet.insert_vertex_sequence(pts.begin(), pts.end(), CLOCKWISE, false); - } - } - - - template <typename Unit> - inline - void handleResizingEdge45(polygon_45_set_data<Unit>& sizingSet, point_data<Unit> first, - point_data<Unit> second, Unit resizing, RoundingOption rounding) { - if(first.x() == second.x()) { - sizingSet.insert(rectangle_data<int>(first.x() - resizing, first.y(), first.x() + resizing, second.y())); - return; - } - if(first.y() == second.y()) { - sizingSet.insert(rectangle_data<int>(first.x(), first.y() - resizing, second.x(), first.y() + resizing)); - return; - } - //edge is 45 - std::vector<point_data<Unit> > pts; - Unit bloating = resizing < 0 ? -resizing : resizing; - if(second.x() < first.x()) std::swap(first, second); - if(first.y() < second.y()) { - pts.push_back(bloatVertexInDirWithOptions(first, 3, bloating, rounding)); - pts.push_back(bloatVertexInDirWithOptions(first, 7, bloating, rounding)); - pts.push_back(bloatVertexInDirWithOptions(second, 7, bloating, rounding)); - pts.push_back(bloatVertexInDirWithOptions(second, 3, bloating, rounding)); - sizingSet.insert_vertex_sequence(pts.begin(), pts.end(), HIGH, false); - } else { - pts.push_back(bloatVertexInDirWithOptions(first, 1, bloating, rounding)); - pts.push_back(bloatVertexInDirWithOptions(first, 5, bloating, rounding)); - pts.push_back(bloatVertexInDirWithOptions(second, 5, bloating, rounding)); - pts.push_back(bloatVertexInDirWithOptions(second, 1, bloating, rounding)); - sizingSet.insert_vertex_sequence(pts.begin(), pts.end(), HIGH, false); - } - } - - template <typename Unit> - inline point_data<Unit> bloatVertexInDirWithSQRT1OVER2(int edge1, int normal1, const point_data<Unit>& second, Unit bloating, - bool first) { - orientation_2d orient = first ? HORIZONTAL : VERTICAL; - orientation_2d orientp = orient.get_perpendicular(); - int multiplier = first ? 1 : -1; - point_data<Unit> pt1(second); - if(edge1 == 1) { - if(normal1 == 3) { - move(pt1, orient, -multiplier * bloating); - } else { - move(pt1, orientp, -multiplier * bloating); - } - } else if(edge1 == 3) { - if(normal1 == 1) { - move(pt1, orient, multiplier * bloating); - } else { - move(pt1, orientp, -multiplier * bloating); - } - } else if(edge1 == 5) { - if(normal1 == 3) { - move(pt1, orientp, multiplier * bloating); - } else { - move(pt1, orient, multiplier * bloating); - } - } else { - if(normal1 == 5) { - move(pt1, orient, -multiplier * bloating); - } else { - move(pt1, orientp, multiplier * bloating); - } - } - return pt1; - } - - template <typename Unit> - inline - void handleResizingVertex45(polygon_45_set_data<Unit>& sizingSet, const point_data<Unit>& first, - const point_data<Unit>& second, const point_data<Unit>& third, Unit resizing, - RoundingOption rounding, CornerOption corner, - int multiplier) { - unsigned int edge1 = getEdge45Direction(first, second); - unsigned int edge2 = getEdge45Direction(second, third); - unsigned int diffAngle; - if(multiplier < 0) - diffAngle = (edge2 + 8 - edge1) % 8; - else - diffAngle = (edge1 + 8 - edge2) % 8; - if(diffAngle < 4) { - if(resizing > 0) return; //accute interior corner - else multiplier *= -1; //make it appear to be an accute exterior angle - } - Unit bloating = local_abs(resizing); - if(rounding == SQRT1OVER2) { - if(edge1 % 2 && edge2 % 2) return; - if(corner == ORTHOGONAL && edge1 % 2 == 0 && edge2 % 2 == 0) { - rectangle_data<Unit> insertion_rect; - set_points(insertion_rect, second, second); - bloat(insertion_rect, bloating); - sizingSet.insert(insertion_rect); - } else if(corner != ORTHOGONAL) { - point_data<Unit> pt1(0, 0); - point_data<Unit> pt2(0, 0); - unsigned int normal1 = getEdge45NormalDirection(edge1, multiplier); - unsigned int normal2 = getEdge45NormalDirection(edge2, multiplier); - if(edge1 % 2) { - pt1 = bloatVertexInDirWithSQRT1OVER2(edge1, normal1, second, bloating, true); - } else { - pt1 = bloatVertexInDirWithOptions(second, normal1, bloating, UNDERSIZE); - } - if(edge2 % 2) { - pt2 = bloatVertexInDirWithSQRT1OVER2(edge2, normal2, second, bloating, false); - } else { - pt2 = bloatVertexInDirWithOptions(second, normal2, bloating, UNDERSIZE); - } - std::vector<point_data<Unit> > pts; - pts.push_back(pt1); - pts.push_back(second); - pts.push_back(pt2); - pts.push_back(getIntersectionPoint(pt1, edge1, pt2, edge2)); - polygon_45_data<Unit> poly(pts.begin(), pts.end()); - sizingSet.insert(poly); - } else { - //ORTHOGONAL of a 45 degree corner - int normal = 0; - if(edge1 % 2) { - normal = getEdge45NormalDirection(edge2, multiplier); - } else { - normal = getEdge45NormalDirection(edge1, multiplier); - } - rectangle_data<Unit> insertion_rect; - point_data<Unit> edgePoint = bloatVertexInDirWithOptions(second, normal, bloating, UNDERSIZE); - set_points(insertion_rect, second, edgePoint); - if(normal == 0 || normal == 4) - bloat(insertion_rect, VERTICAL, bloating); - else - bloat(insertion_rect, HORIZONTAL, bloating); - sizingSet.insert(insertion_rect); - } - return; - } - unsigned int normal1 = getEdge45NormalDirection(edge1, multiplier); - unsigned int normal2 = getEdge45NormalDirection(edge2, multiplier); - point_data<Unit> edgePoint1 = bloatVertexInDirWithOptions(second, normal1, bloating, rounding); - point_data<Unit> edgePoint2 = bloatVertexInDirWithOptions(second, normal2, bloating, rounding); - //if the change in angle is 135 degrees it is an accute exterior corner - if((edge1+ multiplier * 3) % 8 == edge2) { - if(corner == ORTHOGONAL) { - rectangle_data<Unit> insertion_rect; - set_points(insertion_rect, edgePoint1, edgePoint2); - sizingSet.insert(insertion_rect); - return; - } - } - std::vector<point_data<Unit> > pts; - pts.push_back(edgePoint1); - pts.push_back(second); - pts.push_back(edgePoint2); - pts.push_back(getIntersectionPoint(edgePoint1, edge1, edgePoint2, edge2)); - polygon_45_data<Unit> poly(pts.begin(), pts.end()); - sizingSet.insert(poly); - } - - template <typename Unit> - template <typename geometry_type> - inline polygon_45_set_data<Unit>& - polygon_45_set_data<Unit>::insert_with_resize_dispatch(const geometry_type& poly, - coordinate_type resizing, - RoundingOption rounding, - CornerOption corner, - bool hole, polygon_45_concept ) { - direction_1d wdir = winding(poly); - int multiplier = wdir == LOW ? -1 : 1; - if(hole) resizing *= -1; - typedef typename polygon_45_data<Unit>::iterator_type piterator; - piterator first, second, third, end, real_end; - real_end = end_points(poly); - third = begin_points(poly); - first = third; - if(first == real_end) return *this; - ++third; - if(third == real_end) return *this; - second = end = third; - ++third; - if(third == real_end) return *this; - polygon_45_set_data<Unit> sizingSet; - //insert minkofski shapes on edges and corners - do { - if(rounding != SQRT1OVER2) { - handleResizingEdge45(sizingSet, *first, *second, resizing, rounding); - } else { - handleResizingEdge45_SQRT1OVER2(sizingSet, *first, *second, resizing, corner); - } - if(corner != UNFILLED) - handleResizingVertex45(sizingSet, *first, *second, *third, resizing, rounding, corner, multiplier); - first = second; - second = third; - ++third; - if(third == real_end) { - third = begin_points(poly); - if(*second == *third) { - ++third; //skip first point if it is duplicate of last point - } - } - } while(second != end); - //sizingSet.snap(); - polygon_45_set_data<Unit> tmp; - //insert original shape - tmp.insert_dispatch(poly, false, polygon_45_concept()); - if(resizing < 0) tmp -= sizingSet; - else tmp += sizingSet; - tmp.clean(); - insert(tmp, hole); - dirty_ = true; - unsorted_ = true; - return (*this); - } - - // accumulate the bloated polygon with holes - template <typename Unit> - template <typename geometry_type> - inline polygon_45_set_data<Unit>& - polygon_45_set_data<Unit>::insert_with_resize_dispatch(const geometry_type& poly, - coordinate_type resizing, - RoundingOption rounding, - CornerOption corner, - bool hole, polygon_45_with_holes_concept ) { - insert_with_resize_dispatch(poly, resizing, rounding, corner, hole, polygon_45_concept()); - for(typename polygon_with_holes_traits<geometry_type>::iterator_holes_type itr = - begin_holes(poly); itr != end_holes(poly); - ++itr) { - insert_with_resize_dispatch(*itr, resizing, rounding, corner, !hole, polygon_45_concept()); - } - return *this; - } - - // transform set - template <typename Unit> - template <typename transformation_type> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::transform(const transformation_type& tr){ - clean(); - std::vector<polygon_45_with_holes_data<Unit> > polys; - get(polys); - for(typename std::vector<polygon_45_with_holes_data<Unit> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - ::boost::polygon::transform(*itr, tr); - } - clear(); - insert(polys.begin(), polys.end()); - dirty_ = true; - unsorted_ = true; - return *this; - } - - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::scale_up(typename coordinate_traits<Unit>::unsigned_area_type factor) { - scale_up_vertex_45_compact_range(data_.begin(), data_.end(), factor); - return *this; - } - - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::scale_down(typename coordinate_traits<Unit>::unsigned_area_type factor) { - clean(); - std::vector<polygon_45_with_holes_data<Unit> > polys; - get_polygons_with_holes(polys); - for(typename std::vector<polygon_45_with_holes_data<Unit> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - ::boost::polygon::scale_down(*itr, factor); - } - clear(); - insert(polys.begin(), polys.end()); - dirty_ = true; - unsorted_ = true; - return *this; - } - - template <typename Unit> - inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::scale(double factor) { - clean(); - std::vector<polygon_45_with_holes_data<Unit> > polys; - get_polygons_with_holes(polys); - for(typename std::vector<polygon_45_with_holes_data<Unit> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - ::boost::polygon::scale(*itr, factor); - } - clear(); - insert(polys.begin(), polys.end()); - dirty_ = true; - unsorted_ = true; - return *this; - } - - template <typename Unit> - inline bool polygon_45_set_data<Unit>::clean() const { - if(unsorted_) sort(); - if(dirty_) { - applyAdaptiveUnary_<0>(); - dirty_ = false; - } - return true; - } - - template <typename Unit> - template <int op> - inline void polygon_45_set_data<Unit>::applyAdaptiveBoolean_(const polygon_45_set_data<Unit>& rvalue) const { - polygon_45_set_data<Unit> tmp; - applyAdaptiveBoolean_<op>(tmp, rvalue); - data_.swap(tmp.data_); //swapping vectors should be constant time operation - error_data_.swap(tmp.error_data_); - is_manhattan_ = tmp.is_manhattan_; - unsorted_ = false; - dirty_ = false; - } - - template <typename Unit2, int op> - bool applyBoolean45OpOnVectors(std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact>& result_data, - std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact>& lvalue_data, - std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact>& rvalue_data - ) { - bool result_is_manhattan_ = true; - typename boolean_op_45<Unit2>::template Scan45<typename boolean_op_45<Unit2>::Count2, - typename boolean_op_45<Unit2>::template boolean_op_45_output_functor<op> > scan45; - std::vector<typename boolean_op_45<Unit2>::Vertex45> eventOut; - typedef std::pair<typename boolean_op_45<Unit2>::Point, - typename boolean_op_45<Unit2>::template Scan45CountT<typename boolean_op_45<Unit2>::Count2> > Scan45Vertex; - std::vector<Scan45Vertex> eventIn; - typedef std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact> value_type; - typename value_type::const_iterator iter1 = lvalue_data.begin(); - typename value_type::const_iterator iter2 = rvalue_data.begin(); - typename value_type::const_iterator end1 = lvalue_data.end(); - typename value_type::const_iterator end2 = rvalue_data.end(); - const Unit2 UnitMax = (std::numeric_limits<Unit2>::max)(); - Unit2 x = UnitMax; - while(iter1 != end1 || iter2 != end2) { - Unit2 currentX = UnitMax; - if(iter1 != end1) currentX = iter1->pt.x(); - if(iter2 != end2) currentX = (std::min)(currentX, iter2->pt.x()); - if(currentX != x) { - //std::cout << "SCAN " << currentX << "\n"; - //scan event - scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - polygon_sort(eventOut.begin(), eventOut.end()); - std::size_t ptCount = 0; - for(std::size_t i = 0; i < eventOut.size(); ++i) { - if(!result_data.empty() && - result_data.back().pt == eventOut[i].pt) { - result_data.back().count += eventOut[i]; - ++ptCount; - } else { - if(!result_data.empty()) { - if(result_data.back().count.is_45()) { - result_is_manhattan_ = false; - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - } - result_data.push_back(eventOut[i]); - ptCount = 1; - } - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - eventOut.clear(); - eventIn.clear(); - x = currentX; - } - //std::cout << "get next\n"; - if(iter2 != end2 && (iter1 == end1 || iter2->pt.x() < iter1->pt.x() || - (iter2->pt.x() == iter1->pt.x() && - iter2->pt.y() < iter1->pt.y()) )) { - //std::cout << "case1 next\n"; - eventIn.push_back(Scan45Vertex - (iter2->pt, - typename polygon_45_formation<Unit2>:: - Scan45Count(typename polygon_45_formation<Unit2>::Count2(0, iter2->count[0]), - typename polygon_45_formation<Unit2>::Count2(0, iter2->count[1]), - typename polygon_45_formation<Unit2>::Count2(0, iter2->count[2]), - typename polygon_45_formation<Unit2>::Count2(0, iter2->count[3])))); - ++iter2; - } else if(iter1 != end1 && (iter2 == end2 || iter1->pt.x() < iter2->pt.x() || - (iter1->pt.x() == iter2->pt.x() && - iter1->pt.y() < iter2->pt.y()) )) { - //std::cout << "case2 next\n"; - eventIn.push_back(Scan45Vertex - (iter1->pt, - typename polygon_45_formation<Unit2>:: - Scan45Count( - typename polygon_45_formation<Unit2>::Count2(iter1->count[0], 0), - typename polygon_45_formation<Unit2>::Count2(iter1->count[1], 0), - typename polygon_45_formation<Unit2>::Count2(iter1->count[2], 0), - typename polygon_45_formation<Unit2>::Count2(iter1->count[3], 0)))); - ++iter1; - } else { - //std::cout << "case3 next\n"; - eventIn.push_back(Scan45Vertex - (iter2->pt, - typename polygon_45_formation<Unit2>:: - Scan45Count(typename polygon_45_formation<Unit2>::Count2(iter1->count[0], - iter2->count[0]), - typename polygon_45_formation<Unit2>::Count2(iter1->count[1], - iter2->count[1]), - typename polygon_45_formation<Unit2>::Count2(iter1->count[2], - iter2->count[2]), - typename polygon_45_formation<Unit2>::Count2(iter1->count[3], - iter2->count[3])))); - ++iter1; - ++iter2; - } - } - scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - polygon_sort(eventOut.begin(), eventOut.end()); - - std::size_t ptCount = 0; - for(std::size_t i = 0; i < eventOut.size(); ++i) { - if(!result_data.empty() && - result_data.back().pt == eventOut[i].pt) { - result_data.back().count += eventOut[i]; - ++ptCount; - } else { - if(!result_data.empty()) { - if(result_data.back().count.is_45()) { - result_is_manhattan_ = false; - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - } - result_data.push_back(eventOut[i]); - ptCount = 1; - } - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - if(!result_data.empty() && - result_data.back().count.is_45()) { - result_is_manhattan_ = false; - } - return result_is_manhattan_; - } - - template <typename Unit2, int op> - bool applyUnary45OpOnVectors(std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact>& result_data, - std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact>& lvalue_data ) { - bool result_is_manhattan_ = true; - typename boolean_op_45<Unit2>::template Scan45<typename boolean_op_45<Unit2>::Count1, - typename boolean_op_45<Unit2>::template unary_op_45_output_functor<op> > scan45; - std::vector<typename boolean_op_45<Unit2>::Vertex45> eventOut; - typedef typename boolean_op_45<Unit2>::template Scan45CountT<typename boolean_op_45<Unit2>::Count1> Scan45Count; - typedef std::pair<typename boolean_op_45<Unit2>::Point, Scan45Count> Scan45Vertex; - std::vector<Scan45Vertex> eventIn; - typedef std::vector<typename polygon_45_formation<Unit2>::Vertex45Compact> value_type; - typename value_type::const_iterator iter1 = lvalue_data.begin(); - typename value_type::const_iterator end1 = lvalue_data.end(); - const Unit2 UnitMax = (std::numeric_limits<Unit2>::max)(); - Unit2 x = UnitMax; - while(iter1 != end1) { - Unit2 currentX = iter1->pt.x(); - if(currentX != x) { - //std::cout << "SCAN " << currentX << "\n"; - //scan event - scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - polygon_sort(eventOut.begin(), eventOut.end()); - std::size_t ptCount = 0; - for(std::size_t i = 0; i < eventOut.size(); ++i) { - if(!result_data.empty() && - result_data.back().pt == eventOut[i].pt) { - result_data.back().count += eventOut[i]; - ++ptCount; - } else { - if(!result_data.empty()) { - if(result_data.back().count.is_45()) { - result_is_manhattan_ = false; - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - } - result_data.push_back(eventOut[i]); - ptCount = 1; - } - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - eventOut.clear(); - eventIn.clear(); - x = currentX; - } - //std::cout << "get next\n"; - eventIn.push_back(Scan45Vertex - (iter1->pt, - Scan45Count( typename boolean_op_45<Unit2>::Count1(iter1->count[0]), - typename boolean_op_45<Unit2>::Count1(iter1->count[1]), - typename boolean_op_45<Unit2>::Count1(iter1->count[2]), - typename boolean_op_45<Unit2>::Count1(iter1->count[3])))); - ++iter1; - } - scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - polygon_sort(eventOut.begin(), eventOut.end()); - - std::size_t ptCount = 0; - for(std::size_t i = 0; i < eventOut.size(); ++i) { - if(!result_data.empty() && - result_data.back().pt == eventOut[i].pt) { - result_data.back().count += eventOut[i]; - ++ptCount; - } else { - if(!result_data.empty()) { - if(result_data.back().count.is_45()) { - result_is_manhattan_ = false; - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - } - result_data.push_back(eventOut[i]); - ptCount = 1; - } - } - if(ptCount == 2 && result_data.back().count == (typename polygon_45_formation<Unit2>::Vertex45Count(0, 0, 0, 0))) { - result_data.pop_back(); - } - if(!result_data.empty() && - result_data.back().count.is_45()) { - result_is_manhattan_ = false; - } - return result_is_manhattan_; - } - - template <typename cT, typename iT> - void get_error_rects_shell(cT& posE, cT& negE, iT beginr, iT endr) { - typedef typename std::iterator_traits<iT>::value_type Point; - typedef typename point_traits<Point>::coordinate_type Unit; - typedef typename coordinate_traits<Unit>::area_type area_type; - Point pt1, pt2, pt3; - bool i1 = true; - bool i2 = true; - bool not_done = beginr != endr; - bool next_to_last = false; - bool last = false; - Point first, second; - while(not_done) { - if(last) { - last = false; - not_done = false; - pt3 = second; - } else if(next_to_last) { - next_to_last = false; - last = true; - pt3 = first; - } else if(i1) { - const Point& pt = *beginr; - first = pt1 = pt; - i1 = false; - i2 = true; - ++beginr; - if(beginr == endr) return; //too few points - continue; - } else if (i2) { - const Point& pt = *beginr; - second = pt2 = pt; - i2 = false; - ++beginr; - if(beginr == endr) return; //too few points - continue; - } else { - const Point& pt = *beginr; - pt3 = pt; - ++beginr; - if(beginr == endr) { - next_to_last = true; - //skip last point equal to first - continue; - } - } - if(local_abs(x(pt2)) % 2) { //y % 2 should also be odd - //is corner concave or convex? - Point pts[] = {pt1, pt2, pt3}; - area_type ar = point_sequence_area<Point*, area_type>(pts, pts+3); - direction_1d dir = ar < 0 ? COUNTERCLOCKWISE : CLOCKWISE; - //std::cout << pt1 << " " << pt2 << " " << pt3 << " " << ar << std::endl; - if(dir == CLOCKWISE) { - posE.push_back(rectangle_data<typename Point::coordinate_type> - (x(pt2) - 1, y(pt2) - 1, x(pt2) + 1, y(pt2) + 1)); - - } else { - negE.push_back(rectangle_data<typename Point::coordinate_type> - (x(pt2) - 1, y(pt2) - 1, x(pt2) + 1, y(pt2) + 1)); - } - } - pt1 = pt2; - pt2 = pt3; - } - } - - template <typename cT, typename pT> - void get_error_rects(cT& posE, cT& negE, const pT& p) { - get_error_rects_shell(posE, negE, p.begin(), p.end()); - for(typename pT::iterator_holes_type iHb = p.begin_holes(); - iHb != p.end_holes(); ++iHb) { - get_error_rects_shell(posE, negE, iHb->begin(), iHb->end()); - } - } - - template <typename Unit> - template <int op> - inline void polygon_45_set_data<Unit>::applyAdaptiveBoolean_(polygon_45_set_data<Unit>& result, - const polygon_45_set_data<Unit>& rvalue) const { - result.clear(); - result.error_data_ = error_data_; - result.error_data_.insert(result.error_data_.end(), rvalue.error_data_.begin(), - rvalue.error_data_.end()); - if(is_manhattan() && rvalue.is_manhattan()) { - //convert each into polygon_90_set data and call boolean operations - polygon_90_set_data<Unit> l90sd(VERTICAL), r90sd(VERTICAL), output(VERTICAL); - for(typename value_type::const_iterator itr = data_.begin(); itr != data_.end(); ++itr) { - if((*itr).count[3] == 0) continue; //skip all non vertical edges - l90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair<Unit, int>((*itr).pt.y(), (*itr).count[3])), false, VERTICAL); - } - for(typename value_type::const_iterator itr = rvalue.data_.begin(); itr != rvalue.data_.end(); ++itr) { - if((*itr).count[3] == 0) continue; //skip all non vertical edges - r90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair<Unit, int>((*itr).pt.y(), (*itr).count[3])), false, VERTICAL); - } - l90sd.sort(); - r90sd.sort(); -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op == 0) { - output.applyBooleanBinaryOp(l90sd.begin(), l90sd.end(), - r90sd.begin(), r90sd.end(), boolean_op::BinaryCount<boolean_op::BinaryOr>()); - } else if (op == 1) { - output.applyBooleanBinaryOp(l90sd.begin(), l90sd.end(), - r90sd.begin(), r90sd.end(), boolean_op::BinaryCount<boolean_op::BinaryAnd>()); - } else if (op == 2) { - output.applyBooleanBinaryOp(l90sd.begin(), l90sd.end(), - r90sd.begin(), r90sd.end(), boolean_op::BinaryCount<boolean_op::BinaryNot>()); - } else if (op == 3) { - output.applyBooleanBinaryOp(l90sd.begin(), l90sd.end(), - r90sd.begin(), r90sd.end(), boolean_op::BinaryCount<boolean_op::BinaryXor>()); - } -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - result.data_.clear(); - result.insert(output); - result.is_manhattan_ = true; - result.dirty_ = false; - result.unsorted_ = false; - } else { - sort(); - rvalue.sort(); - try { - result.is_manhattan_ = applyBoolean45OpOnVectors<Unit, op>(result.data_, data_, rvalue.data_); - } catch (std::string str) { - std::string msg = "GTL 45 Boolean error, precision insufficient to represent edge intersection coordinate value."; - if(str == msg) { - result.clear(); - typedef typename coordinate_traits<Unit>::manhattan_area_type Unit2; - typedef typename polygon_45_formation<Unit2>::Vertex45Compact Vertex45Compact2; - typedef std::vector<Vertex45Compact2> Data2; - Data2 rvalue_data, lvalue_data, result_data; - rvalue_data.reserve(rvalue.data_.size()); - lvalue_data.reserve(data_.size()); - for(std::size_t i = 0 ; i < data_.size(); ++i) { - const Vertex45Compact& vi = data_[i]; - Vertex45Compact2 ci; - ci.pt = point_data<Unit2>(x(vi.pt), y(vi.pt)); - ci.count = typename polygon_45_formation<Unit2>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - lvalue_data.push_back(ci); - } - for(std::size_t i = 0 ; i < rvalue.data_.size(); ++i) { - const Vertex45Compact& vi = rvalue.data_[i]; - Vertex45Compact2 ci; - ci.pt = (point_data<Unit2>(x(vi.pt), y(vi.pt))); - ci.count = typename polygon_45_formation<Unit2>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - rvalue_data.push_back(ci); - } - scale_up_vertex_45_compact_range(lvalue_data.begin(), lvalue_data.end(), 2); - scale_up_vertex_45_compact_range(rvalue_data.begin(), rvalue_data.end(), 2); - bool result_is_manhattan = applyBoolean45OpOnVectors<Unit2, op>(result_data, - lvalue_data, - rvalue_data ); - if(!result_is_manhattan) { - typename polygon_45_formation<Unit2>::Polygon45Formation pf(false); - //std::cout << "FORMING POLYGONS\n"; - std::vector<polygon_45_with_holes_data<Unit2> > container; - pf.scan(container, result_data.begin(), result_data.end()); - Data2 error_data_out; - std::vector<rectangle_data<Unit2> > pos_error_rects; - std::vector<rectangle_data<Unit2> > neg_error_rects; - for(std::size_t i = 0; i < container.size(); ++i) { - get_error_rects(pos_error_rects, neg_error_rects, container[i]); - } - for(std::size_t i = 0; i < pos_error_rects.size(); ++i) { - insert_rectangle_into_vector_45(result_data, pos_error_rects[i], false); - insert_rectangle_into_vector_45(error_data_out, pos_error_rects[i], false); - } - for(std::size_t i = 0; i < neg_error_rects.size(); ++i) { - insert_rectangle_into_vector_45(result_data, neg_error_rects[i], true); - insert_rectangle_into_vector_45(error_data_out, neg_error_rects[i], false); - } - scale_down_vertex_45_compact_range_blindly(error_data_out.begin(), error_data_out.end(), 2); - for(std::size_t i = 0 ; i < error_data_out.size(); ++i) { - const Vertex45Compact2& vi = error_data_out[i]; - Vertex45Compact ci; - ci.pt.x(static_cast<Unit>(x(vi.pt))); - ci.pt.y(static_cast<Unit>(y(vi.pt))); - ci.count = typename polygon_45_formation<Unit>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - result.error_data_.push_back(ci); - } - Data2 new_result_data; - polygon_sort(result_data.begin(), result_data.end()); - applyUnary45OpOnVectors<Unit2, 0>(new_result_data, result_data); //OR operation - result_data.swap(new_result_data); - } - scale_down_vertex_45_compact_range_blindly(result_data.begin(), result_data.end(), 2); - //result.data_.reserve(result_data.size()); - for(std::size_t i = 0 ; i < result_data.size(); ++i) { - const Vertex45Compact2& vi = result_data[i]; - Vertex45Compact ci; - ci.pt.x(static_cast<Unit>(x(vi.pt))); - ci.pt.y(static_cast<Unit>(y(vi.pt))); - ci.count = typename polygon_45_formation<Unit>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - result.data_.push_back(ci); - } - result.is_manhattan_ = result_is_manhattan; - result.dirty_ = false; - result.unsorted_ = false; - } else { throw str; } - } - //std::cout << "DONE SCANNING\n"; - } - } - - template <typename Unit> - template <int op> - inline void polygon_45_set_data<Unit>::applyAdaptiveUnary_() const { - polygon_45_set_data<Unit> result; - result.error_data_ = error_data_; - if(is_manhattan()) { - //convert each into polygon_90_set data and call boolean operations - polygon_90_set_data<Unit> l90sd(VERTICAL); - for(typename value_type::const_iterator itr = data_.begin(); itr != data_.end(); ++itr) { - if((*itr).count[3] == 0) continue; //skip all non vertical edges - l90sd.insert(std::make_pair((*itr).pt.x(), std::make_pair<Unit, int>((*itr).pt.y(), (*itr).count[3])), false, VERTICAL); - } - l90sd.sort(); -#ifdef BOOST_POLYGON_MSVC -#pragma warning (push) -#pragma warning (disable: 4127) -#endif - if(op == 0) { - l90sd.clean(); - } else if (op == 1) { - l90sd.self_intersect(); - } else if (op == 3) { - l90sd.self_xor(); - } -#ifdef BOOST_POLYGON_MSVC -#pragma warning (pop) -#endif - result.data_.clear(); - result.insert(l90sd); - result.is_manhattan_ = true; - result.dirty_ = false; - result.unsorted_ = false; - } else { - sort(); - try { - result.is_manhattan_ = applyUnary45OpOnVectors<Unit, op>(result.data_, data_); - } catch (std::string str) { - std::string msg = "GTL 45 Boolean error, precision insufficient to represent edge intersection coordinate value."; - if(str == msg) { - result.clear(); - typedef typename coordinate_traits<Unit>::manhattan_area_type Unit2; - typedef typename polygon_45_formation<Unit2>::Vertex45Compact Vertex45Compact2; - typedef std::vector<Vertex45Compact2> Data2; - Data2 lvalue_data, result_data; - lvalue_data.reserve(data_.size()); - for(std::size_t i = 0 ; i < data_.size(); ++i) { - const Vertex45Compact& vi = data_[i]; - Vertex45Compact2 ci; - ci.pt.x(static_cast<Unit>(x(vi.pt))); - ci.pt.y(static_cast<Unit>(y(vi.pt))); - ci.count = typename polygon_45_formation<Unit2>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - lvalue_data.push_back(ci); - } - scale_up_vertex_45_compact_range(lvalue_data.begin(), lvalue_data.end(), 2); - bool result_is_manhattan = applyUnary45OpOnVectors<Unit2, op>(result_data, - lvalue_data ); - if(!result_is_manhattan) { - typename polygon_45_formation<Unit2>::Polygon45Formation pf(false); - //std::cout << "FORMING POLYGONS\n"; - std::vector<polygon_45_with_holes_data<Unit2> > container; - pf.scan(container, result_data.begin(), result_data.end()); - Data2 error_data_out; - std::vector<rectangle_data<Unit2> > pos_error_rects; - std::vector<rectangle_data<Unit2> > neg_error_rects; - for(std::size_t i = 0; i < container.size(); ++i) { - get_error_rects(pos_error_rects, neg_error_rects, container[i]); - } - for(std::size_t i = 0; i < pos_error_rects.size(); ++i) { - insert_rectangle_into_vector_45(result_data, pos_error_rects[i], false); - insert_rectangle_into_vector_45(error_data_out, pos_error_rects[i], false); - } - for(std::size_t i = 0; i < neg_error_rects.size(); ++i) { - insert_rectangle_into_vector_45(result_data, neg_error_rects[i], true); - insert_rectangle_into_vector_45(error_data_out, neg_error_rects[i], false); - } - scale_down_vertex_45_compact_range_blindly(error_data_out.begin(), error_data_out.end(), 2); - for(std::size_t i = 0 ; i < error_data_out.size(); ++i) { - const Vertex45Compact2& vi = error_data_out[i]; - Vertex45Compact ci; - ci.pt.x(static_cast<Unit>(x(vi.pt))); - ci.pt.y(static_cast<Unit>(y(vi.pt))); - ci.count = typename polygon_45_formation<Unit>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - result.error_data_.push_back(ci); - } - Data2 new_result_data; - polygon_sort(result_data.begin(), result_data.end()); - applyUnary45OpOnVectors<Unit2, 0>(new_result_data, result_data); //OR operation - result_data.swap(new_result_data); - } - scale_down_vertex_45_compact_range_blindly(result_data.begin(), result_data.end(), 2); - //result.data_.reserve(result_data.size()); - for(std::size_t i = 0 ; i < result_data.size(); ++i) { - const Vertex45Compact2& vi = result_data[i]; - Vertex45Compact ci; - ci.pt.x(static_cast<Unit>(x(vi.pt))); - ci.pt.y(static_cast<Unit>(y(vi.pt))); - ci.count = typename polygon_45_formation<Unit>::Vertex45Count - ( vi.count[0], vi.count[1], vi.count[2], vi.count[3]); - result.data_.push_back(ci); - } - result.is_manhattan_ = result_is_manhattan; - result.dirty_ = false; - result.unsorted_ = false; - } else { throw str; } - } - //std::cout << "DONE SCANNING\n"; - } - data_.swap(result.data_); - error_data_.swap(result.error_data_); - dirty_ = result.dirty_; - unsorted_ = result.unsorted_; - is_manhattan_ = result.is_manhattan_; - } - - template <typename coordinate_type, typename property_type> - class property_merge_45 { - private: - typedef typename coordinate_traits<coordinate_type>::manhattan_area_type big_coord; - typedef typename polygon_45_property_merge<big_coord, property_type>::MergeSetData tsd; - tsd tsd_; - public: - inline property_merge_45() : tsd_() {} - inline property_merge_45(const property_merge_45& that) : tsd_(that.tsd_) {} - inline property_merge_45& operator=(const property_merge_45& that) { - tsd_ = that.tsd_; - return *this; - } - - inline void insert(const polygon_45_set_data<coordinate_type>& ps, property_type property) { - ps.clean(); - polygon_45_property_merge<big_coord, property_type>::populateMergeSetData(tsd_, ps.begin(), ps.end(), property); - } - template <class GeoObjT> - inline void insert(const GeoObjT& geoObj, property_type property) { - polygon_45_set_data<coordinate_type> ps; - ps.insert(geoObj); - insert(ps, property); - } - - //merge properties of input geometries and store the resulting geometries of regions - //with unique sets of merged properties to polygons sets in a map keyed by sets of properties - // T = std::map<std::set<property_type>, polygon_45_set_data<coordiante_type> > or - // T = std::map<std::vector<property_type>, polygon_45_set_data<coordiante_type> > - template <class result_type> - inline void merge(result_type& result) { - typedef typename result_type::key_type keytype; - typedef std::map<keytype, polygon_45_set_data<big_coord> > bigtype; - bigtype result_big; - polygon_45_property_merge<big_coord, property_type>::performMerge(result_big, tsd_); - std::vector<polygon_45_with_holes_data<big_coord> > polys; - std::vector<rectangle_data<big_coord> > pos_error_rects; - std::vector<rectangle_data<big_coord> > neg_error_rects; - for(typename std::map<keytype, polygon_45_set_data<big_coord> >::iterator itr = result_big.begin(); - itr != result_big.end(); ++itr) { - polys.clear(); - (*itr).second.get(polys); - for(std::size_t i = 0; i < polys.size(); ++i) { - get_error_rects(pos_error_rects, neg_error_rects, polys[i]); - } - (*itr).second += pos_error_rects; - (*itr).second -= neg_error_rects; - (*itr).second.scale_down(2); - result[(*itr).first].insert((*itr).second); - } - } - }; - - //ConnectivityExtraction computes the graph of connectivity between rectangle, polygon and - //polygon set graph nodes where an edge is created whenever the geometry in two nodes overlap - template <typename coordinate_type> - class connectivity_extraction_45 { - private: - typedef typename coordinate_traits<coordinate_type>::manhattan_area_type big_coord; - typedef typename polygon_45_touch<big_coord>::TouchSetData tsd; - tsd tsd_; - unsigned int nodeCount_; - public: - inline connectivity_extraction_45() : tsd_(), nodeCount_(0) {} - inline connectivity_extraction_45(const connectivity_extraction_45& that) : tsd_(that.tsd_), - nodeCount_(that.nodeCount_) {} - inline connectivity_extraction_45& operator=(const connectivity_extraction_45& that) { - tsd_ = that.tsd_; - nodeCount_ = that.nodeCount_; {} - return *this; - } - - //insert a polygon set graph node, the value returned is the id of the graph node - inline unsigned int insert(const polygon_45_set_data<coordinate_type>& ps) { - ps.clean(); - polygon_45_touch<big_coord>::populateTouchSetData(tsd_, ps.begin(), ps.end(), nodeCount_); - return nodeCount_++; - } - template <class GeoObjT> - inline unsigned int insert(const GeoObjT& geoObj) { - polygon_45_set_data<coordinate_type> ps; - ps.insert(geoObj); - return insert(ps); - } - - //extract connectivity and store the edges in the graph - //graph must be indexable by graph node id and the indexed value must be a std::set of - //graph node id - template <class GraphT> - inline void extract(GraphT& graph) { - polygon_45_touch<big_coord>::performTouch(graph, tsd_); - } - }; -} -} -#endif - diff --git a/contrib/restricted/boost/boost/polygon/polygon_45_set_traits.hpp b/contrib/restricted/boost/boost/polygon/polygon_45_set_traits.hpp deleted file mode 100644 index f52f57f17e..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_45_set_traits.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - 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_POLYGON_45_SET_TRAITS_HPP -#define BOOST_POLYGON_POLYGON_45_SET_TRAITS_HPP -namespace boost { namespace polygon{ - - //default definition of polygon 45 set traits works for any model of polygon 45, polygon 45 with holes or any vector or list thereof - template <typename T> - struct polygon_45_set_traits { - typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; - typedef typename get_iterator_type<T>::type iterator_type; - typedef T operator_arg_type; - - static inline iterator_type begin(const T& polygon_set) { - return get_iterator_type<T>::begin(polygon_set); - } - - static inline iterator_type end(const T& polygon_set) { - return get_iterator_type<T>::end(polygon_set); - } - - static inline bool clean(const T& ) { return false; } - - static inline bool sorted(const T& ) { return false; } - }; - - template <typename T> - struct is_45_polygonal_concept { typedef gtl_no type; }; - template <> - struct is_45_polygonal_concept<polygon_45_concept> { typedef gtl_yes type; }; - template <> - struct is_45_polygonal_concept<polygon_45_with_holes_concept> { typedef gtl_yes type; }; - template <> - struct is_45_polygonal_concept<polygon_45_set_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_polygon_45_set_type { - typedef typename is_45_polygonal_concept<typename geometry_concept<T>::type>::type type; - }; - template <typename T> - struct is_polygon_45_set_type<std::list<T> > { - typedef typename gtl_or< - typename is_45_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type, - typename is_45_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; - }; - template <typename T> - struct is_polygon_45_set_type<std::vector<T> > { - typedef typename gtl_or< - typename is_45_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type, - typename is_45_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; - }; - - template <typename T> - struct is_mutable_polygon_45_set_type { - typedef typename gtl_same_type<polygon_45_set_concept, typename geometry_concept<T>::type>::type type; - }; - template <typename T> - struct is_mutable_polygon_45_set_type<std::list<T> > { - typedef typename gtl_or< - typename gtl_same_type<polygon_45_set_concept, typename geometry_concept<std::list<T> >::type>::type, - typename is_45_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; - }; - template <typename T> - struct is_mutable_polygon_45_set_type<std::vector<T> > { - typedef typename gtl_or< - typename gtl_same_type<polygon_45_set_concept, typename geometry_concept<std::vector<T> >::type>::type, - typename is_45_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; - }; - - template <typename T> - bool fracture_holes_45_by_concept() { return false; } - template <> - inline bool fracture_holes_45_by_concept<polygon_45_concept>() { return true; } - - template <typename T, typename iT> - void get_45_polygons_T(T& t, iT begin, iT end) { - typedef typename polygon_45_set_traits<T>::coordinate_type Unit; - typedef typename geometry_concept<typename T::value_type>::type CType; - typename polygon_45_formation<Unit>::Polygon45Formation pf(fracture_holes_45_by_concept<CType>()); - //std::cout << "FORMING POLYGONS\n"; - pf.scan(t, begin, end); - } - - template <typename T> - struct polygon_45_set_mutable_traits {}; - template <typename T> - struct polygon_45_set_mutable_traits<std::list<T> > { - template <typename input_iterator_type> - static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) { - polygon_set.clear(); - polygon_45_set_data<typename polygon_45_set_traits<std::list<T> >::coordinate_type> ps; - ps.reserve(std::distance(input_begin, input_end)); - ps.insert(input_begin, input_end); - ps.sort(); - ps.clean(); - get_45_polygons_T(polygon_set, ps.begin(), ps.end()); - } - }; - template <typename T> - struct polygon_45_set_mutable_traits<std::vector<T> > { - template <typename input_iterator_type> - static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) { - polygon_set.clear(); - size_t num_ele = std::distance(input_begin, input_end); - polygon_set.reserve(num_ele); - polygon_45_set_data<typename polygon_45_set_traits<std::list<T> >::coordinate_type> ps; - ps.reserve(num_ele); - ps.insert(input_begin, input_end); - ps.sort(); - ps.clean(); - get_45_polygons_T(polygon_set, ps.begin(), ps.end()); - } - }; - - template <typename T> - struct polygon_45_set_mutable_traits<polygon_45_set_data<T> > { - template <typename input_iterator_type> - static inline void set(polygon_45_set_data<T>& polygon_set, - input_iterator_type input_begin, input_iterator_type input_end) { - polygon_set.set(input_begin, input_end); - } - }; - template <typename T> - struct polygon_45_set_traits<polygon_45_set_data<T> > { - typedef typename polygon_45_set_data<T>::coordinate_type coordinate_type; - typedef typename polygon_45_set_data<T>::iterator_type iterator_type; - typedef typename polygon_45_set_data<T>::operator_arg_type operator_arg_type; - - static inline iterator_type begin(const polygon_45_set_data<T>& polygon_set) { - return polygon_set.begin(); - } - - static inline iterator_type end(const polygon_45_set_data<T>& polygon_set) { - return polygon_set.end(); - } - - static inline bool clean(const polygon_45_set_data<T>& polygon_set) { polygon_set.clean(); return true; } - - static inline bool sorted(const polygon_45_set_data<T>& polygon_set) { polygon_set.sort(); return true; } - - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_45_with_holes_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_45_with_holes_data.hpp deleted file mode 100644 index 0601bdc406..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_45_with_holes_data.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - 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_POLYGON_45_WITH_HOLES_DATA_HPP -#define BOOST_POLYGON_POLYGON_45_WITH_HOLES_DATA_HPP -#include "isotropy.hpp" -#include "polygon_45_data.hpp" -namespace boost { namespace polygon{ -struct polygon_45_with_holes_concept; -template <typename T> -class polygon_45_with_holes_data { -public: - typedef polygon_45_with_holes_concept geometry_type; - typedef T coordinate_type; - typedef typename polygon_45_data<T>::iterator_type iterator_type; - typedef typename std::list<polygon_45_data<coordinate_type> >::const_iterator iterator_holes_type; - typedef polygon_45_data<coordinate_type> hole_type; - typedef typename coordinate_traits<T>::coordinate_distance area_type; - typedef point_data<T> point_type; - - // default constructor of point does not initialize x and y - inline polygon_45_with_holes_data() : self_(), holes_() {} //do nothing default constructor - - template<class iT> - inline polygon_45_with_holes_data(iT input_begin, iT input_end) : self_(), holes_() { - set(input_begin, input_end); - } - - template<class iT, typename hiT> - inline polygon_45_with_holes_data(iT input_begin, iT input_end, hiT holes_begin, hiT holes_end) : self_(), holes_() { - set(input_begin, input_end); - set_holes(holes_begin, holes_end); - } - - template<class iT> - inline polygon_45_with_holes_data& set(iT input_begin, iT input_end) { - self_.set(input_begin, input_end); - return *this; - } - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline polygon_45_with_holes_data& set_holes(iT input_begin, iT input_end) { - holes_.clear(); //just in case there was some old data there - for( ; input_begin != input_end; ++ input_begin) { - holes_.push_back(hole_type()); - holes_.back().set((*input_begin).begin(), (*input_begin).end()); - } - return *this; - } - - // copy constructor (since we have dynamic memory) - inline polygon_45_with_holes_data(const polygon_45_with_holes_data& that) : self_(that.self_), - holes_(that.holes_) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline polygon_45_with_holes_data& operator=(const polygon_45_with_holes_data& that) { - self_ = that.self_; - holes_ = that.holes_; - return *this; - } - - template <typename T2> - inline polygon_45_with_holes_data& operator=(const T2& rvalue); - - // get begin iterator, returns a pointer to a const coordinate_type - inline const iterator_type begin() const { - return self_.begin(); - } - - // get end iterator, returns a pointer to a const coordinate_type - inline const iterator_type end() const { - return self_.end(); - } - - inline std::size_t size() const { - return self_.size(); - } - - // get begin iterator, returns a pointer to a const polygon - inline const iterator_holes_type begin_holes() const { - return holes_.begin(); - } - - // get end iterator, returns a pointer to a const polygon - inline const iterator_holes_type end_holes() const { - return holes_.end(); - } - - inline std::size_t size_holes() const { - return holes_.size(); - } - -public: - polygon_45_data<coordinate_type> self_; - std::list<hole_type> holes_; -}; - - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_90_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_90_data.hpp deleted file mode 100644 index 1f14ed72a6..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_90_data.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - 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_POLYGON_90_DATA_HPP -#define BOOST_POLYGON_POLYGON_90_DATA_HPP -namespace boost { namespace polygon{ -struct polygon_90_concept; -template <typename T> -class polygon_90_data { -public: - typedef polygon_90_concept geometry_type; - typedef T coordinate_type; - typedef typename std::vector<coordinate_type>::const_iterator compact_iterator_type; - typedef iterator_compact_to_points<compact_iterator_type, point_data<coordinate_type> > iterator_type; - typedef typename coordinate_traits<T>::area_type area_type; - - inline polygon_90_data() : coords_() {} //do nothing default constructor - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline polygon_90_data& set(iT begin_point, iT end_point) { - return set_compact(iterator_points_to_compact<iT, typename std::iterator_traits<iT>::value_type>(begin_point, end_point), - iterator_points_to_compact<iT, typename std::iterator_traits<iT>::value_type>(end_point, end_point)); - } - - template<class iT> - inline polygon_90_data& set_compact(iT input_begin, iT input_end) { - coords_.clear(); //just in case there was some old data there - while(input_begin != input_end) { - coords_.insert(coords_.end(), *input_begin); - ++input_begin; - } - return *this; - } - - // copy constructor (since we have dynamic memory) - inline polygon_90_data(const polygon_90_data& that) : coords_(that.coords_) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline polygon_90_data& operator=(const polygon_90_data& that) { - coords_ = that.coords_; - return *this; - } - - template <typename T2> - inline polygon_90_data& operator=(const T2& rvalue); - - // assignment operator (since we have dynamic memory do a deep copy) - inline bool operator==(const polygon_90_data& that) const { - return coords_ == that.coords_; - } - - // get begin iterator, returns a pointer to a const Unit - inline iterator_type begin() const { return iterator_type(coords_.begin(), coords_.end()); } - - // get end iterator, returns a pointer to a const Unit - inline iterator_type end() const { return iterator_type(coords_.end(), coords_.end()); } - - // get begin iterator, returns a pointer to a const Unit - inline compact_iterator_type begin_compact() const { return coords_.begin(); } - - // get end iterator, returns a pointer to a const Unit - inline compact_iterator_type end_compact() const { return coords_.end(); } - - inline std::size_t size() const { return coords_.size(); } - -private: - std::vector<coordinate_type> coords_; -}; - - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_90_set_concept.hpp b/contrib/restricted/boost/boost/polygon/polygon_90_set_concept.hpp deleted file mode 100644 index 5259a079c9..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_90_set_concept.hpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - 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_POLYGON_90_SET_CONCEPT_HPP -#define BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP -#include "polygon_90_set_data.hpp" -#include "polygon_90_set_traits.hpp" -namespace boost { namespace polygon{ - - template <typename polygon_set_type> - typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, - typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type - begin_90_set_data(const polygon_set_type& polygon_set) { - return polygon_90_set_traits<polygon_set_type>::begin(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, - typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type - end_90_set_data(const polygon_set_type& polygon_set) { - return polygon_90_set_traits<polygon_set_type>::end(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, - orientation_2d>::type - scanline_orientation(const polygon_set_type& polygon_set) { - return polygon_90_set_traits<polygon_set_type>::orient(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, - bool>::type - clean(const polygon_set_type& polygon_set) { - return polygon_90_set_traits<polygon_set_type>::clean(polygon_set); - } - - //assign - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if < - typename gtl_and< - typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type, - typename is_polygon_90_set_type<polygon_set_type_2>::type>::type, - polygon_set_type_1>::type & - assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { - polygon_90_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_90_set_data(rvalue), end_90_set_data(rvalue), - scanline_orientation(rvalue)); - return lvalue; - } - - template <typename T1, typename T2> - struct are_not_both_rectangle_concept { typedef gtl_yes type; }; - template <> - struct are_not_both_rectangle_concept<rectangle_concept, rectangle_concept> { typedef gtl_no type; }; - - //equivalence - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3< - typename is_polygon_90_set_type<polygon_set_type_1>::type, - typename is_polygon_90_set_type<polygon_set_type_2>::type, - typename are_not_both_rectangle_concept<typename geometry_concept<polygon_set_type_1>::type, - typename geometry_concept<polygon_set_type_2>::type>::type>::type, - bool>::type - equivalence(const polygon_set_type_1& lvalue, - const polygon_set_type_2& rvalue) { - polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type> ps1; - assign(ps1, lvalue); - polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_2>::coordinate_type> ps2; - assign(ps2, rvalue); - return ps1 == ps2; - } - - - //get rectangle tiles (slicing orientation is vertical) - template <typename output_container_type, typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type, - void>::type - get_rectangles(output_container_type& output, const polygon_set_type& polygon_set) { - clean(polygon_set); - polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(VERTICAL); - assign(ps, polygon_set); - ps.get_rectangles(output); - } - - //get rectangle tiles - template <typename output_container_type, typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type, - void>::type - get_rectangles(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) { - clean(polygon_set); - polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.get_rectangles(output, slicing_orientation); - } - - //get: min_rectangles max_rectangles - template <typename output_container_type, typename polygon_set_type> - typename enable_if <typename gtl_and< - typename is_polygon_90_set_type<polygon_set_type>::type, - typename gtl_same_type<rectangle_concept, - typename geometry_concept - <typename std::iterator_traits - <typename output_container_type::iterator>::value_type>::type>::type>::type, - void>::type - get_max_rectangles(output_container_type& output, const polygon_set_type& polygon_set) { - std::vector<rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> > rects; - assign(rects, polygon_set); - MaxCover<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::getMaxCover(output, rects, scanline_orientation(polygon_set)); - } - - //clear - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - void>::type - clear(polygon_set_type& polygon_set) { - polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(scanline_orientation(polygon_set)); - assign(polygon_set, ps); - } - - //empty - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - bool>::type - empty(const polygon_set_type& polygon_set) { - if(clean(polygon_set)) return begin_90_set_data(polygon_set) == end_90_set_data(polygon_set); - polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.clean(); - return ps.empty(); - } - - //extents - template <typename polygon_set_type, typename rectangle_type> - typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - bool>::type - extents(rectangle_type& extents_rectangle, - const polygon_set_type& polygon_set) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - return ps.extents(extents_rectangle); - } - - //area - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type>::type - area(const polygon_set_type& polygon_set) { - typedef rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> rectangle_type; - typedef typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type area_type; - std::vector<rectangle_type> rects; - assign(rects, polygon_set); - area_type retval = (area_type)0; - for(std::size_t i = 0; i < rects.size(); ++i) { - retval += (area_type)area(rects[i]); - } - return retval; - } - - //interact - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type, - typename is_mutable_polygon_90_set_type<polygon_set_type_2>::type>::type, - polygon_set_type_1>::type& - interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { - typedef typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type Unit; - polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set_2)); - polygon_90_set_data<Unit> ps2(ps); - ps.insert(polygon_set_1); - ps2.insert(polygon_set_2); - ps.interact(ps2); - assign(polygon_set_1, ps); - return polygon_set_1; - } - - //self_intersect - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - self_intersect(polygon_set_type& polygon_set) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.self_intersect(); - assign(polygon_set, ps); - return polygon_set; - } - - //self_xor - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - self_xor(polygon_set_type& polygon_set) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.self_xor(); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - return bloat(polygon_set, bloating, bloating, bloating, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, orientation_2d orient, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - if(orient == orientation_2d(HORIZONTAL)) - return bloat(polygon_set, bloating, bloating, 0, 0); - return bloat(polygon_set, 0, 0, bloating, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, orientation_2d orient, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) { - if(orient == orientation_2d(HORIZONTAL)) - return bloat(polygon_set, low_bloating, high_bloating, 0, 0); - return bloat(polygon_set, 0, 0, low_bloating, high_bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, direction_2d dir, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - if(dir == direction_2d(EAST)) - return bloat(polygon_set, 0, bloating, 0, 0); - if(dir == direction_2d(WEST)) - return bloat(polygon_set, bloating, 0, 0, 0); - if(dir == direction_2d(SOUTH)) - return bloat(polygon_set, 0, 0, bloating, 0); - return bloat(polygon_set, 0, 0, 0, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.bloat(west_bloating, east_bloating, south_bloating, north_bloating); - ps.clean(); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { - return shrink(polygon_set, shrinking, shrinking, shrinking, shrinking); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, orientation_2d orient, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { - if(orient == orientation_2d(HORIZONTAL)) - return shrink(polygon_set, shrinking, shrinking, 0, 0); - return shrink(polygon_set, 0, 0, shrinking, shrinking); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, orientation_2d orient, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_shrinking, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_shrinking) { - if(orient == orientation_2d(HORIZONTAL)) - return shrink(polygon_set, low_shrinking, high_shrinking, 0, 0); - return shrink(polygon_set, 0, 0, low_shrinking, high_shrinking); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, direction_2d dir, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { - if(dir == direction_2d(EAST)) - return shrink(polygon_set, 0, shrinking, 0, 0); - if(dir == direction_2d(WEST)) - return shrink(polygon_set, shrinking, 0, 0, 0); - if(dir == direction_2d(SOUTH)) - return shrink(polygon_set, 0, 0, shrinking, 0); - return shrink(polygon_set, 0, 0, 0, shrinking); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_shrinking, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_shrinking, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_shrinking, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_shrinking) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.shrink(west_shrinking, east_shrinking, south_shrinking, north_shrinking); - ps.clean(); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type, typename coord_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - resize(polygon_set_type& polygon_set, coord_type resizing) { - if(resizing > 0) { - return bloat(polygon_set, resizing); - } - if(resizing < 0) { - return shrink(polygon_set, -resizing); - } - return polygon_set; - } - - //positive or negative values allow for any and all directions of sizing - template <typename polygon_set_type, typename coord_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - resize(polygon_set_type& polygon_set, coord_type west, coord_type east, coord_type south, coord_type north) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.resize(west, east, south, north); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - grow_and(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - return grow_and(polygon_set, bloating, bloating, bloating, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - grow_and(polygon_set_type& polygon_set, orientation_2d orient, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - if(orient == orientation_2d(HORIZONTAL)) - return grow_and(polygon_set, bloating, bloating, 0, 0); - return grow_and(polygon_set, 0, 0, bloating, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - grow_and(polygon_set_type& polygon_set, orientation_2d orient, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) { - if(orient == orientation_2d(HORIZONTAL)) - return grow_and(polygon_set, low_bloating, high_bloating, 0, 0); - return grow_and(polygon_set, 0, 0, low_bloating, high_bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - grow_and(polygon_set_type& polygon_set, direction_2d dir, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - if(dir == direction_2d(EAST)) - return grow_and(polygon_set, 0, bloating, 0, 0); - if(dir == direction_2d(WEST)) - return grow_and(polygon_set, bloating, 0, 0, 0); - if(dir == direction_2d(SOUTH)) - return grow_and(polygon_set, 0, 0, bloating, 0); - return grow_and(polygon_set, 0, 0, 0, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type, - polygon_set_type>::type & - grow_and(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - std::vector<polygon_90_data<Unit> > polys; - assign(polys, polygon_set); - clear(polygon_set); - polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set)); - for(std::size_t i = 0; i < polys.size(); ++i) { - polygon_90_set_data<Unit> tmpPs(scanline_orientation(polygon_set)); - tmpPs.insert(polys[i]); - bloat(tmpPs, west_bloating, east_bloating, south_bloating, north_bloating); - tmpPs.clean(); //apply implicit OR on tmp polygon set - ps.insert(tmpPs); - } - self_intersect(ps); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale_up(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> - ::unsigned_area_type factor) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale_up(factor); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale_down(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> - ::unsigned_area_type factor) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale_down(factor); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type, typename scaling_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale(polygon_set_type& polygon_set, - const scaling_type& scaling) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale(scaling); - assign(polygon_set, ps); - return polygon_set; - } - - struct y_p_s_move : gtl_yes {}; - - //move - template <typename polygon_set_type> - typename enable_if< typename gtl_and<y_p_s_move, typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type>::type, - polygon_set_type>::type & - move(polygon_set_type& polygon_set, - orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement) { - if(orient == HORIZONTAL) - return move(polygon_set, displacement, 0); - else - return move(polygon_set, 0, displacement); - } - - struct y_p_s_move2 : gtl_yes {}; - - template <typename polygon_set_type> - typename enable_if< typename gtl_and<y_p_s_move2, typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type>::type, - polygon_set_type>::type & - move(polygon_set_type& polygon_set, typename polygon_90_set_traits<polygon_set_type>::coordinate_type x_displacement, - typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.move(x_displacement, y_displacement); - ps.clean(); - assign(polygon_set, ps); - return polygon_set; - } - - //transform - template <typename polygon_set_type, typename transformation_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - transform(polygon_set_type& polygon_set, - const transformation_type& transformation) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - polygon_90_set_data<Unit> ps; - assign(ps, polygon_set); - ps.transform(transformation); - ps.clean(); - assign(polygon_set, ps); - return polygon_set; - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - } - - //keep - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, - polygon_set_type>::type & - keep(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_area, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_area, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height, - typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; - typedef typename coordinate_traits<Unit>::unsigned_area_type uat; - std::list<polygon_90_data<Unit> > polys; - assign(polys, polygon_set); - clear(polygon_set); - typename std::list<polygon_90_data<Unit> >::iterator itr_nxt; - for(typename std::list<polygon_90_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ - itr_nxt = itr; - ++itr_nxt; - rectangle_data<Unit> bbox; - extents(bbox, *itr); - uat pwidth = delta(bbox, HORIZONTAL); - if(pwidth > min_width && pwidth <= max_width){ - uat pheight = delta(bbox, VERTICAL); - if(pheight > min_height && pheight <= max_height){ - uat parea = area(*itr); - if(parea <= max_area && parea >= min_area) { - continue; - } - } - } - polys.erase(itr); - } - assign(polygon_set, polys); - return polygon_set; - } - - -} -} -#include "detail/polygon_90_set_view.hpp" -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_90_set_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_90_set_data.hpp deleted file mode 100644 index 2c640bf1ae..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_90_set_data.hpp +++ /dev/null @@ -1,989 +0,0 @@ -/* - 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_POLYGON_90_SET_DATA_HPP -#define BOOST_POLYGON_POLYGON_90_SET_DATA_HPP -#include "isotropy.hpp" -#include "point_concept.hpp" -#include "transform.hpp" -#include "interval_concept.hpp" -#include "rectangle_concept.hpp" -#include "segment_concept.hpp" -#include "detail/iterator_points_to_compact.hpp" -#include "detail/iterator_compact_to_points.hpp" -#include "polygon_traits.hpp" - -//manhattan boolean algorithms -#include "detail/boolean_op.hpp" -#include "detail/polygon_formation.hpp" -#include "detail/rectangle_formation.hpp" -#include "detail/max_cover.hpp" -#include "detail/property_merge.hpp" -#include "detail/polygon_90_touch.hpp" -#include "detail/iterator_geometry_to_set.hpp" - -namespace boost { namespace polygon{ - template <typename ltype, typename rtype, typename op_type> - class polygon_90_set_view; - - template <typename T> - class polygon_90_set_data { - public: - typedef T coordinate_type; - typedef std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > > value_type; - typedef typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::const_iterator iterator_type; - typedef polygon_90_set_data operator_arg_type; - - // default constructor - inline polygon_90_set_data() : orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) {} - - // constructor - inline polygon_90_set_data(orientation_2d orient) : orient_(orient), data_(), dirty_(false), unsorted_(false) {} - - // constructor from an iterator pair over vertex data - template <typename iT> - inline polygon_90_set_data(orientation_2d, iT input_begin, iT input_end) : - orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) { - dirty_ = true; - unsorted_ = true; - for( ; input_begin != input_end; ++input_begin) { insert(*input_begin); } - } - - // copy constructor - inline polygon_90_set_data(const polygon_90_set_data& that) : - orient_(that.orient_), data_(that.data_), dirty_(that.dirty_), unsorted_(that.unsorted_) {} - - template <typename ltype, typename rtype, typename op_type> - inline polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that); - - // copy with orientation change constructor - inline polygon_90_set_data(orientation_2d orient, const polygon_90_set_data& that) : - orient_(orient), data_(), dirty_(false), unsorted_(false) { - insert(that, false, that.orient_); - } - - // destructor - inline ~polygon_90_set_data() {} - - // assignement operator - inline polygon_90_set_data& operator=(const polygon_90_set_data& that) { - if(this == &that) return *this; - orient_ = that.orient_; - data_ = that.data_; - dirty_ = that.dirty_; - unsorted_ = that.unsorted_; - return *this; - } - - template <typename ltype, typename rtype, typename op_type> - inline polygon_90_set_data& operator=(const polygon_90_set_view<ltype, rtype, op_type>& that); - - template <typename geometry_object> - inline polygon_90_set_data& operator=(const geometry_object& geometry) { - data_.clear(); - insert(geometry); - return *this; - } - - // insert iterator range - inline void insert(iterator_type input_begin, iterator_type input_end, orientation_2d orient = HORIZONTAL) { - if(input_begin == input_end || (!data_.empty() && &(*input_begin) == &(*(data_.begin())))) return; - dirty_ = true; - unsorted_ = true; - if(orient == orient_) - data_.insert(data_.end(), input_begin, input_end); - else { - for( ; input_begin != input_end; ++input_begin) { - insert(*input_begin, false, orient); - } - } - } - - // insert iterator range - template <typename iT> - inline void insert(iT input_begin, iT input_end, orientation_2d orient = HORIZONTAL) { - if(input_begin == input_end) return; - dirty_ = true; - unsorted_ = true; - for( ; input_begin != input_end; ++input_begin) { - insert(*input_begin, false, orient); - } - } - - inline void insert(const polygon_90_set_data& polygon_set) { - insert(polygon_set.begin(), polygon_set.end(), polygon_set.orient()); - } - - inline void insert(const std::pair<std::pair<point_data<coordinate_type>, point_data<coordinate_type> >, int>& edge, bool is_hole = false, - orientation_2d = HORIZONTAL) { - std::pair<coordinate_type, std::pair<coordinate_type, int> > vertex; - vertex.first = edge.first.first.x(); - vertex.second.first = edge.first.first.y(); - vertex.second.second = edge.second * (is_hole ? -1 : 1); - insert(vertex, false, VERTICAL); - vertex.first = edge.first.second.x(); - vertex.second.first = edge.first.second.y(); - vertex.second.second *= -1; - insert(vertex, false, VERTICAL); - } - - template <typename geometry_type> - inline void insert(const geometry_type& geometry_object, bool is_hole = false, orientation_2d = HORIZONTAL) { - iterator_geometry_to_set<typename geometry_concept<geometry_type>::type, geometry_type> - begin_input(geometry_object, LOW, orient_, is_hole), end_input(geometry_object, HIGH, orient_, is_hole); - insert(begin_input, end_input, orient_); - } - - inline void insert(const std::pair<coordinate_type, std::pair<coordinate_type, int> >& vertex, bool is_hole = false, - orientation_2d orient = HORIZONTAL) { - data_.push_back(vertex); - if(orient != orient_) std::swap(data_.back().first, data_.back().second.first); - if(is_hole) data_.back().second.second *= -1; - dirty_ = true; - unsorted_ = true; - } - - inline void insert(coordinate_type major_coordinate, const std::pair<interval_data<coordinate_type>, int>& edge) { - std::pair<coordinate_type, std::pair<coordinate_type, int> > vertex; - vertex.first = major_coordinate; - vertex.second.first = edge.first.get(LOW); - vertex.second.second = edge.second; - insert(vertex, false, orient_); - vertex.second.first = edge.first.get(HIGH); - vertex.second.second *= -1; - insert(vertex, false, orient_); - } - - template <typename output_container> - inline void get(output_container& output) const { - get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type()); - } - - template <typename output_container> - inline void get(output_container& output, size_t vthreshold) const { - get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type(), vthreshold); - } - - - template <typename output_container> - inline void get_polygons(output_container& output) const { - get_dispatch(output, polygon_90_concept()); - } - - template <typename output_container> - inline void get_rectangles(output_container& output) const { - clean(); - form_rectangles(output, data_.begin(), data_.end(), orient_, rectangle_concept()); - } - - template <typename output_container> - inline void get_rectangles(output_container& output, orientation_2d slicing_orientation) const { - if(slicing_orientation == orient_) { - get_rectangles(output); - } else { - polygon_90_set_data<coordinate_type> ps(*this); - ps.transform(axis_transformation(axis_transformation::SWAP_XY)); - output_container result; - ps.get_rectangles(result); - for(typename output_container::iterator itr = result.begin(); itr != result.end(); ++itr) { - ::boost::polygon::transform(*itr, axis_transformation(axis_transformation::SWAP_XY)); - } - output.insert(output.end(), result.begin(), result.end()); - } - } - - // equivalence operator - inline bool operator==(const polygon_90_set_data& p) const { - if(orient_ == p.orient()) { - clean(); - p.clean(); - return data_ == p.data_; - } else { - return false; - } - } - - // inequivalence operator - inline bool operator!=(const polygon_90_set_data& p) const { - return !((*this) == p); - } - - // get iterator to begin vertex data - inline iterator_type begin() const { - return data_.begin(); - } - - // get iterator to end vertex data - inline iterator_type end() const { - return data_.end(); - } - - const value_type& value() const { - return data_; - } - - // clear the contents of the polygon_90_set_data - inline void clear() { data_.clear(); dirty_ = unsorted_ = false; } - - // find out if Polygon set is empty - inline bool empty() const { clean(); return data_.empty(); } - - // get the Polygon set size in vertices - inline std::size_t size() const { clean(); return data_.size(); } - - // get the current Polygon set capacity in vertices - inline std::size_t capacity() const { return data_.capacity(); } - - // reserve size of polygon set in vertices - inline void reserve(std::size_t size) { return data_.reserve(size); } - - // find out if Polygon set is sorted - inline bool sorted() const { return !unsorted_; } - - // find out if Polygon set is clean - inline bool dirty() const { return dirty_; } - - // get the scanline orientation of the polygon set - inline orientation_2d orient() const { return orient_; } - - // Start BM - // The problem: If we have two polygon sets with two different scanline orientations: - // I tried changing the orientation of one to coincide with other (If not, resulting boolean operation - // produces spurious results). - // First I tried copying polygon data from one of the sets into another set with corrected orientation - // using one of the copy constructor that takes in orientation (see somewhere above in this file) --> copy constructor throws error - // Then I tried another approach:(see below). This approach also fails to produce the desired results when test case is run. - // Here is the part that beats me: If I comment out the whole section, I can do all the operations (^=, -=, &= )these commented out - // operations perform. So then why do we need them?. Hence, I commented out this whole section. - // End BM - // polygon_90_set_data<coordinate_type>& operator-=(const polygon_90_set_data& that) { - // sort(); - // that.sort(); - // value_type data; - // std::swap(data, data_); - // applyBooleanBinaryOp(data.begin(), data.end(), - // that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryNot>()); - // return *this; - // } - // polygon_90_set_data<coordinate_type>& operator^=(const polygon_90_set_data& that) { - // sort(); - // that.sort(); - // value_type data; - // std::swap(data, data_); - // applyBooleanBinaryOp(data.begin(), data.end(), - // that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryXor>()); - // return *this; - // } - // polygon_90_set_data<coordinate_type>& operator&=(const polygon_90_set_data& that) { - // sort(); - // that.sort(); - // value_type data; - // std::swap(data, data_); - // applyBooleanBinaryOp(data.begin(), data.end(), - // that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryAnd>()); - // return *this; - // } - // polygon_90_set_data<coordinate_type>& operator|=(const polygon_90_set_data& that) { - // insert(that); - // return *this; - // } - - void clean() const { - sort(); - if(dirty_) { - boolean_op::default_arg_workaround<int>::applyBooleanOr(data_); - dirty_ = false; - } - } - - void sort() const{ - if(unsorted_) { - polygon_sort(data_.begin(), data_.end()); - unsorted_ = false; - } - } - - template <typename input_iterator_type> - void set(input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) { - data_.clear(); - reserve(std::distance(input_begin, input_end)); - data_.insert(data_.end(), input_begin, input_end); - orient_ = orient; - dirty_ = true; - unsorted_ = true; - } - - void set(const value_type& value, orientation_2d orient) { - data_ = value; - orient_ = orient; - dirty_ = true; - unsorted_ = true; - } - - //extents - template <typename rectangle_type> - bool - extents(rectangle_type& extents_rectangle) const { - clean(); - if(data_.empty()) return false; - if(orient_ == HORIZONTAL) - set_points(extents_rectangle, point_data<coordinate_type>(data_[0].second.first, data_[0].first), - point_data<coordinate_type>(data_[data_.size() - 1].second.first, data_[data_.size() - 1].first)); - else - set_points(extents_rectangle, point_data<coordinate_type>(data_[0].first, data_[0].second.first), - point_data<coordinate_type>(data_[data_.size() - 1].first, data_[data_.size() - 1].second.first)); - for(std::size_t i = 1; i < data_.size() - 1; ++i) { - if(orient_ == HORIZONTAL) - encompass(extents_rectangle, point_data<coordinate_type>(data_[i].second.first, data_[i].first)); - else - encompass(extents_rectangle, point_data<coordinate_type>(data_[i].first, data_[i].second.first)); - } - return true; - } - - polygon_90_set_data& - bloat2(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating, - typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating, - typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating, - typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) { - std::vector<rectangle_data<coordinate_type> > rects; - clean(); - rects.reserve(data_.size() / 2); - get(rects); - rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)west_bloating), - (coordinate_type)east_bloating), - interval_data<coordinate_type>(-((coordinate_type)south_bloating), - (coordinate_type)north_bloating)); - for(typename std::vector<rectangle_data<coordinate_type> >::iterator itr = rects.begin(); - itr != rects.end(); ++itr) { - convolve(*itr, convolutionRectangle); - } - clear(); - insert(rects.begin(), rects.end()); - return *this; - } - - static void modify_pt(point_data<coordinate_type>& pt, const point_data<coordinate_type>& prev_pt, - const point_data<coordinate_type>& current_pt, const point_data<coordinate_type>& next_pt, - coordinate_type west_bloating, - coordinate_type east_bloating, - coordinate_type south_bloating, - coordinate_type north_bloating) { - bool pxl = prev_pt.x() < current_pt.x(); - bool pyl = prev_pt.y() < current_pt.y(); - bool nxl = next_pt.x() < current_pt.x(); - bool nyl = next_pt.y() < current_pt.y(); - bool pxg = prev_pt.x() > current_pt.x(); - bool pyg = prev_pt.y() > current_pt.y(); - bool nxg = next_pt.x() > current_pt.x(); - bool nyg = next_pt.y() > current_pt.y(); - //two of the four if statements will execute - if(pxl) - pt.y(current_pt.y() - south_bloating); - if(pxg) - pt.y(current_pt.y() + north_bloating); - if(nxl) - pt.y(current_pt.y() + north_bloating); - if(nxg) - pt.y(current_pt.y() - south_bloating); - if(pyl) - pt.x(current_pt.x() + east_bloating); - if(pyg) - pt.x(current_pt.x() - west_bloating); - if(nyl) - pt.x(current_pt.x() - west_bloating); - if(nyg) - pt.x(current_pt.x() + east_bloating); - } - static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly, - coordinate_type west_bloating, - coordinate_type east_bloating, - coordinate_type south_bloating, - coordinate_type north_bloating) { - point_data<coordinate_type> first_pt = poly[0]; - point_data<coordinate_type> second_pt = poly[1]; - point_data<coordinate_type> prev_pt = poly[0]; - point_data<coordinate_type> current_pt = poly[1]; - for(std::size_t i = 2; i < poly.size(); ++i) { - point_data<coordinate_type> next_pt = poly[i]; - modify_pt(poly[i-1], prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating); - prev_pt = current_pt; - current_pt = next_pt; - } - point_data<coordinate_type> next_pt = first_pt; - modify_pt(poly.back(), prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating); - prev_pt = current_pt; - current_pt = next_pt; - next_pt = second_pt; - modify_pt(poly[0], prev_pt, current_pt, next_pt, west_bloating, east_bloating, south_bloating, north_bloating); - remove_colinear_pts(poly); - } - static bool resize_poly_down(std::vector<point_data<coordinate_type> >& poly, - coordinate_type west_shrinking, - coordinate_type east_shrinking, - coordinate_type south_shrinking, - coordinate_type north_shrinking) { - rectangle_data<coordinate_type> extents_rectangle; - set_points(extents_rectangle, poly[0], poly[0]); - point_data<coordinate_type> first_pt = poly[0]; - point_data<coordinate_type> second_pt = poly[1]; - point_data<coordinate_type> prev_pt = poly[0]; - point_data<coordinate_type> current_pt = poly[1]; - encompass(extents_rectangle, current_pt); - for(std::size_t i = 2; i < poly.size(); ++i) { - point_data<coordinate_type> next_pt = poly[i]; - encompass(extents_rectangle, next_pt); - modify_pt(poly[i-1], prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking); - prev_pt = current_pt; - current_pt = next_pt; - } - if(delta(extents_rectangle, HORIZONTAL) < std::abs(west_shrinking + east_shrinking)) - return false; - if(delta(extents_rectangle, VERTICAL) < std::abs(north_shrinking + south_shrinking)) - return false; - point_data<coordinate_type> next_pt = first_pt; - modify_pt(poly.back(), prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking); - prev_pt = current_pt; - current_pt = next_pt; - next_pt = second_pt; - modify_pt(poly[0], prev_pt, current_pt, next_pt, west_shrinking, east_shrinking, south_shrinking, north_shrinking); - return remove_colinear_pts(poly); - } - - static bool remove_colinear_pts(std::vector<point_data<coordinate_type> >& poly) { - bool found_colinear = true; - while(found_colinear && poly.size() >= 4) { - found_colinear = false; - typename std::vector<point_data<coordinate_type> >::iterator itr = poly.begin(); - itr += poly.size() - 1; //get last element position - typename std::vector<point_data<coordinate_type> >::iterator itr2 = poly.begin(); - typename std::vector<point_data<coordinate_type> >::iterator itr3 = itr2; - ++itr3; - std::size_t count = 0; - for( ; itr3 < poly.end(); ++itr3) { - if(((*itr).x() == (*itr2).x() && (*itr).x() == (*itr3).x()) || - ((*itr).y() == (*itr2).y() && (*itr).y() == (*itr3).y()) ) { - ++count; - found_colinear = true; - } else { - itr = itr2; - ++itr2; - } - *itr2 = *itr3; - } - itr3 = poly.begin(); - if(((*itr).x() == (*itr2).x() && (*itr).x() == (*itr3).x()) || - ((*itr).y() == (*itr2).y() && (*itr).y() == (*itr3).y()) ) { - ++count; - found_colinear = true; - } - poly.erase(poly.end() - count, poly.end()); - } - return poly.size() >= 4; - } - - polygon_90_set_data& - bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type west_bloating, - typename coordinate_traits<coordinate_type>::unsigned_area_type east_bloating, - typename coordinate_traits<coordinate_type>::unsigned_area_type south_bloating, - typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) { - std::list<polygon_45_with_holes_data<coordinate_type> > polys; - get(polys); - clear(); - for(typename std::list<polygon_45_with_holes_data<coordinate_type> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - //polygon_90_set_data<coordinate_type> psref; - //psref.insert(view_as<polygon_90_concept>((*itr).self_)); - //rectangle_data<coordinate_type> prerect; - //psref.extents(prerect); - resize_poly_up((*itr).self_.coords_, (coordinate_type)west_bloating, (coordinate_type)east_bloating, - (coordinate_type)south_bloating, (coordinate_type)north_bloating); - iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - begin_input(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE), - end_input(view_as<polygon_90_concept>((*itr).self_), HIGH, orient_, false, true, COUNTERCLOCKWISE); - insert(begin_input, end_input, orient_); - //polygon_90_set_data<coordinate_type> pstest; - //pstest.insert(view_as<polygon_90_concept>((*itr).self_)); - //psref.bloat2(west_bloating, east_bloating, south_bloating, north_bloating); - //if(!equivalence(psref, pstest)) { - // std::cout << "test failed\n"; - //} - for(typename std::list<polygon_45_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin(); - itrh != (*itr).holes_.end(); ++itrh) { - //rectangle_data<coordinate_type> rect; - //psref.extents(rect); - //polygon_90_set_data<coordinate_type> psrefhole; - //psrefhole.insert(prerect); - //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true); - //polygon_45_data<coordinate_type> testpoly(*itrh); - if(resize_poly_down((*itrh).coords_,(coordinate_type)west_bloating, (coordinate_type)east_bloating, - (coordinate_type)south_bloating, (coordinate_type)north_bloating)) { - iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true), - end_input2(view_as<polygon_90_concept>(*itrh), HIGH, orient_, true, true); - insert(begin_input2, end_input2, orient_); - //polygon_90_set_data<coordinate_type> pstesthole; - //pstesthole.insert(rect); - //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - // begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true); - //pstesthole.insert(begin_input2, end_input, orient_); - //psrefhole.bloat2(west_bloating, east_bloating, south_bloating, north_bloating); - //if(!equivalence(psrefhole, pstesthole)) { - // std::cout << (winding(testpoly) == CLOCKWISE) << std::endl; - // std::cout << (winding(*itrh) == CLOCKWISE) << std::endl; - // polygon_90_set_data<coordinate_type> c(psrefhole); - // c.clean(); - // polygon_90_set_data<coordinate_type> a(pstesthole); - // polygon_90_set_data<coordinate_type> b(pstesthole); - // a.sort(); - // b.clean(); - // std::cout << "test hole failed\n"; - // //std::cout << testpoly << std::endl; - //} - } - } - } - return *this; - } - - polygon_90_set_data& - shrink(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking, - typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking, - typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking, - typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) { - std::list<polygon_45_with_holes_data<coordinate_type> > polys; - get(polys); - clear(); - for(typename std::list<polygon_45_with_holes_data<coordinate_type> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - //polygon_90_set_data<coordinate_type> psref; - //psref.insert(view_as<polygon_90_concept>((*itr).self_)); - //rectangle_data<coordinate_type> prerect; - //psref.extents(prerect); - //polygon_45_data<coordinate_type> testpoly((*itr).self_); - if(resize_poly_down((*itr).self_.coords_, -(coordinate_type)west_shrinking, -(coordinate_type)east_shrinking, - -(coordinate_type)south_shrinking, -(coordinate_type)north_shrinking)) { - iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - begin_input(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE), - end_input(view_as<polygon_90_concept>((*itr).self_), HIGH, orient_, false, true, COUNTERCLOCKWISE); - insert(begin_input, end_input, orient_); - //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - // begin_input2(view_as<polygon_90_concept>((*itr).self_), LOW, orient_, false, true, COUNTERCLOCKWISE); - //polygon_90_set_data<coordinate_type> pstest; - //pstest.insert(begin_input2, end_input, orient_); - //psref.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking); - //if(!equivalence(psref, pstest)) { - // std::cout << "test failed\n"; - //} - for(typename std::list<polygon_45_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin(); - itrh != (*itr).holes_.end(); ++itrh) { - //rectangle_data<coordinate_type> rect; - //psref.extents(rect); - //polygon_90_set_data<coordinate_type> psrefhole; - //psrefhole.insert(prerect); - //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true); - //polygon_45_data<coordinate_type> testpoly(*itrh); - resize_poly_up((*itrh).coords_, -(coordinate_type)west_shrinking, -(coordinate_type)east_shrinking, - -(coordinate_type)south_shrinking, -(coordinate_type)north_shrinking); - iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true), - end_input2(view_as<polygon_90_concept>(*itrh), HIGH, orient_, true, true); - insert(begin_input2, end_input2, orient_); - //polygon_90_set_data<coordinate_type> pstesthole; - //pstesthole.insert(rect); - //iterator_geometry_to_set<polygon_90_concept, view_of<polygon_90_concept, polygon_45_data<coordinate_type> > > - // begin_input2(view_as<polygon_90_concept>(*itrh), LOW, orient_, true, true); - //pstesthole.insert(begin_input2, end_input, orient_); - //psrefhole.shrink2(west_shrinking, east_shrinking, south_shrinking, north_shrinking); - //if(!equivalence(psrefhole, pstesthole)) { - // std::cout << (winding(testpoly) == CLOCKWISE) << std::endl; - // std::cout << (winding(*itrh) == CLOCKWISE) << std::endl; - // polygon_90_set_data<coordinate_type> c(psrefhole); - // c.clean(); - // polygon_90_set_data<coordinate_type> a(pstesthole); - // polygon_90_set_data<coordinate_type> b(pstesthole); - // a.sort(); - // b.clean(); - // std::cout << "test hole failed\n"; - // //std::cout << testpoly << std::endl; - //} - } - } - } - return *this; - } - - polygon_90_set_data& - shrink2(typename coordinate_traits<coordinate_type>::unsigned_area_type west_shrinking, - typename coordinate_traits<coordinate_type>::unsigned_area_type east_shrinking, - typename coordinate_traits<coordinate_type>::unsigned_area_type south_shrinking, - typename coordinate_traits<coordinate_type>::unsigned_area_type north_shrinking) { - rectangle_data<coordinate_type> externalBoundary; - if(!extents(externalBoundary)) return *this; - ::boost::polygon::bloat(externalBoundary, 10); //bloat by diferential ammount - //insert a hole that encompasses the data - insert(externalBoundary, true); //note that the set is in a dirty state now - sort(); //does not apply implicit OR operation - std::vector<rectangle_data<coordinate_type> > rects; - rects.reserve(data_.size() / 2); - //begin does not apply implicit or operation, this is a dirty range - form_rectangles(rects, data_.begin(), data_.end(), orient_, rectangle_concept()); - clear(); - rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)east_shrinking), - (coordinate_type)west_shrinking), - interval_data<coordinate_type>(-((coordinate_type)north_shrinking), - (coordinate_type)south_shrinking)); - for(typename std::vector<rectangle_data<coordinate_type> >::iterator itr = rects.begin(); - itr != rects.end(); ++itr) { - rectangle_data<coordinate_type>& rect = *itr; - convolve(rect, convolutionRectangle); - //insert rectangle as a hole - insert(rect, true); - } - convolve(externalBoundary, convolutionRectangle); - //insert duplicate of external boundary as solid to cancel out the external hole boundaries - insert(externalBoundary); - clean(); //we have negative values in the set, so we need to apply an OR operation to make it valid input to a boolean - return *this; - } - - polygon_90_set_data& - shrink(direction_2d dir, typename coordinate_traits<coordinate_type>::unsigned_area_type shrinking) { - if(dir == WEST) - return shrink(shrinking, 0, 0, 0); - if(dir == EAST) - return shrink(0, shrinking, 0, 0); - if(dir == SOUTH) - return shrink(0, 0, shrinking, 0); - return shrink(0, 0, 0, shrinking); - } - - polygon_90_set_data& - bloat(direction_2d dir, typename coordinate_traits<coordinate_type>::unsigned_area_type shrinking) { - if(dir == WEST) - return bloat(shrinking, 0, 0, 0); - if(dir == EAST) - return bloat(0, shrinking, 0, 0); - if(dir == SOUTH) - return bloat(0, 0, shrinking, 0); - return bloat(0, 0, 0, shrinking); - } - - polygon_90_set_data& - resize(coordinate_type west, coordinate_type east, coordinate_type south, coordinate_type north); - - polygon_90_set_data& move(coordinate_type x_delta, coordinate_type y_delta) { - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - if(orient_ == orientation_2d(VERTICAL)) { - (*itr).first += x_delta; - (*itr).second.first += y_delta; - } else { - (*itr).second.first += x_delta; - (*itr).first += y_delta; - } - } - return *this; - } - - // transform set - template <typename transformation_type> - polygon_90_set_data& transform(const transformation_type& transformation) { - direction_2d dir1, dir2; - transformation.get_directions(dir1, dir2); - int sign = dir1.get_sign() * dir2.get_sign(); - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - if(orient_ == orientation_2d(VERTICAL)) { - transformation.transform((*itr).first, (*itr).second.first); - } else { - transformation.transform((*itr).second.first, (*itr).first); - } - (*itr).second.second *= sign; - } - if(dir1 != EAST || dir2 != NORTH) - unsorted_ = true; //some mirroring or rotation must have happened - return *this; - } - - // scale set - polygon_90_set_data& scale_up(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) { - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - (*itr).first *= (coordinate_type)factor; - (*itr).second.first *= (coordinate_type)factor; - } - return *this; - } - polygon_90_set_data& scale_down(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) { - typedef typename coordinate_traits<coordinate_type>::coordinate_distance dt; - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - (*itr).first = scaling_policy<coordinate_type>::round((dt)((*itr).first) / (dt)factor); - (*itr).second.first = scaling_policy<coordinate_type>::round((dt)((*itr).second.first) / (dt)factor); - } - unsorted_ = true; //scaling down can make coordinates equal that were not previously equal - return *this; - } - template <typename scaling_type> - polygon_90_set_data& scale(const anisotropic_scale_factor<scaling_type>& scaling) { - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - if(orient_ == orientation_2d(VERTICAL)) { - scaling.scale((*itr).first, (*itr).second.first); - } else { - scaling.scale((*itr).second.first, (*itr).first); - } - } - unsorted_ = true; - return *this; - } - template <typename scaling_type> - polygon_90_set_data& scale_with(const scaling_type& scaling) { - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - if(orient_ == orientation_2d(VERTICAL)) { - scaling.scale((*itr).first, (*itr).second.first); - } else { - scaling.scale((*itr).second.first, (*itr).first); - } - } - unsorted_ = true; - return *this; - } - polygon_90_set_data& scale(double factor) { - typedef typename coordinate_traits<coordinate_type>::coordinate_distance dt; - for(typename std::vector<std::pair<coordinate_type, std::pair<coordinate_type, int> > >::iterator - itr = data_.begin(); itr != data_.end(); ++itr) { - (*itr).first = scaling_policy<coordinate_type>::round((dt)((*itr).first) * (dt)factor); - (*itr).second.first = scaling_policy<coordinate_type>::round((dt)((*itr).second.first) * (dt)factor); - } - unsorted_ = true; //scaling make coordinates equal that were not previously equal - return *this; - } - - polygon_90_set_data& self_xor() { - sort(); - if(dirty_) { //if it is clean it is a no-op - boolean_op::default_arg_workaround<boolean_op::UnaryCount>::applyBooleanOr(data_); - dirty_ = false; - } - return *this; - } - - polygon_90_set_data& self_intersect() { - sort(); - if(dirty_) { //if it is clean it is a no-op - interval_data<coordinate_type> ivl((std::numeric_limits<coordinate_type>::min)(), (std::numeric_limits<coordinate_type>::max)()); - rectangle_data<coordinate_type> rect(ivl, ivl); - insert(rect, true); - clean(); - } - return *this; - } - - inline polygon_90_set_data& interact(const polygon_90_set_data& that) { - typedef coordinate_type Unit; - if(that.dirty_) that.clean(); - typename touch_90_operation<Unit>::TouchSetData tsd; - touch_90_operation<Unit>::populateTouchSetData(tsd, that.data_, 0); - std::vector<polygon_90_data<Unit> > polys; - get(polys); - std::vector<std::set<int> > graph(polys.size()+1, std::set<int>()); - for(std::size_t i = 0; i < polys.size(); ++i){ - polygon_90_set_data<Unit> psTmp(that.orient_); - psTmp.insert(polys[i]); - psTmp.clean(); - touch_90_operation<Unit>::populateTouchSetData(tsd, psTmp.data_, i+1); - } - touch_90_operation<Unit>::performTouch(graph, tsd); - clear(); - for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){ - insert(polys[(*itr)-1]); - } - dirty_ = false; - return *this; - } - - - template <class T2, typename iterator_type_1, typename iterator_type_2> - void applyBooleanBinaryOp(iterator_type_1 itr1, iterator_type_1 itr1_end, - iterator_type_2 itr2, iterator_type_2 itr2_end, - T2 defaultCount) { - data_.clear(); - boolean_op::applyBooleanBinaryOp(data_, itr1, itr1_end, itr2, itr2_end, defaultCount); - } - - private: - orientation_2d orient_; - mutable value_type data_; - mutable bool dirty_; - mutable bool unsorted_; - - private: - //functions - template <typename output_container> - void get_dispatch(output_container& output, rectangle_concept ) const { - clean(); - form_rectangles(output, data_.begin(), data_.end(), orient_, rectangle_concept()); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_90_concept tag) const { - get_fracture(output, true, tag); - } - - template <typename output_container> - void get_dispatch(output_container& output, polygon_90_concept tag, - size_t vthreshold) const { - get_fracture(output, true, tag, vthreshold); - } - - template <typename output_container> - void get_dispatch(output_container& output, polygon_90_with_holes_concept tag) const { - get_fracture(output, false, tag); - } - - template <typename output_container> - void get_dispatch(output_container& output, polygon_90_with_holes_concept tag, - size_t vthreshold) const { - get_fracture(output, false, tag, vthreshold); - } - - - template <typename output_container> - void get_dispatch(output_container& output, polygon_45_concept tag) const { - get_fracture(output, true, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_45_with_holes_concept tag) const { - get_fracture(output, false, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_concept tag) const { - get_fracture(output, true, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_with_holes_concept tag) const { - get_fracture(output, false, tag); - } - template <typename output_container, typename concept_type> - void get_fracture(output_container& container, bool fracture_holes, concept_type tag) const { - clean(); - ::boost::polygon::get_polygons(container, data_.begin(), data_.end(), orient_, fracture_holes, tag); - } - - template <typename output_container, typename concept_type> - void get_fracture(output_container& container, bool fracture_holes, concept_type tag, - size_t vthreshold) const { - clean(); - ::boost::polygon::get_polygons(container, data_.begin(), data_.end(), orient_, fracture_holes, tag, vthreshold); - } - }; - - template <typename coordinate_type> - polygon_90_set_data<coordinate_type>& - polygon_90_set_data<coordinate_type>::resize(coordinate_type west, - coordinate_type east, - coordinate_type south, - coordinate_type north) { - move(-west, -south); - coordinate_type e_total = west + east; - coordinate_type n_total = south + north; - if((e_total < 0) ^ (n_total < 0)) { - //different signs - if(e_total < 0) { - shrink(0, -e_total, 0, 0); - if(n_total != 0) - return bloat(0, 0, 0, n_total); - else - return (*this); - } else { - shrink(0, 0, 0, -n_total); //shrink first - if(e_total != 0) - return bloat(0, e_total, 0, 0); - else - return (*this); - } - } else { - if(e_total < 0) { - return shrink(0, -e_total, 0, -n_total); - } - return bloat(0, e_total, 0, n_total); - } - } - - template <typename coordinate_type, typename property_type> - class property_merge_90 { - private: - std::vector<std::pair<property_merge_point<coordinate_type>, std::pair<property_type, int> > > pmd_; - public: - inline property_merge_90() : pmd_() {} - inline property_merge_90(const property_merge_90& that) : pmd_(that.pmd_) {} - inline property_merge_90& operator=(const property_merge_90& that) { pmd_ = that.pmd_; return *this; } - inline void insert(const polygon_90_set_data<coordinate_type>& ps, const property_type& property) { - merge_scanline<coordinate_type, property_type, polygon_90_set_data<coordinate_type> >:: - populate_property_merge_data(pmd_, ps.begin(), ps.end(), property, ps.orient()); - } - template <class GeoObjT> - inline void insert(const GeoObjT& geoObj, const property_type& property) { - polygon_90_set_data<coordinate_type> ps; - ps.insert(geoObj); - insert(ps, property); - } - //merge properties of input geometries and store the resulting geometries of regions - //with unique sets of merged properties to polygons sets in a map keyed by sets of properties - // T = std::map<std::set<property_type>, polygon_90_set_data<coordiante_type> > or - // T = std::map<std::vector<property_type>, polygon_90_set_data<coordiante_type> > - template <typename ResultType> - inline void merge(ResultType& result) { - merge_scanline<coordinate_type, property_type, polygon_90_set_data<coordinate_type>, typename ResultType::key_type> ms; - ms.perform_merge(result, pmd_); - } - }; - - //ConnectivityExtraction computes the graph of connectivity between rectangle, polygon and - //polygon set graph nodes where an edge is created whenever the geometry in two nodes overlap - template <typename coordinate_type> - class connectivity_extraction_90 { - private: - typedef typename touch_90_operation<coordinate_type>::TouchSetData tsd; - tsd tsd_; - unsigned int nodeCount_; - public: - inline connectivity_extraction_90() : tsd_(), nodeCount_(0) {} - inline connectivity_extraction_90(const connectivity_extraction_90& that) : tsd_(that.tsd_), - nodeCount_(that.nodeCount_) {} - inline connectivity_extraction_90& operator=(const connectivity_extraction_90& that) { - tsd_ = that.tsd_; - nodeCount_ = that.nodeCount_; {} - return *this; - } - - //insert a polygon set graph node, the value returned is the id of the graph node - inline unsigned int insert(const polygon_90_set_data<coordinate_type>& ps) { - ps.clean(); - touch_90_operation<coordinate_type>::populateTouchSetData(tsd_, ps.begin(), ps.end(), nodeCount_); - return nodeCount_++; - } - template <class GeoObjT> - inline unsigned int insert(const GeoObjT& geoObj) { - polygon_90_set_data<coordinate_type> ps; - ps.insert(geoObj); - return insert(ps); - } - - //extract connectivity and store the edges in the graph - //graph must be indexable by graph node id and the indexed value must be a std::set of - //graph node id - template <class GraphT> - inline void extract(GraphT& graph) { - touch_90_operation<coordinate_type>::performTouch(graph, tsd_); - } - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_90_set_traits.hpp b/contrib/restricted/boost/boost/polygon/polygon_90_set_traits.hpp deleted file mode 100644 index c1312e8856..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_90_set_traits.hpp +++ /dev/null @@ -1,366 +0,0 @@ -/* - 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_POLYGON_90_SET_TRAITS_HPP -#define BOOST_POLYGON_POLYGON_90_SET_TRAITS_HPP -namespace boost { namespace polygon{ - - struct polygon_90_set_concept {}; - - template <typename T, typename T2> - struct traits_by_concept {}; - template <typename T> - struct traits_by_concept<T, coordinate_concept> { typedef coordinate_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, interval_concept> { typedef interval_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, point_concept> { typedef point_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, rectangle_concept> { typedef rectangle_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, segment_concept> { typedef segment_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_90_concept> { typedef polygon_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_90_with_holes_concept> { typedef polygon_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_45_concept> { typedef polygon_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_45_with_holes_concept> { typedef polygon_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_concept> { typedef polygon_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_with_holes_concept> { typedef polygon_traits<T> type; }; - - struct polygon_45_set_concept; - struct polygon_set_concept; - template <typename T> - struct polygon_90_set_traits; - template <typename T> - struct polygon_45_set_traits; - template <typename T> - struct polygon_set_traits; - template <typename T> - struct traits_by_concept<T, polygon_90_set_concept> { typedef polygon_90_set_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_45_set_concept> { typedef polygon_45_set_traits<T> type; }; - template <typename T> - struct traits_by_concept<T, polygon_set_concept> { typedef polygon_set_traits<T> type; }; - - template <typename T, typename T2> - struct get_coordinate_type { - typedef typename traits_by_concept<T, T2>::type traits_type; - typedef typename traits_type::coordinate_type type; - }; - //want to prevent recursive template definition syntax errors, so duplicate get_coordinate_type - template <typename T, typename T2> - struct get_coordinate_type_2 { - typedef typename traits_by_concept<T, T2>::type traits_type; - typedef typename traits_type::coordinate_type type; - }; - template <typename T> - struct get_coordinate_type<T, undefined_concept> { - typedef typename get_coordinate_type_2<typename std::iterator_traits - <typename T::iterator>::value_type, - typename geometry_concept<typename std::iterator_traits - <typename T::iterator>::value_type>::type>::type type; }; - - template <typename T, typename T2> - struct get_iterator_type_2 { - typedef const T* type; - static type begin(const T& t) { return &t; } - static type end(const T& t) { const T* tp = &t; ++tp; return tp; } - }; - template <typename T> - struct get_iterator_type { - typedef get_iterator_type_2<T, typename geometry_concept<T>::type> indirect_type; - typedef typename indirect_type::type type; - static type begin(const T& t) { return indirect_type::begin(t); } - static type end(const T& t) { return indirect_type::end(t); } - }; - template <typename T> - struct get_iterator_type_2<T, undefined_concept> { - typedef typename T::const_iterator type; - static type begin(const T& t) { return t.begin(); } - static type end(const T& t) { return t.end(); } - }; - -// //helpers for allowing polygon 45 and containers of polygon 45 to behave interchangably in polygon_45_set_traits -// template <typename T, typename T2> -// struct get_coordinate_type_45 {}; -// template <typename T, typename T2> -// struct get_coordinate_type_2_45 {}; -// template <typename T> -// struct get_coordinate_type_45<T, void> { -// typedef typename get_coordinate_type_2_45< typename T::value_type, typename geometry_concept<typename T::value_type>::type >::type type; }; -// template <typename T> -// struct get_coordinate_type_45<T, polygon_45_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; -// template <typename T> -// struct get_coordinate_type_45<T, polygon_45_with_holes_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; -// template <typename T> -// struct get_coordinate_type_2_45<T, polygon_45_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; -// template <typename T> -// struct get_coordinate_type_2_45<T, polygon_45_with_holes_concept> { typedef typename polygon_traits<T>::coordinate_type type; }; -// template <typename T, typename T2> -// struct get_iterator_type_45 {}; -// template <typename T> -// struct get_iterator_type_45<T, void> { -// typedef typename T::const_iterator type; -// static type begin(const T& t) { return t.begin(); } -// static type end(const T& t) { return t.end(); } -// }; -// template <typename T> -// struct get_iterator_type_45<T, polygon_45_concept> { -// typedef const T* type; -// static type begin(const T& t) { return &t; } -// static type end(const T& t) { const T* tp = &t; ++tp; return tp; } -// }; -// template <typename T> -// struct get_iterator_type_45<T, polygon_45_with_holes_concept> { -// typedef const T* type; -// static type begin(const T& t) { return &t; } -// static type end(const T& t) { const T* tp = &t; ++tp; return tp; } -// }; -// template <typename T> -// struct get_iterator_type_45<T, polygon_90_set_concept> { -// typedef const T* type; -// static type begin(const T& t) { return &t; } -// static type end(const T& t) { const T* tp = &t; ++tp; return tp; } -// }; - - template <typename T> - struct polygon_90_set_traits { - typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; - typedef get_iterator_type<T> indirection_type; - typedef typename get_iterator_type<T>::type iterator_type; - typedef T operator_arg_type; - - static inline iterator_type begin(const T& polygon_set) { - return indirection_type::begin(polygon_set); - } - - static inline iterator_type end(const T& polygon_set) { - return indirection_type::end(polygon_set); - } - - static inline orientation_2d orient(const T&) { return HORIZONTAL; } - - static inline bool clean(const T&) { return false; } - - static inline bool sorted(const T&) { return false; } - }; - - template <typename T> - struct is_manhattan_polygonal_concept { typedef gtl_no type; }; - template <> - struct is_manhattan_polygonal_concept<rectangle_concept> { typedef gtl_yes type; }; - template <> - struct is_manhattan_polygonal_concept<polygon_90_concept> { typedef gtl_yes type; }; - template <> - struct is_manhattan_polygonal_concept<polygon_90_with_holes_concept> { typedef gtl_yes type; }; - template <> - struct is_manhattan_polygonal_concept<polygon_90_set_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_polygon_90_set_type { - typedef typename is_manhattan_polygonal_concept<typename geometry_concept<T>::type>::type type; - }; - template <typename T> - struct is_polygon_90_set_type<std::list<T> > { - typedef typename gtl_or< - typename is_manhattan_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type, - typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; - }; - template <typename T> - struct is_polygon_90_set_type<std::vector<T> > { - typedef typename gtl_or< - typename is_manhattan_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type, - typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; - }; - - template <typename T> - struct is_mutable_polygon_90_set_type { - typedef typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<T>::type>::type type; - }; - template <typename T> - struct is_mutable_polygon_90_set_type<std::list<T> > { - typedef typename gtl_or< - typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<std::list<T> >::type>::type, - typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; - }; - template <typename T> - struct is_mutable_polygon_90_set_type<std::vector<T> > { - typedef typename gtl_or< - typename gtl_same_type<polygon_90_set_concept, typename geometry_concept<std::vector<T> >::type>::type, - typename is_manhattan_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; - }; - -// //specialization for rectangle, polygon_90 and polygon_90_with_holes types -// template <typename T> -// struct polygon_90_set_traits -// typedef typename geometry_concept<T>::type concept_type; -// typedef typename get_coordinate_type<T, concept_type>::type coordinate_type; -// typedef iterator_geometry_to_set<concept_type, T> iterator_type; -// typedef T operator_arg_type; - -// static inline iterator_type begin(const T& polygon_set) { -// return iterator_geometry_to_set<concept_type, T>(polygon_set, LOW, HORIZONTAL); -// } - -// static inline iterator_type end(const T& polygon_set) { -// return iterator_geometry_to_set<concept_type, T>(polygon_set, HIGH, HORIZONTAL); -// } - -// static inline orientation_2d orient(const T& polygon_set) { return HORIZONTAL; } - -// static inline bool clean(const T& polygon_set) { return false; } - -// static inline bool sorted(const T& polygon_set) { return false; } - -// }; - -// //specialization for containers of recangle, polygon_90, polygon_90_with_holes -// template <typename T> -// struct polygon_90_set_traits<T, typename is_manhattan_polygonal_concept<typename std::iterator_traits<typename T::iterator>::value_type>::type> { -// typedef typename std::iterator_traits<typename T::iterator>::value_type geometry_type; -// typedef typename geometry_concept<geometry_type>::type concept_type; -// typedef typename get_coordinate_type<geometry_type, concept_type>::type coordinate_type; -// typedef iterator_geometry_range_to_set<concept_type, typename T::const_iterator> iterator_type; -// typedef T operator_arg_type; - -// static inline iterator_type begin(const T& polygon_set) { -// return iterator_type(polygon_set.begin(), HORIZONTAL); -// } - -// static inline iterator_type end(const T& polygon_set) { -// return iterator_type(polygon_set.end(), HORIZONTAL); -// } - -// static inline orientation_2d orient(const T& polygon_set) { return HORIZONTAL; } - -// static inline bool clean(const T& polygon_set) { return false; } - -// static inline bool sorted(const T& polygon_set) { return false; } - -// }; - - //get dispatch functions - template <typename output_container_type, typename pst> - void get_90_dispatch(output_container_type& output, const pst& ps, - orientation_2d orient, rectangle_concept ) { - form_rectangles(output, ps.begin(), ps.end(), orient, rectangle_concept()); - } - - template <typename output_container_type, typename pst> - void get_90_dispatch(output_container_type& output, const pst& ps, - orientation_2d orient, polygon_90_concept tag) { - get_polygons(output, ps.begin(), ps.end(), orient, true, tag); - } - - template <typename output_container_type, typename pst> - void get_90_dispatch(output_container_type& output, const pst& ps, - orientation_2d orient, polygon_90_with_holes_concept tag) { - get_polygons(output, ps.begin(), ps.end(), orient, false, tag); - } - - //by default works with containers of rectangle, polygon or polygon with holes - //must be specialized to work with anything else - template <typename T> - struct polygon_90_set_mutable_traits {}; - template <typename T> - struct polygon_90_set_mutable_traits<std::list<T> > { - typedef typename geometry_concept<T>::type concept_type; - template <typename input_iterator_type> - static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) { - polygon_set.clear(); - polygon_90_set_data<typename polygon_90_set_traits<std::list<T> >::coordinate_type> ps(orient); - ps.reserve(std::distance(input_begin, input_end)); - ps.insert(input_begin, input_end, orient); - ps.clean(); - get_90_dispatch(polygon_set, ps, orient, concept_type()); - } - }; - template <typename T> - struct polygon_90_set_mutable_traits<std::vector<T> > { - typedef typename geometry_concept<T>::type concept_type; - template <typename input_iterator_type> - static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end, orientation_2d orient) { - polygon_set.clear(); - size_t num_ele = std::distance(input_begin, input_end); - polygon_set.reserve(num_ele); - polygon_90_set_data<typename polygon_90_set_traits<std::list<T> >::coordinate_type> ps(orient); - ps.reserve(num_ele); - ps.insert(input_begin, input_end, orient); - ps.clean(); - get_90_dispatch(polygon_set, ps, orient, concept_type()); - } - }; - - template <typename T> - struct polygon_90_set_mutable_traits<polygon_90_set_data<T> > { - - template <typename input_iterator_type> - static inline void set(polygon_90_set_data<T>& polygon_set, - input_iterator_type input_begin, input_iterator_type input_end, - orientation_2d orient) { - polygon_set.clear(); - polygon_set.reserve(std::distance(input_begin, input_end)); - polygon_set.insert(input_begin, input_end, orient); - } - - }; - - template <typename T> - struct polygon_90_set_traits<polygon_90_set_data<T> > { - typedef typename polygon_90_set_data<T>::coordinate_type coordinate_type; - typedef typename polygon_90_set_data<T>::iterator_type iterator_type; - typedef typename polygon_90_set_data<T>::operator_arg_type operator_arg_type; - - static inline iterator_type begin(const polygon_90_set_data<T>& polygon_set) { - return polygon_set.begin(); - } - - static inline iterator_type end(const polygon_90_set_data<T>& polygon_set) { - return polygon_set.end(); - } - - static inline orientation_2d orient(const polygon_90_set_data<T>& polygon_set) { return polygon_set.orient(); } - - static inline bool clean(const polygon_90_set_data<T>& polygon_set) { polygon_set.clean(); return true; } - - static inline bool sorted(const polygon_90_set_data<T>& polygon_set) { polygon_set.sort(); return true; } - - }; - - template <typename T> - struct is_polygon_90_set_concept { }; - template <> - struct is_polygon_90_set_concept<polygon_90_set_concept> { typedef gtl_yes type; }; - template <> - struct is_polygon_90_set_concept<rectangle_concept> { typedef gtl_yes type; }; - template <> - struct is_polygon_90_set_concept<polygon_90_concept> { typedef gtl_yes type; }; - template <> - struct is_polygon_90_set_concept<polygon_90_with_holes_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_mutable_polygon_90_set_concept { typedef gtl_no type; }; - template <> - struct is_mutable_polygon_90_set_concept<polygon_90_set_concept> { typedef gtl_yes type; }; - - template <typename T> - struct geometry_concept<polygon_90_set_data<T> > { typedef polygon_90_set_concept type; }; - - //template <typename T> - //typename enable_if<typename is_polygon_90_set_type<T>::type, void>::type - //print_is_polygon_90_set_concept(const T& t) { std::cout << "is polygon 90 set concept\n"; } - //template <typename T> - //typename enable_if<typename is_mutable_polygon_90_set_type<T>::type, void>::type - //print_is_mutable_polygon_90_set_concept(const T& t) { std::cout << "is mutable polygon 90 set concept\n"; } -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_90_with_holes_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_90_with_holes_data.hpp deleted file mode 100644 index be43b6582e..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_90_with_holes_data.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - 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_POLYGON_90_WITH_HOLES_DATA_HPP -#define BOOST_POLYGON_POLYGON_90_WITH_HOLES_DATA_HPP -namespace boost { namespace polygon{ -#include "isotropy.hpp" -#include "polygon_90_data.hpp" -struct polygon_90_with_holes_concept; -template <typename T> -class polygon_90_with_holes_data { -public: - typedef polygon_90_with_holes_concept geometry_type; - typedef T coordinate_type; - typedef typename polygon_90_data<T>::iterator_type iterator_type; - typedef typename polygon_90_data<T>::compact_iterator_type compact_iterator_type; - typedef typename std::list<polygon_90_data<coordinate_type> >::const_iterator iterator_holes_type; - typedef polygon_90_data<coordinate_type> hole_type; - typedef typename coordinate_traits<T>::area_type area_type; - typedef point_data<T> point_type; - - // default constructor of point does not initialize x and y - inline polygon_90_with_holes_data() : self_(), holes_() {} //do nothing default constructor - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline polygon_90_with_holes_data& set(iT input_begin, iT input_end) { - self_.set(input_begin, input_end); - return *this; - } - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline polygon_90_with_holes_data& set_compact(iT input_begin, iT input_end) { - self_.set_compact(input_begin, input_end); - return *this; - } - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline polygon_90_with_holes_data& set_holes(iT input_begin, iT input_end) { - holes_.clear(); //just in case there was some old data there - for( ; input_begin != input_end; ++ input_begin) { - holes_.push_back(hole_type()); - holes_.back().set_compact((*input_begin).begin_compact(), (*input_begin).end_compact()); - } - return *this; - } - - // copy constructor (since we have dynamic memory) - inline polygon_90_with_holes_data(const polygon_90_with_holes_data& that) : self_(that.self_), - holes_(that.holes_) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline polygon_90_with_holes_data& operator=(const polygon_90_with_holes_data& that) { - self_ = that.self_; - holes_ = that.holes_; - return *this; - } - - template <typename T2> - inline polygon_90_with_holes_data& operator=(const T2& rvalue); - - // get begin iterator, returns a pointer to a const coordinate_type - inline const iterator_type begin() const { - return self_.begin(); - } - - // get end iterator, returns a pointer to a const coordinate_type - inline const iterator_type end() const { - return self_.end(); - } - - // get begin iterator, returns a pointer to a const coordinate_type - inline const compact_iterator_type begin_compact() const { - return self_.begin_compact(); - } - - // get end iterator, returns a pointer to a const coordinate_type - inline const compact_iterator_type end_compact() const { - return self_.end_compact(); - } - - inline std::size_t size() const { - return self_.size(); - } - - // get begin iterator, returns a pointer to a const polygon - inline const iterator_holes_type begin_holes() const { - return holes_.begin(); - } - - // get end iterator, returns a pointer to a const polygon - inline const iterator_holes_type end_holes() const { - return holes_.end(); - } - - inline std::size_t size_holes() const { - return holes_.size(); - } - -private: - polygon_90_data<coordinate_type> self_; - std::list<hole_type> holes_; -}; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_data.hpp deleted file mode 100644 index 9784466f1d..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_data.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - 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_POLYGON_DATA_HPP -#define BOOST_POLYGON_POLYGON_DATA_HPP -namespace boost { namespace polygon{ -struct polygon_concept; -template <typename T> -class polygon_data { -public: - typedef polygon_concept geometry_type; - typedef T coordinate_type; - typedef typename std::vector<point_data<coordinate_type> >::const_iterator iterator_type; - typedef typename coordinate_traits<T>::coordinate_distance area_type; - typedef point_data<T> point_type; - - inline polygon_data() : coords_() {} //do nothing default constructor - - template<class iT> - inline polygon_data(iT input_begin, iT input_end) : coords_(input_begin, input_end) {} - - template<class iT> - inline polygon_data& set(iT input_begin, iT input_end) { - coords_.clear(); //just in case there was some old data there - coords_.insert(coords_.end(), input_begin, input_end); - return *this; - } - - // copy constructor (since we have dynamic memory) - inline polygon_data(const polygon_data& that) : coords_(that.coords_) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline polygon_data& operator=(const polygon_data& that) { - coords_ = that.coords_; - return *this; - } - - template <typename T2> - inline polygon_data& operator=(const T2& rvalue); - - inline bool operator==(const polygon_data& that) const { - if(coords_.size() != that.coords_.size()) return false; - for(std::size_t i = 0; i < coords_.size(); ++i) { - if(coords_[i] != that.coords_[i]) return false; - } - return true; - } - - inline bool operator!=(const polygon_data& that) const { return !((*this) == that); } - - // get begin iterator, returns a pointer to a const Unit - inline iterator_type begin() const { return coords_.begin(); } - - // get end iterator, returns a pointer to a const Unit - inline iterator_type end() const { return coords_.end(); } - - inline std::size_t size() const { return coords_.size(); } - -public: - std::vector<point_data<coordinate_type> > coords_; -}; - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_set_concept.hpp b/contrib/restricted/boost/boost/polygon/polygon_set_concept.hpp deleted file mode 100644 index e3d37b8216..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_set_concept.hpp +++ /dev/null @@ -1,581 +0,0 @@ -/* - 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_POLYGON_SET_CONCEPT_HPP -#define BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP -#include "polygon_set_data.hpp" -#include "detail/polygon_simplify.hpp" -namespace boost { namespace polygon{ - - template <typename T, typename T2> - struct is_either_polygon_set_type { - typedef typename gtl_or<typename is_polygon_set_type<T>::type, typename is_polygon_set_type<T2>::type >::type type; - }; - - template <typename T> - struct is_any_polygon_set_type { - typedef typename gtl_or<typename is_polygon_45_or_90_set_type<T>::type, typename is_polygon_set_type<T>::type >::type type; - }; - - template <typename polygon_set_type> - typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type, - typename polygon_set_traits<polygon_set_type>::iterator_type>::type - begin_polygon_set_data(const polygon_set_type& polygon_set) { - return polygon_set_traits<polygon_set_type>::begin(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type, - typename polygon_set_traits<polygon_set_type>::iterator_type>::type - end_polygon_set_data(const polygon_set_type& polygon_set) { - return polygon_set_traits<polygon_set_type>::end(polygon_set); - } - - template <typename polygon_set_type> - typename enable_if< typename is_polygon_set_type<polygon_set_type>::type, - bool>::type - clean(const polygon_set_type& polygon_set) { - return polygon_set_traits<polygon_set_type>::clean(polygon_set); - } - - //assign - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and< - typename is_mutable_polygon_set_type<polygon_set_type_1>::type, - typename is_any_polygon_set_type<polygon_set_type_2>::type>::type, - polygon_set_type_1>::type & - assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { - if(clean(rvalue)) - polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue)); - else { - polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps; - ps.insert(begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue)); - ps.clean(); - polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, ps.begin(), ps.end()); - } - return lvalue; - } - - //get trapezoids - template <typename output_container_type, typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - void>::type - get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) { - polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.get_trapezoids(output); - } - - //get trapezoids - template <typename output_container_type, typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - void>::type - get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, - orientation_2d orient) { - polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.get_trapezoids(output, orient); - } - - //equivalence - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3 < - typename is_any_polygon_set_type<polygon_set_type_1>::type, - typename is_any_polygon_set_type<polygon_set_type_2>::type, - typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type, - bool>::type - equivalence(const polygon_set_type_1& lvalue, - const polygon_set_type_2& rvalue) { - polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1; - assign(ps1, lvalue); - polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2; - assign(ps2, rvalue); - return ps1 == ps2; - } - - //clear - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - void>::type - clear(polygon_set_type& polygon_set) { - polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; - assign(polygon_set, ps); - } - - //empty - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - bool>::type - empty(const polygon_set_type& polygon_set) { - if(clean(polygon_set)) return begin_polygon_set_data(polygon_set) == end_polygon_set_data(polygon_set); - polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - ps.clean(); - return ps.empty(); - } - - //extents - template <typename polygon_set_type, typename rectangle_type> - typename enable_if< typename gtl_and< - typename is_mutable_polygon_set_type<polygon_set_type>::type, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - bool>::type - extents(rectangle_type& extents_rectangle, - const polygon_set_type& polygon_set) { - clean(polygon_set); - polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps; - assign(ps, polygon_set); - return ps.extents(extents_rectangle); - } - - //area - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type>::type - area(const polygon_set_type& polygon_set) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - typedef polygon_with_holes_data<Unit> p_type; - typedef typename coordinate_traits<Unit>::area_type area_type; - std::vector<p_type> polys; - assign(polys, polygon_set); - area_type retval = (area_type)0; - for(std::size_t i = 0; i < polys.size(); ++i) { - retval += area(polys[i]); - } - return retval; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - std::size_t>::type - simplify(polygon_set_type& polygon_set, typename coordinate_traits< - typename polygon_set_traits<polygon_set_type>::coordinate_type - >::coordinate_distance threshold) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - typedef polygon_with_holes_data<Unit> p_type; - std::vector<p_type> polys; - assign(polys, polygon_set); - std::size_t retval = 0; - for(std::size_t i = 0; i < polys.size(); ++i) { - retval += detail::simplify_detail::simplify(polys[i].self_.coords_, - polys[i].self_.coords_, threshold); - for(typename std::list<polygon_data<Unit> >::iterator itrh = - polys[i].holes_.begin(); itrh != (polys[i].holes_.end()); ++itrh) { - retval += detail::simplify_detail::simplify((*itrh).coords_, - (*itrh).coords_, threshold); - } - } - assign(polygon_set, polys); - return retval; - } - - template <typename polygon_set_type, typename coord_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - resize(polygon_set_type& polygon_set, coord_type resizing, bool corner_fill_arcs = false, int num_circle_segments = 0) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_set_data<Unit> ps; - assign(ps, polygon_set); - ps.resize(resizing, corner_fill_arcs,num_circle_segments); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - bloat(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { - return resize(polygon_set, bloating); - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - shrink(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { - return resize(polygon_set, -(typename polygon_set_traits<polygon_set_type>::coordinate_type)shrinking); - } - - //interact - template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3 < - typename is_any_polygon_set_type<polygon_set_type_1>::type, - typename is_any_polygon_set_type<polygon_set_type_2>::type, - typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type, - polygon_set_type_1>::type& - interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { - polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1; - assign(ps1, polygon_set_1); - polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2; - assign(ps2, polygon_set_2); - ps1.interact(ps2); - assign(polygon_set_1, ps1); - return polygon_set_1; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale_up(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale_up(factor); - assign(polygon_set, ps); - return polygon_set; - } - - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - scale_down(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_set_data<Unit> ps; - assign(ps, polygon_set); - ps.scale_down(factor); - assign(polygon_set, ps); - return polygon_set; - } - - //transform - template <typename polygon_set_type, typename transformation_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - transform(polygon_set_type& polygon_set, - const transformation_type& transformation) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - clean(polygon_set); - polygon_set_data<Unit> ps; - assign(ps, polygon_set); - ps.transform(transformation); - assign(polygon_set, ps); - return polygon_set; - } - - //keep - template <typename polygon_set_type> - typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type, - polygon_set_type>::type & - keep(polygon_set_type& polygon_set, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type min_area, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type max_area, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height, - typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) { - typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit; - typedef typename coordinate_traits<Unit>::unsigned_area_type uat; - std::list<polygon_with_holes_data<Unit> > polys; - assign(polys, polygon_set); - typename std::list<polygon_with_holes_data<Unit> >::iterator itr_nxt; - for(typename std::list<polygon_with_holes_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ - itr_nxt = itr; - ++itr_nxt; - rectangle_data<Unit> bbox; - extents(bbox, *itr); - uat pwidth = delta(bbox, HORIZONTAL); - if(pwidth > min_width && pwidth <= max_width){ - uat pheight = delta(bbox, VERTICAL); - if(pheight > min_height && pheight <= max_height){ - typename coordinate_traits<Unit>::area_type parea = area(*itr); - if(parea <= max_area && parea >= min_area) { - continue; - } - } - } - polys.erase(itr); - } - assign(polygon_set, polys); - return polygon_set; - } - - namespace operators { - - struct yes_ps_ob : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4 < yes_ps_ob, typename is_any_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type, - typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type - operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_set_view<geometry_type_1, geometry_type_2, 0> - (lvalue, rvalue); - } - - struct yes_ps_op : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4 < yes_ps_op, - typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type, - typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type> - ::type, polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type - operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_set_view<geometry_type_1, geometry_type_2, 0> - (lvalue, rvalue); - } - - struct yes_ps_os : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4 < yes_ps_os, - typename is_any_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type, - typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type - operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_set_view<geometry_type_1, geometry_type_2, 1> - (lvalue, rvalue); - } - - struct yes_ps_oa : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4 < yes_ps_oa, - typename is_any_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type, - typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type - operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_set_view<geometry_type_1, geometry_type_2, 1> - (lvalue, rvalue); - } - - struct yes_ps_ox : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4 < yes_ps_ox, - typename is_any_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type, - typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type, - polygon_set_view<geometry_type_1, geometry_type_2, 2> >::type - operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_set_view<geometry_type_1, geometry_type_2, 2> - (lvalue, rvalue); - } - - struct yes_ps_om : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4 < yes_ps_om, - typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type, - typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type, - typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type> - ::type, polygon_set_view<geometry_type_1, geometry_type_2, 3> >::type - operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return polygon_set_view<geometry_type_1, geometry_type_2, 3> - (lvalue, rvalue); - } - - struct yes_ps_ope : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_4< yes_ps_ope, gtl_yes, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); - } - - struct yes_ps_obe : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< yes_ps_obe, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue); - } - - struct yes_ps_ose : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< yes_ps_ose, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); - } - - struct yes_ps_oae : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< - typename gtl_and_3< yes_ps_oae, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue); - } - - struct yes_ps_oxe : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< typename gtl_and_3< yes_ps_oxe, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue); - } - - struct yes_ps_ome : gtl_yes {}; - - template <typename geometry_type_1, typename geometry_type_2> - typename enable_if< - typename gtl_and_3< yes_ps_ome, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename is_any_polygon_set_type<geometry_type_2>::type>::type, - geometry_type_1>::type & - operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { - return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue); - } - - // TODO: Dafna, test these four resizing operators - struct y_ps_rpe : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3< y_ps_rpe, typename is_mutable_polygon_set_type<geometry_type_1>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type>::type, - geometry_type_1>::type & - operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { - return resize(lvalue, rvalue); - } - - struct y_ps_rme : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps_rme, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type>::type, - geometry_type_1>::type & - operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { - return resize(lvalue, -rvalue); - } - - struct y_ps_rp : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps_rp, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type> - ::type, geometry_type_1>::type - operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { - geometry_type_1 retval(lvalue); - retval += rvalue; - return retval; - } - - struct y_ps_rm : gtl_yes {}; - - template <typename geometry_type_1, typename coordinate_type_1> - typename enable_if< typename gtl_and_3<y_ps_rm, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type, - typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, - coordinate_concept>::type> - ::type, geometry_type_1>::type - operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { - geometry_type_1 retval(lvalue); - retval -= rvalue; - return retval; - } - - - } //end operators namespace - - template <typename T> - struct view_of<polygon_45_set_concept, T> { - typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; - T* tp; - std::vector<polygon_45_with_holes_data<coordinate_type> > polys; - view_of(const T& obj) : tp(), polys() { - std::vector<polygon_with_holes_data<coordinate_type> > gpolys; - assign(gpolys, obj); - for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); - itr != gpolys.end(); ++itr) { - polys.push_back(polygon_45_with_holes_data<coordinate_type>()); - assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr)); - } - } - view_of(T& obj) : tp(&obj), polys() { - std::vector<polygon_with_holes_data<coordinate_type> > gpolys; - assign(gpolys, obj); - for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin(); - itr != gpolys.end(); ++itr) { - polys.push_back(polygon_45_with_holes_data<coordinate_type>()); - assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr)); - } - } - - typedef typename std::vector<polygon_45_with_holes_data<coordinate_type> >::const_iterator iterator_type; - typedef view_of operator_arg_type; - - inline iterator_type begin() const { - return polys.begin(); - } - - inline iterator_type end() const { - return polys.end(); - } - - inline orientation_2d orient() const { return HORIZONTAL; } - - inline bool clean() const { return false; } - - inline bool sorted() const { return false; } - - inline T& get() { return *tp; } - }; - - template <typename T> - struct polygon_45_set_traits<view_of<polygon_45_set_concept, T> > { - typedef typename view_of<polygon_45_set_concept, T>::coordinate_type coordinate_type; - typedef typename view_of<polygon_45_set_concept, T>::iterator_type iterator_type; - typedef view_of<polygon_45_set_concept, T> operator_arg_type; - - static inline iterator_type begin(const view_of<polygon_45_set_concept, T>& polygon_set) { - return polygon_set.begin(); - } - - static inline iterator_type end(const view_of<polygon_45_set_concept, T>& polygon_set) { - return polygon_set.end(); - } - - static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) { - return polygon_set.orient(); } - - static inline bool clean(const view_of<polygon_45_set_concept, T>& polygon_set) { - return polygon_set.clean(); } - - static inline bool sorted(const view_of<polygon_45_set_concept, T>& polygon_set) { - return polygon_set.sorted(); } - - }; - - template <typename T> - struct geometry_concept<view_of<polygon_45_set_concept, T> > { - typedef polygon_45_set_concept type; - }; - - template <typename T> - struct get_coordinate_type<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> { - typedef typename view_of<polygon_45_set_concept, T>::coordinate_type type; - }; - template <typename T> - struct get_iterator_type_2<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> { - typedef typename view_of<polygon_45_set_concept, T>::iterator_type type; - static type begin(const view_of<polygon_45_set_concept, T>& t) { return t.begin(); } - static type end(const view_of<polygon_45_set_concept, T>& t) { return t.end(); } - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_set_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_set_data.hpp deleted file mode 100644 index 32dd800fe7..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_set_data.hpp +++ /dev/null @@ -1,1006 +0,0 @@ -/* - 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_POLYGON_SET_DATA_HPP -#define BOOST_POLYGON_POLYGON_SET_DATA_HPP -#include "polygon_45_set_data.hpp" -#include "polygon_45_set_concept.hpp" -#include "polygon_traits.hpp" -#include "detail/polygon_arbitrary_formation.hpp" - -namespace boost { namespace polygon { - - - // utility function to round coordinate types down - // rounds down for both negative and positive numbers - // intended really for integer type T (does not make sense for float) - template <typename T> - static inline T round_down(double val) { - T rounded_val = (T)(val); - if(val < (double)rounded_val) - --rounded_val; - return rounded_val; - } - template <typename T> - static inline point_data<T> round_down(point_data<double> v) { - return point_data<T>(round_down<T>(v.x()),round_down<T>(v.y())); - } - - - - //foward declare view - template <typename ltype, typename rtype, int op_type> class polygon_set_view; - - template <typename T> - class polygon_set_data { - public: - typedef T coordinate_type; - typedef point_data<T> point_type; - typedef std::pair<point_type, point_type> edge_type; - typedef std::pair<edge_type, int> element_type; - typedef std::vector<element_type> value_type; - typedef typename value_type::const_iterator iterator_type; - typedef polygon_set_data operator_arg_type; - - // default constructor - inline polygon_set_data() : data_(), dirty_(false), unsorted_(false), is_45_(true) {} - - // constructor from an iterator pair over edge data - template <typename iT> - inline polygon_set_data(iT input_begin, iT input_end) : data_(), dirty_(false), unsorted_(false), is_45_(true) { - for( ; input_begin != input_end; ++input_begin) { insert(*input_begin); } - } - - // copy constructor - inline polygon_set_data(const polygon_set_data& that) : - data_(that.data_), dirty_(that.dirty_), unsorted_(that.unsorted_), is_45_(that.is_45_) {} - - // copy constructor - template <typename ltype, typename rtype, int op_type> - inline polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that); - - // destructor - inline ~polygon_set_data() {} - - // assignement operator - inline polygon_set_data& operator=(const polygon_set_data& that) { - if(this == &that) return *this; - data_ = that.data_; - dirty_ = that.dirty_; - unsorted_ = that.unsorted_; - is_45_ = that.is_45_; - return *this; - } - - template <typename ltype, typename rtype, int op_type> - inline polygon_set_data& operator=(const polygon_set_view<ltype, rtype, op_type>& geometry) { - (*this) = geometry.value(); - dirty_ = false; - unsorted_ = false; - return *this; - } - - template <typename geometry_object> - inline polygon_set_data& operator=(const geometry_object& geometry) { - data_.clear(); - insert(geometry); - return *this; - } - - - // insert iterator range - inline void insert(iterator_type input_begin, iterator_type input_end, bool is_hole = false) { - if(input_begin == input_end || (!data_.empty() && &(*input_begin) == &(*(data_.begin())))) return; - dirty_ = true; - unsorted_ = true; - while(input_begin != input_end) { - insert(*input_begin, is_hole); - ++input_begin; - } - } - - // insert iterator range - template <typename iT> - inline void insert(iT input_begin, iT input_end, bool is_hole = false) { - if(input_begin == input_end) return; - for(; input_begin != input_end; ++input_begin) { - insert(*input_begin, is_hole); - } - } - - template <typename geometry_type> - inline void insert(const geometry_type& geometry_object, bool is_hole = false) { - insert(geometry_object, is_hole, typename geometry_concept<geometry_type>::type()); - } - - template <typename polygon_type> - inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_concept ) { - insert_vertex_sequence(begin_points(polygon_object), end_points(polygon_object), winding(polygon_object), is_hole); - } - - inline void insert(const polygon_set_data& ps, bool is_hole = false) { - insert(ps.data_.begin(), ps.data_.end(), is_hole); - } - - template <typename polygon_45_set_type> - inline void insert(const polygon_45_set_type& ps, bool is_hole, polygon_45_set_concept) { - std::vector<polygon_45_with_holes_data<typename polygon_45_set_traits<polygon_45_set_type>::coordinate_type> > polys; - assign(polys, ps); - insert(polys.begin(), polys.end(), is_hole); - } - - template <typename polygon_90_set_type> - inline void insert(const polygon_90_set_type& ps, bool is_hole, polygon_90_set_concept) { - std::vector<polygon_90_with_holes_data<typename polygon_90_set_traits<polygon_90_set_type>::coordinate_type> > polys; - assign(polys, ps); - insert(polys.begin(), polys.end(), is_hole); - } - - template <typename polygon_type> - inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_45_concept ) { - insert(polygon_object, is_hole, polygon_concept()); } - - template <typename polygon_type> - inline void insert(const polygon_type& polygon_object, bool is_hole, polygon_90_concept ) { - insert(polygon_object, is_hole, polygon_concept()); } - - template <typename polygon_with_holes_type> - inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole, - polygon_with_holes_concept ) { - insert(polygon_with_holes_object, is_hole, polygon_concept()); - for(typename polygon_with_holes_traits<polygon_with_holes_type>::iterator_holes_type itr = - begin_holes(polygon_with_holes_object); - itr != end_holes(polygon_with_holes_object); ++itr) { - insert(*itr, !is_hole, polygon_concept()); - } - } - - template <typename polygon_with_holes_type> - inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole, - polygon_45_with_holes_concept ) { - insert(polygon_with_holes_object, is_hole, polygon_with_holes_concept()); } - - template <typename polygon_with_holes_type> - inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole, - polygon_90_with_holes_concept ) { - insert(polygon_with_holes_object, is_hole, polygon_with_holes_concept()); } - - template <typename rectangle_type> - inline void insert(const rectangle_type& rectangle_object, bool is_hole, rectangle_concept ) { - polygon_90_data<coordinate_type> poly; - assign(poly, rectangle_object); - insert(poly, is_hole, polygon_concept()); - } - - inline void insert_clean(const element_type& edge, bool is_hole = false) { - if( ! scanline_base<coordinate_type>::is_45_degree(edge.first) && - ! scanline_base<coordinate_type>::is_horizontal(edge.first) && - ! scanline_base<coordinate_type>::is_vertical(edge.first) ) is_45_ = false; - data_.push_back(edge); - if(data_.back().first.second < data_.back().first.first) { - std::swap(data_.back().first.second, data_.back().first.first); - data_.back().second *= -1; - } - if(is_hole) - data_.back().second *= -1; - } - - inline void insert(const element_type& edge, bool is_hole = false) { - insert_clean(edge, is_hole); - dirty_ = true; - unsorted_ = true; - } - - template <class iT> - inline void insert_vertex_sequence(iT begin_vertex, iT end_vertex, direction_1d winding, bool is_hole) { - if (begin_vertex == end_vertex) { - // No edges to insert. - return; - } - // Current edge endpoints. - iT vertex0 = begin_vertex; - iT vertex1 = begin_vertex; - if (++vertex1 == end_vertex) { - // No edges to insert. - return; - } - int wmultiplier = (winding == COUNTERCLOCKWISE) ? 1 : -1; - if (is_hole) { - wmultiplier = -wmultiplier; - } - dirty_ = true; - unsorted_ = true; - while (vertex0 != end_vertex) { - point_type p0, p1; - assign(p0, *vertex0); - assign(p1, *vertex1); - if (p0 != p1) { - int hmultiplier = (p0.get(HORIZONTAL) == p1.get(HORIZONTAL)) ? -1 : 1; - element_type elem(edge_type(p0, p1), hmultiplier * wmultiplier); - insert_clean(elem); - } - ++vertex0; - ++vertex1; - if (vertex1 == end_vertex) { - vertex1 = begin_vertex; - } - } - } - - template <typename output_container> - inline void get(output_container& output) const { - get_dispatch(output, typename geometry_concept<typename output_container::value_type>::type()); - } - - // append to the container cT with polygons of three or four verticies - // slicing orientation is vertical - template <class cT> - void get_trapezoids(cT& container) const { - clean(); - trapezoid_arbitrary_formation<coordinate_type> pf; - typedef typename polygon_arbitrary_formation<coordinate_type>::vertex_half_edge vertex_half_edge; - std::vector<vertex_half_edge> data; - for(iterator_type itr = data_.begin(); itr != data_.end(); ++itr){ - data.push_back(vertex_half_edge((*itr).first.first, (*itr).first.second, (*itr).second)); - data.push_back(vertex_half_edge((*itr).first.second, (*itr).first.first, -1 * (*itr).second)); - } - polygon_sort(data.begin(), data.end()); - pf.scan(container, data.begin(), data.end()); - //std::cout << "DONE FORMING POLYGONS\n"; - } - - // append to the container cT with polygons of three or four verticies - template <class cT> - void get_trapezoids(cT& container, orientation_2d slicing_orientation) const { - if(slicing_orientation == VERTICAL) { - get_trapezoids(container); - } else { - polygon_set_data<T> ps(*this); - ps.transform(axis_transformation(axis_transformation::SWAP_XY)); - cT result; - ps.get_trapezoids(result); - for(typename cT::iterator itr = result.begin(); itr != result.end(); ++itr) { - ::boost::polygon::transform(*itr, axis_transformation(axis_transformation::SWAP_XY)); - } - container.insert(container.end(), result.begin(), result.end()); - } - } - - // equivalence operator - inline bool operator==(const polygon_set_data& p) const; - - // inequivalence operator - inline bool operator!=(const polygon_set_data& p) const { - return !((*this) == p); - } - - // get iterator to begin vertex data - inline iterator_type begin() const { - return data_.begin(); - } - - // get iterator to end vertex data - inline iterator_type end() const { - return data_.end(); - } - - const value_type& value() const { - return data_; - } - - // clear the contents of the polygon_set_data - inline void clear() { data_.clear(); dirty_ = unsorted_ = false; } - - // find out if Polygon set is empty - inline bool empty() const { return data_.empty(); } - - // get the Polygon set size in vertices - inline std::size_t size() const { clean(); return data_.size(); } - - // get the current Polygon set capacity in vertices - inline std::size_t capacity() const { return data_.capacity(); } - - // reserve size of polygon set in vertices - inline void reserve(std::size_t size) { return data_.reserve(size); } - - // find out if Polygon set is sorted - inline bool sorted() const { return !unsorted_; } - - // find out if Polygon set is clean - inline bool dirty() const { return dirty_; } - - void clean() const; - - void sort() const{ - if(unsorted_) { - polygon_sort(data_.begin(), data_.end()); - unsorted_ = false; - } - } - - template <typename input_iterator_type> - void set(input_iterator_type input_begin, input_iterator_type input_end) { - clear(); - reserve(std::distance(input_begin,input_end)); - insert(input_begin, input_end); - dirty_ = true; - unsorted_ = true; - } - - void set(const value_type& value) { - data_ = value; - dirty_ = true; - unsorted_ = true; - } - - template <typename rectangle_type> - bool extents(rectangle_type& rect) { - clean(); - if(empty()) return false; - bool first_iteration = true; - for(iterator_type itr = begin(); - itr != end(); ++itr) { - rectangle_type edge_box; - set_points(edge_box, (*itr).first.first, (*itr).first.second); - if(first_iteration) - rect = edge_box; - else - encompass(rect, edge_box); - first_iteration = false; - } - return true; - } - - inline polygon_set_data& - resize(coordinate_type resizing, bool corner_fill_arc = false, unsigned int num_circle_segments=0); - - template <typename transform_type> - inline polygon_set_data& - transform(const transform_type& tr) { - std::vector<polygon_with_holes_data<T> > polys; - get(polys); - clear(); - for(std::size_t i = 0 ; i < polys.size(); ++i) { - ::boost::polygon::transform(polys[i], tr); - insert(polys[i]); - } - unsorted_ = true; - dirty_ = true; - return *this; - } - - inline polygon_set_data& - scale_up(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) { - for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) { - ::boost::polygon::scale_up((*itr).first.first, factor); - ::boost::polygon::scale_up((*itr).first.second, factor); - } - return *this; - } - - inline polygon_set_data& - scale_down(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) { - for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) { - bool vb = (*itr).first.first.x() == (*itr).first.second.x(); - ::boost::polygon::scale_down((*itr).first.first, factor); - ::boost::polygon::scale_down((*itr).first.second, factor); - bool va = (*itr).first.first.x() == (*itr).first.second.x(); - if(!vb && va) { - (*itr).second *= -1; - } - } - unsorted_ = true; - dirty_ = true; - return *this; - } - - template <typename scaling_type> - inline polygon_set_data& scale(polygon_set_data&, - const scaling_type& scaling) { - for(typename value_type::iterator itr = begin(); itr != end(); ++itr) { - bool vb = (*itr).first.first.x() == (*itr).first.second.x(); - ::boost::polygon::scale((*itr).first.first, scaling); - ::boost::polygon::scale((*itr).first.second, scaling); - bool va = (*itr).first.first.x() == (*itr).first.second.x(); - if(!vb && va) { - (*itr).second *= -1; - } - } - unsorted_ = true; - dirty_ = true; - return *this; - } - - static inline void compute_offset_edge(point_data<long double>& pt1, point_data<long double>& pt2, - const point_data<long double>& prev_pt, - const point_data<long double>& current_pt, - long double distance, int multiplier) { - long double dx = current_pt.x() - prev_pt.x(); - long double dy = current_pt.y() - prev_pt.y(); - long double edge_length = std::sqrt(dx*dx + dy*dy); - long double dnx = dy; - long double dny = -dx; - dnx = dnx * (long double)distance / edge_length; - dny = dny * (long double)distance / edge_length; - pt1.x(prev_pt.x() + (long double)dnx * (long double)multiplier); - pt2.x(current_pt.x() + (long double)dnx * (long double)multiplier); - pt1.y(prev_pt.y() + (long double)dny * (long double)multiplier); - pt2.y(current_pt.y() + (long double)dny * (long double)multiplier); - } - - static inline void modify_pt(point_data<coordinate_type>& pt, const point_data<coordinate_type>& prev_pt, - const point_data<coordinate_type>& current_pt, const point_data<coordinate_type>& next_pt, - coordinate_type distance, coordinate_type multiplier) { - std::pair<point_data<long double>, point_data<long double> > he1, he2; - he1.first.x((long double)(prev_pt.x())); - he1.first.y((long double)(prev_pt.y())); - he1.second.x((long double)(current_pt.x())); - he1.second.y((long double)(current_pt.y())); - he2.first.x((long double)(current_pt.x())); - he2.first.y((long double)(current_pt.y())); - he2.second.x((long double)(next_pt.x())); - he2.second.y((long double)(next_pt.y())); - compute_offset_edge(he1.first, he1.second, prev_pt, current_pt, distance, multiplier); - compute_offset_edge(he2.first, he2.second, current_pt, next_pt, distance, multiplier); - typedef scanline_base<long double>::compute_intersection_pack pack; - point_data<long double> rpt; - point_data<long double> bisectorpt((he1.second.x()+he2.first.x())/2, - (he1.second.y()+he2.first.y())/2); - point_data<long double> orig_pt((long double)pt.x(), (long double)pt.y()); - if(euclidean_distance(bisectorpt, orig_pt) < distance/2) { - if(!pack::compute_lazy_intersection(rpt, he1, he2, true, false)) { - rpt = he1.second; //colinear offset edges use shared point - } - } else { - if(!pack::compute_lazy_intersection(rpt, he1, std::pair<point_data<long double>, point_data<long double> >(orig_pt, bisectorpt), true, false)) { - rpt = he1.second; //colinear offset edges use shared point - } - } - pt.x((coordinate_type)(std::floor(rpt.x()+0.5))); - pt.y((coordinate_type)(std::floor(rpt.y()+0.5))); - } - - static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly, coordinate_type distance, coordinate_type multiplier) { - point_data<coordinate_type> first_pt = poly[0]; - point_data<coordinate_type> second_pt = poly[1]; - point_data<coordinate_type> prev_pt = poly[0]; - point_data<coordinate_type> current_pt = poly[1]; - for(std::size_t i = 2; i < poly.size()-1; ++i) { - point_data<coordinate_type> next_pt = poly[i]; - modify_pt(poly[i-1], prev_pt, current_pt, next_pt, distance, multiplier); - prev_pt = current_pt; - current_pt = next_pt; - } - point_data<coordinate_type> next_pt = first_pt; - modify_pt(poly[poly.size()-2], prev_pt, current_pt, next_pt, distance, multiplier); - prev_pt = current_pt; - current_pt = next_pt; - next_pt = second_pt; - modify_pt(poly[0], prev_pt, current_pt, next_pt, distance, multiplier); - poly.back() = poly.front(); - } - static bool resize_poly_down(std::vector<point_data<coordinate_type> >& poly, coordinate_type distance, coordinate_type multiplier) { - std::vector<point_data<coordinate_type> > orig_poly(poly); - rectangle_data<coordinate_type> extents_rectangle; - set_points(extents_rectangle, poly[0], poly[0]); - point_data<coordinate_type> first_pt = poly[0]; - point_data<coordinate_type> second_pt = poly[1]; - point_data<coordinate_type> prev_pt = poly[0]; - point_data<coordinate_type> current_pt = poly[1]; - encompass(extents_rectangle, current_pt); - for(std::size_t i = 2; i < poly.size()-1; ++i) { - point_data<coordinate_type> next_pt = poly[i]; - encompass(extents_rectangle, next_pt); - modify_pt(poly[i-1], prev_pt, current_pt, next_pt, distance, multiplier); - prev_pt = current_pt; - current_pt = next_pt; - } - if(delta(extents_rectangle, HORIZONTAL) <= std::abs(2*distance)) - return false; - if(delta(extents_rectangle, VERTICAL) <= std::abs(2*distance)) - return false; - point_data<coordinate_type> next_pt = first_pt; - modify_pt(poly[poly.size()-2], prev_pt, current_pt, next_pt, distance, multiplier); - prev_pt = current_pt; - current_pt = next_pt; - next_pt = second_pt; - modify_pt(poly[0], prev_pt, current_pt, next_pt, distance, multiplier); - poly.back() = poly.front(); - //if the line segments formed between orignial and new points cross for an edge that edge inverts - //if all edges invert the polygon should be discarded - //if even one edge does not invert return true because the polygon is valid - bool non_inverting_edge = false; - for(std::size_t i = 1; i < poly.size(); ++i) { - std::pair<point_data<coordinate_type>, point_data<coordinate_type> > - he1(poly[i], orig_poly[i]), - he2(poly[i-1], orig_poly[i-1]); - if(!scanline_base<coordinate_type>::intersects(he1, he2)) { - non_inverting_edge = true; - break; - } - } - return non_inverting_edge; - } - - polygon_set_data& - bloat(typename coordinate_traits<coordinate_type>::unsigned_area_type distance) { - std::list<polygon_with_holes_data<coordinate_type> > polys; - get(polys); - clear(); - for(typename std::list<polygon_with_holes_data<coordinate_type> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - resize_poly_up((*itr).self_.coords_, (coordinate_type)distance, (coordinate_type)1); - insert_vertex_sequence((*itr).self_.begin(), (*itr).self_.end(), COUNTERCLOCKWISE, false); //inserts without holes - for(typename std::list<polygon_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin(); - itrh != (*itr).holes_.end(); ++itrh) { - if(resize_poly_down((*itrh).coords_, (coordinate_type)distance, (coordinate_type)1)) { - insert_vertex_sequence((*itrh).coords_.begin(), (*itrh).coords_.end(), CLOCKWISE, true); - } - } - } - return *this; - } - - polygon_set_data& - shrink(typename coordinate_traits<coordinate_type>::unsigned_area_type distance) { - std::list<polygon_with_holes_data<coordinate_type> > polys; - get(polys); - clear(); - for(typename std::list<polygon_with_holes_data<coordinate_type> >::iterator itr = polys.begin(); - itr != polys.end(); ++itr) { - if(resize_poly_down((*itr).self_.coords_, (coordinate_type)distance, (coordinate_type)-1)) { - insert_vertex_sequence((*itr).self_.begin(), (*itr).self_.end(), COUNTERCLOCKWISE, false); //inserts without holes - for(typename std::list<polygon_data<coordinate_type> >::iterator itrh = (*itr).holes_.begin(); - itrh != (*itr).holes_.end(); ++itrh) { - resize_poly_up((*itrh).coords_, (coordinate_type)distance, (coordinate_type)-1); - insert_vertex_sequence((*itrh).coords_.begin(), (*itrh).coords_.end(), CLOCKWISE, true); - } - } - } - return *this; - } - - // TODO:: should be private - template <typename geometry_type> - inline polygon_set_data& - insert_with_resize(const geometry_type& poly, coordinate_type resizing, bool corner_fill_arc=false, unsigned int num_circle_segments=0, bool hole = false) { - return insert_with_resize_dispatch(poly, resizing, corner_fill_arc, num_circle_segments, hole, typename geometry_concept<geometry_type>::type()); - } - - template <typename geometry_type> - inline polygon_set_data& - insert_with_resize_dispatch(const geometry_type& poly, coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments, bool hole, - polygon_with_holes_concept) { - insert_with_resize_dispatch(poly, resizing, corner_fill_arc, num_circle_segments, hole, polygon_concept()); - for(typename polygon_with_holes_traits<geometry_type>::iterator_holes_type itr = - begin_holes(poly); itr != end_holes(poly); - ++itr) { - insert_with_resize_dispatch(*itr, resizing, corner_fill_arc, num_circle_segments, !hole, polygon_concept()); - } - return *this; - } - - template <typename geometry_type> - inline polygon_set_data& - insert_with_resize_dispatch(const geometry_type& poly, coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments, bool hole, - polygon_concept) { - - if (resizing==0) - return *this; - - - // one dimensional used to store CCW/CW flag - //direction_1d wdir = winding(poly); - // LOW==CLOCKWISE just faster to type - // so > 0 is CCW - //int multiplier = wdir == LOW ? -1 : 1; - //std::cout<<" multiplier : "<<multiplier<<std::endl; - //if(hole) resizing *= -1; - direction_1d resize_wdir = resizing>0?COUNTERCLOCKWISE:CLOCKWISE; - - typedef typename polygon_data<T>::iterator_type piterator; - piterator first, second, third, end, real_end; - real_end = end_points(poly); - third = begin_points(poly); - first = third; - if(first == real_end) return *this; - ++third; - if(third == real_end) return *this; - second = end = third; - ++third; - if(third == real_end) return *this; - - // for 1st corner - std::vector<point_data<T> > first_pts; - std::vector<point_data<T> > all_pts; - direction_1d first_wdir = CLOCKWISE; - - // for all corners - polygon_set_data<T> sizingSet; - bool sizing_sign = resizing<0; - bool prev_concave = true; - point_data<T> prev_point; - //int iCtr=0; - - - //insert minkofski shapes on edges and corners - do { // REAL WORK IS HERE - - - //first, second and third point to points in correct CCW order - // check if convex or concave case - point_data<coordinate_type> normal1( second->y()-first->y(), first->x()-second->x()); - point_data<coordinate_type> normal2( third->y()-second->y(), second->x()-third->x()); - double direction = normal1.x()*normal2.y()- normal2.x()*normal1.y(); - bool convex = direction>0; - - bool treat_as_concave = !convex; - if(sizing_sign) - treat_as_concave = convex; - point_data<double> v; - assign(v, normal1); - double s2 = (v.x()*v.x()+v.y()*v.y()); - double s = std::sqrt(s2)/resizing; - v = point_data<double>(v.x()/s,v.y()/s); - point_data<T> curr_prev; - if (prev_concave) - //TODO missing round_down() - curr_prev = point_data<T>(first->x()+v.x(),first->y()+v.y()); - else - curr_prev = prev_point; - - // around concave corners - insert rectangle - // if previous corner is concave it's point info may be ignored - if ( treat_as_concave) { - std::vector<point_data<T> > pts; - - pts.push_back(point_data<T>(second->x()+v.x(),second->y()+v.y())); - pts.push_back(*second); - pts.push_back(*first); - pts.push_back(point_data<T>(curr_prev)); - if (first_pts.size()){ - sizingSet.insert_vertex_sequence(pts.begin(),pts.end(), resize_wdir,false); - }else { - first_pts=pts; - first_wdir = resize_wdir; - } - } else { - - // add either intersection_quad or pie_shape, based on corner_fill_arc option - // for convex corner (convexity depends on sign of resizing, whether we shrink or grow) - std::vector< std::vector<point_data<T> > > pts; - direction_1d winding; - winding = convex?COUNTERCLOCKWISE:CLOCKWISE; - if (make_resizing_vertex_list(pts, curr_prev, prev_concave, *first, *second, *third, resizing - , num_circle_segments, corner_fill_arc)) - { - if (first_pts.size()) { - for (int i=0; i<pts.size(); i++) { - sizingSet.insert_vertex_sequence(pts[i].begin(),pts[i].end(),winding,false); - } - - } else { - first_pts = pts[0]; - first_wdir = resize_wdir; - for (int i=1; i<pts.size(); i++) { - sizingSet.insert_vertex_sequence(pts[i].begin(),pts[i].end(),winding,false); - } - } - prev_point = curr_prev; - - } else { - treat_as_concave = true; - } - } - - prev_concave = treat_as_concave; - first = second; - second = third; - ++third; - if(third == real_end) { - third = begin_points(poly); - if(*second == *third) { - ++third; //skip first point if it is duplicate of last point - } - } - } while(second != end); - - // handle insertion of first point - if (!prev_concave) { - first_pts[first_pts.size()-1]=prev_point; - } - sizingSet.insert_vertex_sequence(first_pts.begin(),first_pts.end(),first_wdir,false); - - polygon_set_data<coordinate_type> tmp; - - //insert original shape - tmp.insert(poly, false, polygon_concept()); - if((resizing < 0) ^ hole) tmp -= sizingSet; - else tmp += sizingSet; - //tmp.clean(); - insert(tmp, hole); - return (*this); - } - - - inline polygon_set_data& - interact(const polygon_set_data& that); - - inline bool downcast(polygon_45_set_data<coordinate_type>& result) const { - if(!is_45_) return false; - for(iterator_type itr = begin(); itr != end(); ++itr) { - const element_type& elem = *itr; - int count = elem.second; - int rise = 1; //up sloping 45 - if(scanline_base<coordinate_type>::is_horizontal(elem.first)) rise = 0; - else if(scanline_base<coordinate_type>::is_vertical(elem.first)) rise = 2; - else { - if(!scanline_base<coordinate_type>::is_45_degree(elem.first)) { - is_45_ = false; - return false; //consider throwing because is_45_ has be be wrong - } - if(elem.first.first.y() > elem.first.second.y()) rise = -1; //down sloping 45 - } - typename polygon_45_set_data<coordinate_type>::Vertex45Compact vertex(elem.first.first, rise, count); - result.insert(vertex); - typename polygon_45_set_data<coordinate_type>::Vertex45Compact vertex2(elem.first.second, rise, -count); - result.insert(vertex2); - } - return true; - } - - inline GEOMETRY_CONCEPT_ID concept_downcast() const { - typedef typename coordinate_traits<coordinate_type>::coordinate_difference delta_type; - bool is_45 = false; - for(iterator_type itr = begin(); itr != end(); ++itr) { - const element_type& elem = *itr; - delta_type h_delta = euclidean_distance(elem.first.first, elem.first.second, HORIZONTAL); - delta_type v_delta = euclidean_distance(elem.first.first, elem.first.second, VERTICAL); - if(h_delta != 0 || v_delta != 0) { - //neither delta is zero and the edge is not MANHATTAN - if(v_delta != h_delta && v_delta != -h_delta) return POLYGON_SET_CONCEPT; - else is_45 = true; - } - } - if(is_45) return POLYGON_45_SET_CONCEPT; - return POLYGON_90_SET_CONCEPT; - } - - private: - mutable value_type data_; - mutable bool dirty_; - mutable bool unsorted_; - mutable bool is_45_; - - private: - //functions - - template <typename output_container> - void get_dispatch(output_container& output, polygon_concept tag) const { - get_fracture(output, true, tag); - } - template <typename output_container> - void get_dispatch(output_container& output, polygon_with_holes_concept tag) const { - get_fracture(output, false, tag); - } - template <typename output_container, typename concept_type> - void get_fracture(output_container& container, bool fracture_holes, concept_type ) const { - clean(); - polygon_arbitrary_formation<coordinate_type> pf(fracture_holes); - typedef typename polygon_arbitrary_formation<coordinate_type>::vertex_half_edge vertex_half_edge; - std::vector<vertex_half_edge> data; - for(iterator_type itr = data_.begin(); itr != data_.end(); ++itr){ - data.push_back(vertex_half_edge((*itr).first.first, (*itr).first.second, (*itr).second)); - data.push_back(vertex_half_edge((*itr).first.second, (*itr).first.first, -1 * (*itr).second)); - } - polygon_sort(data.begin(), data.end()); - pf.scan(container, data.begin(), data.end()); - } - }; - - struct polygon_set_concept; - template <typename T> - struct geometry_concept<polygon_set_data<T> > { - typedef polygon_set_concept type; - }; - -// template <typename T> -// inline double compute_area(point_data<T>& a, point_data<T>& b, point_data<T>& c) { - -// return (double)(b.x()-a.x())*(double)(c.y()-a.y())- (double)(c.x()-a.x())*(double)(b.y()-a.y()); - - -// } - - template <typename T> - inline int make_resizing_vertex_list(std::vector<std::vector<point_data< T> > >& return_points, - point_data<T>& curr_prev, bool ignore_prev_point, - point_data< T> start, point_data<T> middle, point_data< T> end, - double sizing_distance, unsigned int num_circle_segments, bool corner_fill_arc) { - - // handle the case of adding an intersection point - point_data<double> dn1( middle.y()-start.y(), start.x()-middle.x()); - double size = sizing_distance/std::sqrt( dn1.x()*dn1.x()+dn1.y()*dn1.y()); - dn1 = point_data<double>( dn1.x()*size, dn1.y()* size); - point_data<double> dn2( end.y()-middle.y(), middle.x()-end.x()); - size = sizing_distance/std::sqrt( dn2.x()*dn2.x()+dn2.y()*dn2.y()); - dn2 = point_data<double>( dn2.x()*size, dn2.y()* size); - point_data<double> start_offset((start.x()+dn1.x()),(start.y()+dn1.y())); - point_data<double> mid1_offset((middle.x()+dn1.x()),(middle.y()+dn1.y())); - point_data<double> end_offset((end.x()+dn2.x()),(end.y()+dn2.y())); - point_data<double> mid2_offset((middle.x()+dn2.x()),(middle.y()+dn2.y())); - if (ignore_prev_point) - curr_prev = round_down<T>(start_offset); - - - if (corner_fill_arc) { - std::vector<point_data< T> > return_points1; - return_points.push_back(return_points1); - std::vector<point_data< T> >& return_points_back = return_points[return_points.size()-1]; - return_points_back.push_back(round_down<T>(mid1_offset)); - return_points_back.push_back(middle); - return_points_back.push_back(start); - return_points_back.push_back(curr_prev); - point_data<double> dmid(middle.x(),middle.y()); - return_points.push_back(return_points1); - int num = make_arc(return_points[return_points.size()-1],mid1_offset,mid2_offset,dmid,sizing_distance,num_circle_segments); - curr_prev = round_down<T>(mid2_offset); - return num; - - } - - std::pair<point_data<double>,point_data<double> > he1(start_offset,mid1_offset); - std::pair<point_data<double>,point_data<double> > he2(mid2_offset ,end_offset); - //typedef typename high_precision_type<double>::type high_precision; - - point_data<T> intersect; - typename scanline_base<T>::compute_intersection_pack pack; - bool res = pack.compute_intersection(intersect,he1,he2,true); - if( res ) { - std::vector<point_data< T> > return_points1; - return_points.push_back(return_points1); - std::vector<point_data< T> >& return_points_back = return_points[return_points.size()-1]; - return_points_back.push_back(intersect); - return_points_back.push_back(middle); - return_points_back.push_back(start); - return_points_back.push_back(curr_prev); - - //double d1= compute_area(intersect,middle,start); - //double d2= compute_area(start,curr_prev,intersect); - - curr_prev = intersect; - - - return return_points.size(); - } - return 0; - - } - - // this routine should take in start and end point s.t. end point is CCW from start - // it sould make a pie slice polygon that is an intersection of that arc - // with an ngon segments approximation of the circle centered at center with radius r - // point start is gauaranteed to be on the segmentation - // returnPoints will start with the first point after start - // returnPoints vector may be empty - template <typename T> - inline int make_arc(std::vector<point_data< T> >& return_points, - point_data< double> start, point_data< double> end, - point_data< double> center, double r, unsigned int num_circle_segments) { - const double our_pi=3.1415926535897932384626433832795028841971; - - // derive start and end angles - double ps = atan2(start.y()-center.y(), start.x()-center.x()); - double pe = atan2(end.y()-center.y(), end.x()-center.x()); - if (ps < 0.0) - ps += 2.0 * our_pi; - if (pe <= 0.0) - pe += 2.0 * our_pi; - if (ps >= 2.0 * our_pi) - ps -= 2.0 * our_pi; - while (pe <= ps) - pe += 2.0 * our_pi; - double delta_angle = (2.0 * our_pi) / (double)num_circle_segments; - if ( start==end) // full circle? - { - ps = delta_angle*0.5; - pe = ps + our_pi * 2.0; - double x,y; - x = center.x() + r * cos(ps); - y = center.y() + r * sin(ps); - start = point_data<double>(x,y); - end = start; - } - return_points.push_back(round_down<T>(center)); - return_points.push_back(round_down<T>(start)); - unsigned int i=0; - double curr_angle = ps+delta_angle; - while( curr_angle < pe - 0.01 && i < 2 * num_circle_segments) { - i++; - double x = center.x() + r * cos( curr_angle); - double y = center.y() + r * sin( curr_angle); - return_points.push_back( round_down<T>((point_data<double>(x,y)))); - curr_angle+=delta_angle; - } - return_points.push_back(round_down<T>(end)); - return return_points.size(); - } - -}// close namespace -}// close name space - -#include "detail/scan_arbitrary.hpp" - -namespace boost { namespace polygon { - //ConnectivityExtraction computes the graph of connectivity between rectangle, polygon and - //polygon set graph nodes where an edge is created whenever the geometry in two nodes overlap - template <typename coordinate_type> - class connectivity_extraction{ - private: - typedef arbitrary_connectivity_extraction<coordinate_type, int> ce; - ce ce_; - unsigned int nodeCount_; - public: - inline connectivity_extraction() : ce_(), nodeCount_(0) {} - inline connectivity_extraction(const connectivity_extraction& that) : ce_(that.ce_), - nodeCount_(that.nodeCount_) {} - inline connectivity_extraction& operator=(const connectivity_extraction& that) { - ce_ = that.ce_; - nodeCount_ = that.nodeCount_; {} - return *this; - } - - //insert a polygon set graph node, the value returned is the id of the graph node - inline unsigned int insert(const polygon_set_data<coordinate_type>& ps) { - ps.clean(); - ce_.populateTouchSetData(ps.begin(), ps.end(), nodeCount_); - return nodeCount_++; - } - template <class GeoObjT> - inline unsigned int insert(const GeoObjT& geoObj) { - polygon_set_data<coordinate_type> ps; - ps.insert(geoObj); - return insert(ps); - } - - //extract connectivity and store the edges in the graph - //graph must be indexable by graph node id and the indexed value must be a std::set of - //graph node id - template <class GraphT> - inline void extract(GraphT& graph) { - ce_.execute(graph); - } - }; - - template <typename T> - polygon_set_data<T>& - polygon_set_data<T>::interact(const polygon_set_data<T>& that) { - connectivity_extraction<coordinate_type> ce; - std::vector<polygon_with_holes_data<T> > polys; - get(polys); - clear(); - for(std::size_t i = 0; i < polys.size(); ++i) { - ce.insert(polys[i]); - } - int id = ce.insert(that); - std::vector<std::set<int> > graph(id+1); - ce.extract(graph); - for(std::set<int>::iterator itr = graph[id].begin(); - itr != graph[id].end(); ++itr) { - insert(polys[*itr]); - } - return *this; - } -} -} - -#include "polygon_set_traits.hpp" -#include "detail/polygon_set_view.hpp" - -#include "polygon_set_concept.hpp" -#include "detail/minkowski.hpp" -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_set_traits.hpp b/contrib/restricted/boost/boost/polygon/polygon_set_traits.hpp deleted file mode 100644 index b68bbc1390..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_set_traits.hpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - 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_POLYGON_SET_TRAITS_HPP -#define BOOST_POLYGON_POLYGON_SET_TRAITS_HPP -namespace boost { namespace polygon{ - - struct polygon_set_concept {}; - - //default definition of polygon set traits works for any model of polygon , polygon with holes or any vector or list thereof - template <typename T> - struct polygon_set_traits { - typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type; - typedef typename get_iterator_type<T>::type iterator_type; - typedef T operator_arg_type; - - static inline iterator_type begin(const T& polygon_set) { - return get_iterator_type<T>::begin(polygon_set); - } - - static inline iterator_type end(const T& polygon_set) { - return get_iterator_type<T>::end(polygon_set); - } - - static inline bool clean(const T& ) { return false; } - - static inline bool sorted(const T& ) { return false; } - }; - - template <typename T> - struct is_polygonal_concept { typedef gtl_no type; }; - template <> - struct is_polygonal_concept<polygon_concept> { typedef gtl_yes type; }; - template <> - struct is_polygonal_concept<polygon_with_holes_concept> { typedef gtl_yes type; }; - template <> - struct is_polygonal_concept<polygon_set_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_polygon_set_type { - typedef typename is_polygonal_concept<typename geometry_concept<T>::type>::type type; - }; - template <typename T> - struct is_polygon_set_type<std::list<T> > { - typedef typename gtl_or< - typename is_polygonal_concept<typename geometry_concept<std::list<T> >::type>::type, - typename is_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; - }; - template <typename T> - struct is_polygon_set_type<std::vector<T> > { - typedef typename gtl_or< - typename is_polygonal_concept<typename geometry_concept<std::vector<T> >::type>::type, - typename is_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; - }; - - template <typename T> - struct is_mutable_polygon_set_type { - typedef typename gtl_same_type<polygon_set_concept, typename geometry_concept<T>::type>::type type; - }; - template <typename T> - struct is_mutable_polygon_set_type<std::list<T> > { - typedef typename gtl_or< - typename gtl_same_type<polygon_set_concept, typename geometry_concept<std::list<T> >::type>::type, - typename is_polygonal_concept<typename geometry_concept<typename std::list<T>::value_type>::type>::type>::type type; - }; - template <typename T> - struct is_mutable_polygon_set_type<std::vector<T> > { - typedef typename gtl_or< - typename gtl_same_type<polygon_set_concept, typename geometry_concept<std::vector<T> >::type>::type, - typename is_polygonal_concept<typename geometry_concept<typename std::vector<T>::value_type>::type>::type>::type type; - }; - - template <typename T> - struct polygon_set_mutable_traits {}; - template <typename T> - struct polygon_set_mutable_traits<std::list<T> > { - template <typename input_iterator_type> - static inline void set(std::list<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) { - polygon_set.clear(); - polygon_set_data<typename polygon_set_traits<std::list<T> >::coordinate_type> ps; - ps.reserve(std::distance(input_begin, input_end)); - ps.insert(input_begin, input_end); - ps.get(polygon_set); - } - }; - template <typename T> - struct polygon_set_mutable_traits<std::vector<T> > { - template <typename input_iterator_type> - static inline void set(std::vector<T>& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) { - polygon_set.clear(); - size_t num_ele = std::distance(input_begin, input_end); - polygon_set.reserve(num_ele); - polygon_set_data<typename polygon_set_traits<std::list<T> >::coordinate_type> ps; - ps.reserve(num_ele); - ps.insert(input_begin, input_end); - ps.get(polygon_set); - } - }; - - template <typename T> - struct polygon_set_mutable_traits<polygon_set_data<T> > { - template <typename input_iterator_type> - static inline void set(polygon_set_data<T>& polygon_set, - input_iterator_type input_begin, input_iterator_type input_end) { - polygon_set.set(input_begin, input_end); - } - }; - template <typename T> - struct polygon_set_traits<polygon_set_data<T> > { - typedef typename polygon_set_data<T>::coordinate_type coordinate_type; - typedef typename polygon_set_data<T>::iterator_type iterator_type; - typedef typename polygon_set_data<T>::operator_arg_type operator_arg_type; - - static inline iterator_type begin(const polygon_set_data<T>& polygon_set) { - return polygon_set.begin(); - } - - static inline iterator_type end(const polygon_set_data<T>& polygon_set) { - return polygon_set.end(); - } - - static inline bool clean(const polygon_set_data<T>& polygon_set) { polygon_set.clean(); return true; } - - static inline bool sorted(const polygon_set_data<T>& polygon_set) { polygon_set.sort(); return true; } - - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_traits.hpp b/contrib/restricted/boost/boost/polygon/polygon_traits.hpp deleted file mode 100644 index 692e9f14b1..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_traits.hpp +++ /dev/null @@ -1,1861 +0,0 @@ -/* - 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_POLYGON_TRAITS_HPP -#define BOOST_POLYGON_POLYGON_TRAITS_HPP -namespace boost { namespace polygon{ - - template <typename T, typename enable = gtl_yes> - struct polygon_90_traits { - typedef typename T::coordinate_type coordinate_type; - typedef typename T::compact_iterator_type compact_iterator_type; - - // Get the begin iterator - static inline compact_iterator_type begin_compact(const T& t) { - return t.begin_compact(); - } - - // Get the end iterator - static inline compact_iterator_type end_compact(const T& t) { - return t.end_compact(); - } - - // Get the number of sides of the polygon - static inline std::size_t size(const T& t) { - return t.size(); - } - - // Get the winding direction of the polygon - static inline winding_direction winding(const T&) { - return unknown_winding; - } - }; - - template <typename T> - struct polygon_traits_general { - typedef typename T::coordinate_type coordinate_type; - typedef typename T::iterator_type iterator_type; - typedef typename T::point_type point_type; - - // Get the begin iterator - static inline iterator_type begin_points(const T& t) { - return t.begin(); - } - - // Get the end iterator - static inline iterator_type end_points(const T& t) { - return t.end(); - } - - // Get the number of sides of the polygon - static inline std::size_t size(const T& t) { - return t.size(); - } - - // Get the winding direction of the polygon - static inline winding_direction winding(const T&) { - return unknown_winding; - } - }; - - template <typename T> - struct polygon_traits_90 { - typedef typename polygon_90_traits<T>::coordinate_type coordinate_type; - typedef iterator_compact_to_points<typename polygon_90_traits<T>::compact_iterator_type, point_data<coordinate_type> > iterator_type; - typedef point_data<coordinate_type> point_type; - - // Get the begin iterator - static inline iterator_type begin_points(const T& t) { - return iterator_type(polygon_90_traits<T>::begin_compact(t), - polygon_90_traits<T>::end_compact(t)); - } - - // Get the end iterator - static inline iterator_type end_points(const T& t) { - return iterator_type(polygon_90_traits<T>::end_compact(t), - polygon_90_traits<T>::end_compact(t)); - } - - // Get the number of sides of the polygon - static inline std::size_t size(const T& t) { - return polygon_90_traits<T>::size(t); - } - - // Get the winding direction of the polygon - static inline winding_direction winding(const T& t) { - return polygon_90_traits<T>::winding(t); - } - }; - -#ifndef BOOST_VERY_LITTLE_SFINAE - - template <typename T, typename enable = gtl_yes> - struct polygon_traits {}; - - template <typename T> - struct polygon_traits<T, - typename gtl_or_4< - typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type - >::type> : public polygon_traits_general<T> {}; - - template <typename T> - struct polygon_traits< T, - typename gtl_or< - typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type - >::type > : public polygon_traits_90<T> {}; - -#else - - template <typename T, typename T_IF, typename T_ELSE> - struct gtl_ifelse {}; - template <typename T_IF, typename T_ELSE> - struct gtl_ifelse<gtl_no, T_IF, T_ELSE> { - typedef T_ELSE type; - }; - template <typename T_IF, typename T_ELSE> - struct gtl_ifelse<gtl_yes, T_IF, T_ELSE> { - typedef T_IF type; - }; - - template <typename T, typename enable = gtl_yes> - struct polygon_traits {}; - - template <typename T> - struct polygon_traits<T, typename gtl_or<typename gtl_or_4< - typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type - >::type, typename gtl_or< - typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type - >::type>::type > : public gtl_ifelse<typename gtl_or< - typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type, - typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type >::type, - polygon_traits_90<T>, - polygon_traits_general<T> >::type { - }; - -#endif - - template <typename T, typename enable = void> - struct polygon_with_holes_traits { - typedef typename T::iterator_holes_type iterator_holes_type; - typedef typename T::hole_type hole_type; - - // Get the begin iterator - static inline iterator_holes_type begin_holes(const T& t) { - return t.begin_holes(); - } - - // Get the end iterator - static inline iterator_holes_type end_holes(const T& t) { - return t.end_holes(); - } - - // Get the number of holes - static inline std::size_t size_holes(const T& t) { - return t.size_holes(); - } - }; - - template <typename T, typename enable = void> - struct polygon_90_mutable_traits { - - // Set the data of a polygon with the unique coordinates in an iterator, starting with an x - template <typename iT> - static inline T& set_compact(T& t, iT input_begin, iT input_end) { - t.set_compact(input_begin, input_end); - return t; - } - - }; - - template <typename T, typename enable = void> - struct polygon_mutable_traits { - - // Set the data of a polygon with the unique coordinates in an iterator, starting with an x - template <typename iT> - static inline T& set_points(T& t, iT input_begin, iT input_end) { - t.set(input_begin, input_end); - return t; - } - - }; - - template <typename T, typename enable = void> - struct polygon_with_holes_mutable_traits { - - // Set the data of a polygon with the unique coordinates in an iterator, starting with an x - template <typename iT> - static inline T& set_holes(T& t, iT inputBegin, iT inputEnd) { - t.set_holes(inputBegin, inputEnd); - return t; - } - - }; -} -} -#include "isotropy.hpp" - -//point -#include "point_data.hpp" -#include "point_traits.hpp" -#include "point_concept.hpp" - -//interval -#include "interval_data.hpp" -#include "interval_traits.hpp" -#include "interval_concept.hpp" - -//rectangle -#include "rectangle_data.hpp" -#include "rectangle_traits.hpp" -#include "rectangle_concept.hpp" - -//algorithms needed by polygon types -#include "detail/iterator_points_to_compact.hpp" -#include "detail/iterator_compact_to_points.hpp" - -//polygons -#include "polygon_45_data.hpp" -#include "polygon_data.hpp" -#include "polygon_90_data.hpp" -#include "polygon_90_with_holes_data.hpp" -#include "polygon_45_with_holes_data.hpp" -#include "polygon_with_holes_data.hpp" - -namespace boost { namespace polygon{ - struct polygon_concept {}; - struct polygon_with_holes_concept {}; - struct polygon_45_concept {}; - struct polygon_45_with_holes_concept {}; - struct polygon_90_concept {}; - struct polygon_90_with_holes_concept {}; - - - template <typename T> - struct is_polygon_90_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_90_concept, GC>::type type; - }; - - template <typename T> - struct is_polygon_45_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_or<typename is_polygon_90_type<T>::type, - typename gtl_same_type<polygon_45_concept, GC>::type>::type type; - }; - - template <typename T> - struct is_polygon_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_or<typename is_polygon_45_type<T>::type, - typename gtl_same_type<polygon_concept, GC>::type>::type type; - }; - - template <typename T> - struct is_polygon_90_with_holes_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_or<typename is_polygon_90_type<T>::type, - typename gtl_same_type<polygon_90_with_holes_concept, GC>::type>::type type; - }; - - template <typename T> - struct is_polygon_45_with_holes_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_or_3<typename is_polygon_90_with_holes_type<T>::type, - typename is_polygon_45_type<T>::type, - typename gtl_same_type<polygon_45_with_holes_concept, GC>::type>::type type; - }; - - template <typename T> - struct is_polygon_with_holes_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_or_3<typename is_polygon_45_with_holes_type<T>::type, - typename is_polygon_type<T>::type, - typename gtl_same_type<polygon_with_holes_concept, GC>::type>::type type; - }; - - template <typename T> - struct is_mutable_polygon_90_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_90_concept, GC>::type type; - }; - - template <typename T> - struct is_mutable_polygon_45_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_45_concept, GC>::type type; - }; - - template <typename T> - struct is_mutable_polygon_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_concept, GC>::type type; - }; - - template <typename T> - struct is_mutable_polygon_90_with_holes_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_90_with_holes_concept, GC>::type type; - }; - - template <typename T> - struct is_mutable_polygon_45_with_holes_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_45_with_holes_concept, GC>::type type; - }; - - template <typename T> - struct is_mutable_polygon_with_holes_type { - typedef typename geometry_concept<T>::type GC; - typedef typename gtl_same_type<polygon_with_holes_concept, GC>::type type; - }; - - template <typename T> - struct is_any_mutable_polygon_with_holes_type { - typedef typename gtl_or_3<typename is_mutable_polygon_90_with_holes_type<T>::type, - typename is_mutable_polygon_45_with_holes_type<T>::type, - typename is_mutable_polygon_with_holes_type<T>::type>::type type; - }; - template <typename T> - struct is_any_mutable_polygon_without_holes_type { - typedef typename gtl_or_3< - typename is_mutable_polygon_90_type<T>::type, - typename is_mutable_polygon_45_type<T>::type, - typename is_mutable_polygon_type<T>::type>::type type; }; - - template <typename T> - struct is_any_mutable_polygon_type { - typedef typename gtl_or<typename is_any_mutable_polygon_with_holes_type<T>::type, - typename is_any_mutable_polygon_without_holes_type<T>::type>::type type; - }; - - template <typename T> - struct polygon_from_polygon_with_holes_type {}; - template <> - struct polygon_from_polygon_with_holes_type<polygon_with_holes_concept> { typedef polygon_concept type; }; - template <> - struct polygon_from_polygon_with_holes_type<polygon_45_with_holes_concept> { typedef polygon_45_concept type; }; - template <> - struct polygon_from_polygon_with_holes_type<polygon_90_with_holes_concept> { typedef polygon_90_concept type; }; - - template <> - struct geometry_domain<polygon_45_concept> { typedef forty_five_domain type; }; - template <> - struct geometry_domain<polygon_45_with_holes_concept> { typedef forty_five_domain type; }; - template <> - struct geometry_domain<polygon_90_concept> { typedef manhattan_domain type; }; - template <> - struct geometry_domain<polygon_90_with_holes_concept> { typedef manhattan_domain type; }; - - template <typename domain_type, typename coordinate_type> - struct distance_type_by_domain { typedef typename coordinate_traits<coordinate_type>::coordinate_distance type; }; - template <typename coordinate_type> - struct distance_type_by_domain<manhattan_domain, coordinate_type> { - typedef typename coordinate_traits<coordinate_type>::coordinate_difference type; }; - - // \brief Sets the boundary of the polygon to the points in the iterator range - // \tparam T A type that models polygon_concept - // \tparam iT Iterator type over objects that model point_concept - // \param t The polygon to set - // \param begin_points The start of the range of points - // \param end_points The end of the range of points - - /// \relatesalso polygon_concept - template <typename T, typename iT> - typename enable_if <typename is_any_mutable_polygon_type<T>::type, T>::type & - set_points(T& t, iT begin_points, iT end_points) { - polygon_mutable_traits<T>::set_points(t, begin_points, end_points); - return t; - } - - // \brief Sets the boundary of the polygon to the non-redundant coordinates in the iterator range - // \tparam T A type that models polygon_90_concept - // \tparam iT Iterator type over objects that model coordinate_concept - // \param t The polygon to set - // \param begin_compact_coordinates The start of the range of coordinates - // \param end_compact_coordinates The end of the range of coordinates - -/// \relatesalso polygon_90_concept - template <typename T, typename iT> - typename enable_if <typename gtl_or< - typename is_mutable_polygon_90_type<T>::type, - typename is_mutable_polygon_90_with_holes_type<T>::type>::type, T>::type & - set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) { - polygon_90_mutable_traits<T>::set_compact(t, begin_compact_coordinates, end_compact_coordinates); - return t; - } - -/// \relatesalso polygon_with_holes_concept - template <typename T, typename iT> - typename enable_if< typename gtl_and < - typename is_any_mutable_polygon_with_holes_type<T>::type, - typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, - manhattan_domain>::type>::type, - T>::type & - set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) { - iterator_compact_to_points<iT, point_data<typename polygon_traits<T>::coordinate_type> > - itrb(begin_compact_coordinates, end_compact_coordinates), - itre(end_compact_coordinates, end_compact_coordinates); - return set_points(t, itrb, itre); - } - -/// \relatesalso polygon_with_holes_concept - template <typename T, typename iT> - typename enable_if <typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type & - set_holes(T& t, iT begin_holes, iT end_holes) { - polygon_with_holes_mutable_traits<T>::set_holes(t, begin_holes, end_holes); - return t; - } - -/// \relatesalso polygon_90_concept - template <typename T> - typename polygon_90_traits<T>::compact_iterator_type - begin_compact(const T& polygon, - typename enable_if< - typename gtl_and <typename is_polygon_with_holes_type<T>::type, - typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type, - manhattan_domain>::type>::type>::type * = 0 - ) { - return polygon_90_traits<T>::begin_compact(polygon); - } - -/// \relatesalso polygon_90_concept - template <typename T> - typename polygon_90_traits<T>::compact_iterator_type - end_compact(const T& polygon, - typename enable_if< - typename gtl_and <typename is_polygon_with_holes_type<T>::type, - typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type, - manhattan_domain>::type>::type>::type * = 0 - ) { - return polygon_90_traits<T>::end_compact(polygon); - } - - /// \relatesalso polygon_concept - template <typename T> - typename enable_if < typename gtl_if< - typename is_polygon_with_holes_type<T>::type>::type, - typename polygon_traits<T>::iterator_type>::type - begin_points(const T& polygon) { - return polygon_traits<T>::begin_points(polygon); - } - - /// \relatesalso polygon_concept - template <typename T> - typename enable_if < typename gtl_if< - typename is_polygon_with_holes_type<T>::type>::type, - typename polygon_traits<T>::iterator_type>::type - end_points(const T& polygon) { - return polygon_traits<T>::end_points(polygon); - } - - /// \relatesalso polygon_concept - template <typename T> - typename enable_if <typename is_polygon_with_holes_type<T>::type, - std::size_t>::type - size(const T& polygon) { - return polygon_traits<T>::size(polygon); - } - -/// \relatesalso polygon_with_holes_concept - template <typename T> - typename enable_if < typename gtl_if< - typename is_polygon_with_holes_type<T>::type>::type, - typename polygon_with_holes_traits<T>::iterator_holes_type>::type - begin_holes(const T& polygon) { - return polygon_with_holes_traits<T>::begin_holes(polygon); - } - -/// \relatesalso polygon_with_holes_concept - template <typename T> - typename enable_if < typename gtl_if< - typename is_polygon_with_holes_type<T>::type>::type, - typename polygon_with_holes_traits<T>::iterator_holes_type>::type - end_holes(const T& polygon) { - return polygon_with_holes_traits<T>::end_holes(polygon); - } - -/// \relatesalso polygon_with_holes_concept - template <typename T> - typename enable_if <typename is_polygon_with_holes_type<T>::type, - std::size_t>::type - size_holes(const T& polygon) { - return polygon_with_holes_traits<T>::size_holes(polygon); - } - - // \relatesalso polygon_concept - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_polygon_type<T1>::type, - typename is_polygon_type<T2>::type>::type, T1>::type & - assign(T1& lvalue, const T2& rvalue) { - polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue), - polygon_traits<T2>::end_points(rvalue)); - return lvalue; - } - -// \relatesalso polygon_with_holes_concept - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_polygon_with_holes_type<T1>::type, - typename is_polygon_with_holes_type<T2>::type>::type, T1>::type & - assign(T1& lvalue, const T2& rvalue) { - polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue), - polygon_traits<T2>::end_points(rvalue)); - polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue), - polygon_with_holes_traits<T2>::end_holes(rvalue)); - return lvalue; - } - - // \relatesalso polygon_45_concept - template <typename T1, typename T2> - typename enable_if< typename gtl_and< typename is_mutable_polygon_45_type<T1>::type, typename is_polygon_45_type<T2>::type>::type, T1>::type & - assign(T1& lvalue, const T2& rvalue) { - polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue), - polygon_traits<T2>::end_points(rvalue)); - return lvalue; - } - -// \relatesalso polygon_45_with_holes_concept - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_polygon_45_with_holes_type<T1>::type, - typename is_polygon_45_with_holes_type<T2>::type>::type, T1>::type & - assign(T1& lvalue, const T2& rvalue) { - polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue), - polygon_traits<T2>::end_points(rvalue)); - polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue), - polygon_with_holes_traits<T2>::end_holes(rvalue)); - return lvalue; - } - - // \relatesalso polygon_90_concept - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_polygon_90_type<T1>::type, - typename is_polygon_90_type<T2>::type>::type, T1>::type & - assign(T1& lvalue, const T2& rvalue) { - polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue), - polygon_90_traits<T2>::end_compact(rvalue)); - return lvalue; - } - -// \relatesalso polygon_90_with_holes_concept - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_polygon_90_with_holes_type<T1>::type, - typename is_polygon_90_with_holes_type<T2>::type>::type, T1>::type & - assign(T1& lvalue, const T2& rvalue) { - polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue), - polygon_90_traits<T2>::end_compact(rvalue)); - polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue), - polygon_with_holes_traits<T2>::end_holes(rvalue)); - return lvalue; - } - - // \relatesalso polygon_90_concept - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_type<T1>::type, - typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, T1>::type & - assign(T1& polygon, const T2& rect) { - typedef point_data<typename polygon_traits<T1>::coordinate_type> PT; - PT points[4] = {PT(xl(rect), yl(rect)), PT(xh(rect), yl(rect)), PT(xh(rect), yh(rect)), PT(xl(rect), yh(rect))}; - set_points(polygon, points, points+4); - return polygon; - } - -/// \relatesalso polygon_90_concept - template <typename polygon_type, typename point_type> - typename enable_if< typename gtl_and< typename is_mutable_polygon_90_type<polygon_type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - polygon_type>::type & - convolve(polygon_type& polygon, const point_type& point) { - std::vector<typename polygon_90_traits<polygon_type>::coordinate_type> coords; - coords.reserve(size(polygon)); - bool pingpong = true; - for(typename polygon_90_traits<polygon_type>::compact_iterator_type iter = begin_compact(polygon); - iter != end_compact(polygon); ++iter) { - coords.push_back((*iter) + (pingpong ? x(point) : y(point))); - pingpong = !pingpong; - } - polygon_90_mutable_traits<polygon_type>::set_compact(polygon, coords.begin(), coords.end()); - return polygon; - } - -/// \relatesalso polygon_concept - template <typename polygon_type, typename point_type> - typename enable_if< typename gtl_and< typename gtl_or< - typename is_mutable_polygon_45_type<polygon_type>::type, - typename is_mutable_polygon_type<polygon_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - polygon_type>::type & - convolve(polygon_type& polygon, const point_type& point) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - convolve(points.back(), point); - } - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - -/// \relatesalso polygon_with_holes_concept - template <typename polygon_type, typename point_type> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - polygon_type>::type & - convolve(polygon_type& polygon, const point_type& point) { - typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type; - hole_type h; - set_points(h, begin_points(polygon), end_points(polygon)); - convolve(h, point); - std::vector<hole_type> holes; - holes.reserve(size_holes(polygon)); - for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon); - itr != end_holes(polygon); ++itr) { - holes.push_back(*itr); - convolve(holes.back(), point); - } - assign(polygon, h); - set_holes(polygon, holes.begin(), holes.end()); - return polygon; - } - -/// \relatesalso polygon_concept - template <typename T> - typename enable_if< typename is_any_mutable_polygon_type<T>::type, T>::type & - move(T& polygon, orientation_2d orient, typename polygon_traits<T>::coordinate_type displacement) { - typedef typename polygon_traits<T>::coordinate_type Unit; - if(orient == HORIZONTAL) return convolve(polygon, point_data<Unit>(displacement, Unit(0))); - return convolve(polygon, point_data<Unit>(Unit(0), displacement)); - } - -/// \relatesalso polygon_concept -/// \brief Applies a transformation to the polygon. -/// \tparam polygon_type A type that models polygon_concept -/// \tparam transform_type A type that may be either axis_transformation or transformation or that overloads point_concept::transform -/// \param polygon The polygon to transform -/// \param tr The transformation to apply - template <typename polygon_type, typename transform_type> - typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type & - transform(polygon_type& polygon, const transform_type& tr) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - transform(points.back(), tr); - } - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - -/// \relatesalso polygon_with_holes_concept - template <typename T, typename transform_type> - typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type & - transform(T& polygon, const transform_type& tr) { - typedef typename polygon_with_holes_traits<T>::hole_type hole_type; - hole_type h; - set_points(h, begin_points(polygon), end_points(polygon)); - transform(h, tr); - std::vector<hole_type> holes; - holes.reserve(size_holes(polygon)); - for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon); - itr != end_holes(polygon); ++itr) { - holes.push_back(*itr); - transform(holes.back(), tr); - } - assign(polygon, h); - set_holes(polygon, holes.begin(), holes.end()); - return polygon; - } - - template <typename polygon_type> - typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type & - scale_up(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - scale_up(points.back(), factor); - } - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - - template <typename T> - typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type & - scale_up(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) { - typedef typename polygon_with_holes_traits<T>::hole_type hole_type; - hole_type h; - set_points(h, begin_points(polygon), end_points(polygon)); - scale_up(h, factor); - std::vector<hole_type> holes; - holes.reserve(size_holes(polygon)); - for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon); - itr != end_holes(polygon); ++itr) { - holes.push_back(*itr); - scale_up(holes.back(), factor); - } - assign(polygon, h); - set_holes(polygon, holes.begin(), holes.end()); - return polygon; - } - - //scale non-45 down - template <typename polygon_type> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, - typename gtl_not<typename gtl_same_type - < forty_five_domain, - typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type, - polygon_type>::type & - scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - scale_down(points.back(), factor); - } - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - - template <typename Unit> - Unit local_abs(Unit value) { return value < 0 ? (Unit)-value : value; } - - template <typename Unit> - void snap_point_vector_to_45(std::vector<point_data<Unit> >& pts) { - typedef point_data<Unit> Point; - if(pts.size() < 3) { pts.clear(); return; } - typename std::vector<point_data<Unit> >::iterator endLocation = std::unique(pts.begin(), pts.end()); - if(endLocation != pts.end()){ - pts.resize(endLocation - pts.begin()); - } - if(pts.back() == pts[0]) pts.pop_back(); - //iterate over point triplets - int numPts = pts.size(); - bool wrap_around = false; - for(int i = 0; i < numPts; ++i) { - Point& pt1 = pts[i]; - Point& pt2 = pts[(i + 1) % numPts]; - Point& pt3 = pts[(i + 2) % numPts]; - //check if non-45 edge - Unit deltax = x(pt2) - x(pt1); - Unit deltay = y(pt2) - y(pt1); - if(deltax && deltay && - local_abs(deltax) != local_abs(deltay)) { - //adjust the middle point - Unit ndx = x(pt3) - x(pt2); - Unit ndy = y(pt3) - y(pt2); - if(ndx && ndy) { - Unit diff = local_abs(local_abs(deltax) - local_abs(deltay)); - Unit halfdiff = diff/2; - if((deltax > 0 && deltay > 0) || - (deltax < 0 && deltay < 0)) { - //previous edge is rising slope - if(local_abs(deltax + halfdiff + (diff % 2)) == - local_abs(deltay - halfdiff)) { - x(pt2, x(pt2) + halfdiff + (diff % 2)); - y(pt2, y(pt2) - halfdiff); - } else if(local_abs(deltax - halfdiff - (diff % 2)) == - local_abs(deltay + halfdiff)) { - x(pt2, x(pt2) - halfdiff - (diff % 2)); - y(pt2, y(pt2) + halfdiff); - } else{ - //std::cout << "fail1\n"; - } - } else { - //previous edge is falling slope - if(local_abs(deltax + halfdiff + (diff % 2)) == - local_abs(deltay + halfdiff)) { - x(pt2, x(pt2) + halfdiff + (diff % 2)); - y(pt2, y(pt2) + halfdiff); - } else if(local_abs(deltax - halfdiff - (diff % 2)) == - local_abs(deltay - halfdiff)) { - x(pt2, x(pt2) - halfdiff - (diff % 2)); - y(pt2, y(pt2) - halfdiff); - } else { - //std::cout << "fail2\n"; - } - } - if(i == numPts - 1 && (diff % 2)) { - //we have a wrap around effect - if(!wrap_around) { - wrap_around = true; - i = -1; - } - } - } else if(ndx) { - //next edge is horizontal - //find the x value for pt1 that would make the abs(deltax) == abs(deltay) - Unit newDeltaX = local_abs(deltay); - if(deltax < 0) newDeltaX *= -1; - x(pt2, x(pt1) + newDeltaX); - } else { //ndy - //next edge is vertical - //find the y value for pt1 that would make the abs(deltax) == abs(deltay) - Unit newDeltaY = local_abs(deltax); - if(deltay < 0) newDeltaY *= -1; - y(pt2, y(pt1) + newDeltaY); - } - } - } - } - - template <typename polygon_type> - typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type & - snap_to_45(polygon_type& polygon) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - } - snap_point_vector_to_45(points); - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - - template <typename polygon_type> - typename enable_if< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type, polygon_type>::type & - snap_to_45(polygon_type& polygon) { - typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type; - hole_type h; - set_points(h, begin_points(polygon), end_points(polygon)); - snap_to_45(h); - std::vector<hole_type> holes; - holes.reserve(size_holes(polygon)); - for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon); - itr != end_holes(polygon); ++itr) { - holes.push_back(*itr); - snap_to_45(holes.back()); - } - assign(polygon, h); - set_holes(polygon, holes.begin(), holes.end()); - return polygon; - } - - //scale specifically 45 down - template <typename polygon_type> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, - typename gtl_same_type - < forty_five_domain, - typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type, - polygon_type>::type & - scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - scale_down(points.back(), factor); - } - snap_point_vector_to_45(points); - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - - template <typename T> - typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type & - scale_down(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) { - typedef typename polygon_with_holes_traits<T>::hole_type hole_type; - hole_type h; - set_points(h, begin_points(polygon), end_points(polygon)); - scale_down(h, factor); - std::vector<hole_type> holes; - holes.reserve(size_holes(polygon)); - for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon); - itr != end_holes(polygon); ++itr) { - holes.push_back(*itr); - scale_down(holes.back(), factor); - } - assign(polygon, h); - set_holes(polygon, holes.begin(), holes.end()); - return polygon; - } - - //scale non-45 - template <typename polygon_type> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, - typename gtl_not<typename gtl_same_type - < forty_five_domain, - typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type, - polygon_type>::type & - scale(polygon_type& polygon, double factor) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - scale(points.back(), anisotropic_scale_factor<double>(factor, factor)); - } - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - - //scale specifically 45 - template <typename polygon_type> - polygon_type& - scale(polygon_type& polygon, double factor, - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, - typename gtl_same_type - < forty_five_domain, - typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type * = 0 - ) { - std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points; - points.reserve(size(polygon)); - for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); - iter != end_points(polygon); ++iter) { - points.push_back(*iter); - scale(points.back(), anisotropic_scale_factor<double>(factor, factor)); - } - snap_point_vector_to_45(points); - polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end()); - return polygon; - } - - template <typename T> - T& - scale(T& polygon, double factor, - typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type>::type * = 0 - ) { - typedef typename polygon_with_holes_traits<T>::hole_type hole_type; - hole_type h; - set_points(h, begin_points(polygon), end_points(polygon)); - scale(h, factor); - std::vector<hole_type> holes; - holes.reserve(size_holes(polygon)); - for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon); - itr != end_holes(polygon); ++itr) { - holes.push_back(*itr); - scale(holes.back(), factor); - } - assign(polygon, h); - set_holes(polygon, holes.begin(), holes.end()); - return polygon; - } - - template <typename iterator_type, typename area_type> - static area_type - point_sequence_area(iterator_type begin_range, iterator_type end_range) { - typedef typename std::iterator_traits<iterator_type>::value_type point_type; - if(begin_range == end_range) return area_type(0); - point_type first = *begin_range; - point_type previous = first; - ++begin_range; - // Initialize trapezoid base line - area_type y_base = (area_type)y(first); - // Initialize area accumulator - - area_type area(0); - while (begin_range != end_range) { - area_type x1 = (area_type)x(previous); - area_type x2 = (area_type)x(*begin_range); -#ifdef BOOST_POLYGON_ICC -#pragma warning (push) -#pragma warning (disable:1572) -#endif - if(x1 != x2) { -#ifdef BOOST_POLYGON_ICC -#pragma warning (pop) -#endif - // do trapezoid area accumulation - area += (x2 - x1) * (((area_type)y(*begin_range) - y_base) + - ((area_type)y(previous) - y_base)) / 2; - } - previous = *begin_range; - // go to next point - ++begin_range; - } - //wrap around to evaluate the edge between first and last if not closed - if(!equivalence(first, previous)) { - area_type x1 = (area_type)x(previous); - area_type x2 = (area_type)x(first); - area += (x2 - x1) * (((area_type)y(first) - y_base) + - ((area_type)y(previous) - y_base)) / 2; - } - return area; - } - - template <typename T> - typename enable_if< - typename is_polygon_with_holes_type<T>::type, - typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type, - typename polygon_traits<T>::coordinate_type>::type>::type - area(const T& polygon) { - typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type, - typename polygon_traits<T>::coordinate_type>::type area_type; - area_type retval = point_sequence_area<typename polygon_traits<T>::iterator_type, area_type> - (begin_points(polygon), end_points(polygon)); - if(retval < 0) retval *= -1; - for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = - polygon_with_holes_traits<T>::begin_holes(polygon); - itr != polygon_with_holes_traits<T>::end_holes(polygon); ++itr) { - area_type tmp_area = point_sequence_area - <typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type, area_type> - (begin_points(*itr), end_points(*itr)); - if(tmp_area < 0) tmp_area *= -1; - retval -= tmp_area; - } - return retval; - } - - template <typename iT> - bool point_sequence_is_45(iT itr, iT itr_end) { - typedef typename std::iterator_traits<iT>::value_type Point; - typedef typename point_traits<Point>::coordinate_type Unit; - if(itr == itr_end) return true; - Point firstPt = *itr; - Point prevPt = firstPt; - ++itr; - while(itr != itr_end) { - Point pt = *itr; - Unit deltax = x(pt) - x(prevPt); - Unit deltay = y(pt) - y(prevPt); - if(deltax && deltay && - local_abs(deltax) != local_abs(deltay)) - return false; - prevPt = pt; - ++itr; - } - Unit deltax = x(firstPt) - x(prevPt); - Unit deltay = y(firstPt) - y(prevPt); - if(deltax && deltay && - local_abs(deltax) != local_abs(deltay)) - return false; - return true; - } - - template <typename polygon_type> - typename enable_if< typename is_polygon_with_holes_type<polygon_type>::type, bool>::type - is_45(const polygon_type& polygon) { - typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon), itr_end = end_points(polygon); - if(!point_sequence_is_45(itr, itr_end)) return false; - typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itrh = begin_holes(polygon), itrh_end = end_holes(polygon); - typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type; - for(; itrh != itrh_end; ++ itrh) { - typename polygon_traits<hole_type>::iterator_type itr1 = begin_points(polygon), itr1_end = end_points(polygon); - if(!point_sequence_is_45(itr1, itr1_end)) return false; - } - return true; - } - - template <typename distance_type, typename iterator_type> - distance_type point_sequence_distance(iterator_type itr, iterator_type itr_end) { - typedef distance_type Unit; - typedef iterator_type iterator; - typedef typename std::iterator_traits<iterator>::value_type point_type; - Unit return_value = Unit(0); - point_type previous_point, first_point; - if(itr == itr_end) return return_value; - previous_point = first_point = *itr; - ++itr; - for( ; itr != itr_end; ++itr) { - point_type current_point = *itr; - return_value += (Unit)euclidean_distance(current_point, previous_point); - previous_point = current_point; - } - return_value += (Unit)euclidean_distance(previous_point, first_point); - return return_value; - } - - template <typename T> - typename distance_type_by_domain - <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type - perimeter(const T& polygon, - typename enable_if< - typename is_polygon_with_holes_type<T>::type>::type * = 0 - ) { - typedef typename distance_type_by_domain - <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type Unit; - typedef typename polygon_traits<T>::iterator_type iterator; - iterator itr = begin_points(polygon); - iterator itr_end = end_points(polygon); - Unit return_value = point_sequence_distance<Unit, iterator>(itr, itr_end); - for(typename polygon_with_holes_traits<T>::iterator_holes_type itr_holes = begin_holes(polygon); - itr_holes != end_holes(polygon); ++itr_holes) { - typedef typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type hitertype; - return_value += point_sequence_distance<Unit, hitertype>(begin_points(*itr_holes), end_points(*itr_holes)); - } - return return_value; - } - - template <typename T> - typename enable_if <typename is_polygon_with_holes_type<T>::type, - direction_1d>::type - winding(const T& polygon) { - winding_direction wd = polygon_traits<T>::winding(polygon); - if(wd != unknown_winding) { - return wd == clockwise_winding ? CLOCKWISE: COUNTERCLOCKWISE; - } - typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type, - typename polygon_traits<T>::coordinate_type>::type area_type; - return point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>(begin_points(polygon), end_points(polygon)) < 0 ? - COUNTERCLOCKWISE : CLOCKWISE; - } - - template <typename T, typename input_point_type> - typename enable_if< - typename gtl_and< - typename is_polygon_90_type<T>::type, - typename gtl_same_type< - typename geometry_concept<input_point_type>::type, - point_concept - >::type - >::type, - bool - >::type contains( - const T& polygon, - const input_point_type& point, - bool consider_touch = true) { - typedef T polygon_type; - typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type; - typedef typename polygon_traits<polygon_type>::iterator_type iterator; - typedef typename std::iterator_traits<iterator>::value_type point_type; - coordinate_type point_x = x(point); - coordinate_type point_y = y(point); - // Check how many intersections has the ray extended from the given - // point in the x-axis negative direction with the polygon edges. - // If the number is odd the point is within the polygon, otherwise not. - // We can safely ignore horizontal edges, however intersections with - // end points of the vertical edges require special handling. We should - // add one intersection in case horizontal edges that extend vertical edge - // point in the same direction. - int num_full_intersections = 0; - int num_half_intersections = 0; - for (iterator iter = begin_points(polygon); iter != end_points(polygon);) { - point_type curr_point = *iter; - ++iter; - point_type next_point = (iter == end_points(polygon)) ? *begin_points(polygon) : *iter; - if (x(curr_point) == x(next_point)) { - if (x(curr_point) > point_x) { - continue; - } - coordinate_type min_y = (std::min)(y(curr_point), y(next_point)); - coordinate_type max_y = (std::max)(y(curr_point), y(next_point)); - if (point_y > min_y && point_y < max_y) { - if (x(curr_point) == point_x) { - return consider_touch; - } - ++num_full_intersections; - } - if (point_y == min_y || point_y == max_y) { - num_half_intersections += (y(curr_point) < y(next_point) ? 1 : -1); - } - } else { - coordinate_type min_x = (std::min)(x(curr_point), x(next_point)); - coordinate_type max_x = (std::max)(x(curr_point), x(next_point)); - if (point_x >= min_x && point_x <= max_x) { - if (y(curr_point) == point_y) { - return consider_touch; - } - } - } - } - int total_intersections = num_full_intersections + (num_half_intersections >> 1); - return total_intersections & 1; - } - - //TODO: refactor to expose as user APIs - template <typename Unit> - struct edge_utils { - typedef point_data<Unit> Point; - typedef std::pair<Point, Point> half_edge; - - class less_point { - public: - typedef Point first_argument_type; - typedef Point second_argument_type; - typedef bool result_type; - inline less_point() {} - inline bool operator () (const Point& pt1, const Point& pt2) const { - if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true; - if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) { - if(pt1.get(VERTICAL) < pt2.get(VERTICAL)) return true; - } - return false; - } - }; - - static inline bool between(Point pt, Point pt1, Point pt2) { - less_point lp; - if(lp(pt1, pt2)) - return lp(pt, pt2) && lp(pt1, pt); - return lp(pt, pt1) && lp(pt2, pt); - } - - template <typename area_type> - static inline bool equal_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) { - typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type; - unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1); - unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2); - int dx1_sign = dx1 < 0 ? -1 : 1; - int dx2_sign = dx2 < 0 ? -1 : 1; - int dy1_sign = dy1 < 0 ? -1 : 1; - int dy2_sign = dy2 < 0 ? -1 : 1; - int cross_1_sign = dx2_sign * dy1_sign; - int cross_2_sign = dx1_sign * dy2_sign; - return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0); - } - - static inline bool equal_slope(const Unit& x, const Unit& y, - const Point& pt1, const Point& pt2) { - const Point* pts[2] = {&pt1, &pt2}; - typedef typename coordinate_traits<Unit>::manhattan_area_type at; - at dy2 = (at)pts[1]->get(VERTICAL) - (at)y; - at dy1 = (at)pts[0]->get(VERTICAL) - (at)y; - at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x; - at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x; - return equal_slope(dx1, dy1, dx2, dy2); - } - - template <typename area_type> - static inline bool less_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) { - //reflext x and y slopes to right hand side half plane - if(dx1 < 0) { - dy1 *= -1; - dx1 *= -1; - } else if(dx1 == 0) { - //if the first slope is vertical the first cannot be less - return false; - } - if(dx2 < 0) { - dy2 *= -1; - dx2 *= -1; - } else if(dx2 == 0) { - //if the second slope is vertical the first is always less unless it is also vertical, in which case they are equal - return dx1 != 0; - } - typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type; - unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1); - unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2); - int dx1_sign = dx1 < 0 ? -1 : 1; - int dx2_sign = dx2 < 0 ? -1 : 1; - int dy1_sign = dy1 < 0 ? -1 : 1; - int dy2_sign = dy2 < 0 ? -1 : 1; - int cross_1_sign = dx2_sign * dy1_sign; - int cross_2_sign = dx1_sign * dy2_sign; - if(cross_1_sign < cross_2_sign) return true; - if(cross_2_sign < cross_1_sign) return false; - if(cross_1_sign == -1) return cross_2 < cross_1; - return cross_1 < cross_2; - } - - static inline bool less_slope(const Unit& x, const Unit& y, - const Point& pt1, const Point& pt2) { - const Point* pts[2] = {&pt1, &pt2}; - //compute y value on edge from pt_ to pts[1] at the x value of pts[0] - typedef typename coordinate_traits<Unit>::manhattan_area_type at; - at dy2 = (at)pts[1]->get(VERTICAL) - (at)y; - at dy1 = (at)pts[0]->get(VERTICAL) - (at)y; - at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x; - at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x; - return less_slope(dx1, dy1, dx2, dy2); - } - - //return -1 below, 0 on and 1 above line - //assumes point is on x interval of segment - static inline int on_above_or_below(Point pt, const half_edge& he) { - if(pt == he.first || pt == he.second) return 0; - if(equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second)) return 0; - bool less_result = less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second); - int retval = less_result ? -1 : 1; - less_point lp; - if(lp(he.second, he.first)) retval *= -1; - if(!between(pt, he.first, he.second)) retval *= -1; - return retval; - } - }; - - template <typename T, typename input_point_type> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_with_holes_type<T>::type, - typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type, - bool>::type - contains(const T& polygon, const input_point_type& point, bool consider_touch = true) { - typedef typename polygon_with_holes_traits<T>::iterator_holes_type holes_iterator; - bool isInside = contains( view_as< typename polygon_from_polygon_with_holes_type< - typename geometry_concept<T>::type>::type>( polygon ), point, consider_touch ); - if(!isInside) return false; //no need to check holes - holes_iterator itH = begin_holes( polygon ); - while( itH != end_holes( polygon ) ) { - if( contains( *itH, point, !consider_touch ) ) { - isInside = false; - break; - } - ++itH; - } - return isInside; - } - - template <typename T, typename input_point_type> - typename enable_if< - typename gtl_and_3< - typename is_polygon_type<T>::type, - typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type, - typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type, - bool>::type - contains(const T& polygon, const input_point_type& point, bool consider_touch = true) { - typedef typename point_traits<input_point_type>::coordinate_type Unit; - typedef point_data<Unit> Point; - typedef std::pair<Point, Point> half_edge; - typedef typename polygon_traits<T>::iterator_type iterator; - iterator itr = begin_points(polygon); - iterator itrEnd = end_points(polygon); - half_edge he; - if(itr == itrEnd) return false; - assign(he.first, *itr); - Point firstPt; - assign(firstPt, *itr); - ++itr; - if(itr == itrEnd) return false; - bool done = false; - int above = 0; - while(!done) { - Point currentPt; - if(itr == itrEnd) { - done = true; - currentPt = firstPt; - } else { - assign(currentPt, *itr); - ++itr; - } - if(currentPt == he.first) { - continue; - } else { - he.second = currentPt; - if(equivalence(point, currentPt)) return consider_touch; - Unit xmin = (std::min)(x(he.first), x(he.second)); - Unit xmax = (std::max)(x(he.first), x(he.second)); - if(x(point) >= xmin && x(point) < xmax) { //double counts if <= xmax - Point tmppt; - assign(tmppt, point); - int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he); - if(oabedge == 0) return consider_touch; - if(oabedge == 1) ++above; - } else if(x(point) == xmax) { - if(x(point) == xmin) { - Unit ymin = (std::min)(y(he.first), y(he.second)); - Unit ymax = (std::max)(y(he.first), y(he.second)); - Unit ypt = y(point); - if(ypt <= ymax && ypt >= ymin) - return consider_touch; - } else { - Point tmppt; - assign(tmppt, point); - if( edge_utils<Unit>::on_above_or_below(tmppt, he) == 0 ) { - return consider_touch; - } - } - } - } - he.first = he.second; - } - return above % 2 != 0; //if the point is above an odd number of edges is must be inside polygon - } - - /* - template <typename T, typename input_point_type> - typename enable_if< - typename gtl_and_3< - typename is_polygon_with_holes_type<T>::type, - typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type, - typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type, - bool>::type - contains(const T& polygon, const input_point_type& point, bool consider_touch = true) { - typedef typename point_traits<input_point_type>::coordinate_type Unit; - typedef point_data<Unit> Point; - typedef std::pair<Point, Point> half_edge; - typedef typename polygon_traits<T>::iterator_type iterator; - iterator itr = begin_points(polygon); - iterator itrEnd = end_points(polygon); - half_edge he; - if(itr == itrEnd) return false; - assign(he.first, *itr); - Point firstPt; - assign(firstPt, *itr); - ++itr; - if(itr == itrEnd) return false; - bool done = false; - int above = 0; - while(!done) { - Point currentPt; - if(itr == itrEnd) { - done = true; - currentPt = firstPt; - } else { - assign(currentPt, *itr); - ++itr; - } - if(currentPt == he.first) { - continue; - } else { - he.second = currentPt; - if(equivalence(point, currentPt)) return consider_touch; - Unit xmin = (std::min)(x(he.first), x(he.second)); - Unit xmax = (std::max)(x(he.first), x(he.second)); - if(x(point) >= xmin && x(point) < xmax) { //double counts if <= xmax - Point tmppt; - assign(tmppt, point); - int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he); - if(oabedge == 0) return consider_touch; - if(oabedge == 1) ++above; - } - } - he.first = he.second; - } - return above % 2 != 0; //if the point is above an odd number of edges is must be inside polygon - } - */ - - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<T1>::type>::type, - typename is_polygon_with_holes_type<T2>::type>::type, - bool>::type - extents(T1& bounding_box, const T2& polygon) { - typedef typename polygon_traits<T2>::iterator_type iterator; - bool first_iteration = true; - iterator itr_end = end_points(polygon); - for(iterator itr = begin_points(polygon); itr != itr_end; ++itr) { - if(first_iteration) { - set_points(bounding_box, *itr, *itr); - first_iteration = false; - } else { - encompass(bounding_box, *itr); - } - } - if(first_iteration) return false; - return true; - } - - template <typename T1, typename T2> - typename enable_if< - typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type, - typename is_polygon_with_holes_type<T2>::type>::type, - bool>::type - center(T1& center_point, const T2& polygon) { - typedef typename polygon_traits<T2>::coordinate_type coordinate_type; - rectangle_data<coordinate_type> bbox; - extents(bbox, polygon); - return center(center_point, bbox); - } - - template <class T> - template <class T2> - polygon_90_data<T>& polygon_90_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <class T> - template <class T2> - polygon_45_data<T>& polygon_45_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <class T> - template <class T2> - polygon_data<T>& polygon_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <class T> - template <class T2> - polygon_90_with_holes_data<T>& polygon_90_with_holes_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <class T> - template <class T2> - polygon_45_with_holes_data<T>& polygon_45_with_holes_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <class T> - template <class T2> - polygon_with_holes_data<T>& polygon_with_holes_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <typename T> - struct geometry_concept<polygon_data<T> > { - typedef polygon_concept type; - }; - template <typename T> - struct geometry_concept<polygon_45_data<T> > { - typedef polygon_45_concept type; - }; - template <typename T> - struct geometry_concept<polygon_90_data<T> > { - typedef polygon_90_concept type; - }; - template <typename T> - struct geometry_concept<polygon_with_holes_data<T> > { - typedef polygon_with_holes_concept type; - }; - template <typename T> - struct geometry_concept<polygon_45_with_holes_data<T> > { - typedef polygon_45_with_holes_concept type; - }; - template <typename T> - struct geometry_concept<polygon_90_with_holes_data<T> > { - typedef polygon_90_with_holes_concept type; - }; - -// template <typename T> struct polygon_with_holes_traits<polygon_90_data<T> > { -// typedef polygon_90_data<T> hole_type; -// typedef const hole_type* iterator_holes_type; -// static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; } -// static inline iterator_holes_type end_holes(const hole_type& t) { return &t; } -// static inline std::size_t size_holes(const hole_type& t) { return 0; } -// }; -// template <typename T> struct polygon_with_holes_traits<polygon_45_data<T> > { -// typedef polygon_45_data<T> hole_type; -// typedef const hole_type* iterator_holes_type; -// static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; } -// static inline iterator_holes_type end_holes(const hole_type& t) { return &t; } -// static inline std::size_t size_holes(const hole_type& t) { return 0; } -// }; -// template <typename T> struct polygon_with_holes_traits<polygon_data<T> > { -// typedef polygon_data<T> hole_type; -// typedef const hole_type* iterator_holes_type; -// static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; } -// static inline iterator_holes_type end_holes(const hole_type& t) { return &t; } -// static inline std::size_t size_holes(const hole_type& t) { return 0; } -// }; - template <typename T> struct get_void {}; - template <> struct get_void<gtl_yes> { typedef void type; }; - - template <typename T> struct polygon_with_holes_traits< - T, typename get_void<typename is_any_mutable_polygon_without_holes_type<T>::type>::type > { - typedef T hole_type; - typedef const hole_type* iterator_holes_type; - static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; } - static inline iterator_holes_type end_holes(const hole_type& t) { return &t; } - }; - - template <typename T> - struct view_of<rectangle_concept, T> { - typedef typename polygon_traits<T>::coordinate_type coordinate_type; - typedef interval_data<coordinate_type> interval_type; - rectangle_data<coordinate_type> rect; - view_of(const T& obj) : rect() { - point_data<coordinate_type> pts[2]; - typename polygon_traits<T>::iterator_type itr = - begin_points(obj), itre = end_points(obj); - if(itr == itre) return; - assign(pts[0], *itr); - ++itr; - if(itr == itre) return; - ++itr; - if(itr == itre) return; - assign(pts[1], *itr); - set_points(rect, pts[0], pts[1]); - } - inline interval_type get(orientation_2d orient) const { - return rect.get(orient); } - }; - - template <typename T> - struct geometry_concept<view_of<rectangle_concept, T> > { - typedef rectangle_concept type; - }; - - template <typename T> - struct view_of<polygon_45_concept, T> { - const T* t; - view_of(const T& obj) : t(&obj) {} - typedef typename polygon_traits<T>::coordinate_type coordinate_type; - typedef typename polygon_traits<T>::iterator_type iterator_type; - typedef typename polygon_traits<T>::point_type point_type; - - /// Get the begin iterator - inline iterator_type begin() const { - return polygon_traits<T>::begin_points(*t); - } - - /// Get the end iterator - inline iterator_type end() const { - return polygon_traits<T>::end_points(*t); - } - - /// Get the number of sides of the polygon - inline std::size_t size() const { - return polygon_traits<T>::size(*t); - } - - /// Get the winding direction of the polygon - inline winding_direction winding() const { - return polygon_traits<T>::winding(*t); - } - }; - - template <typename T> - struct geometry_concept<view_of<polygon_45_concept, T> > { - typedef polygon_45_concept type; - }; - - template <typename T> - struct view_of<polygon_90_concept, T> { - const T* t; - view_of(const T& obj) : t(&obj) {} - typedef typename polygon_traits<T>::coordinate_type coordinate_type; - typedef typename polygon_traits<T>::iterator_type iterator_type; - typedef typename polygon_traits<T>::point_type point_type; - typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type; - - /// Get the begin iterator - inline compact_iterator_type begin_compact() const { - return compact_iterator_type(polygon_traits<T>::begin_points(*t), - polygon_traits<T>::end_points(*t)); - } - - /// Get the end iterator - inline compact_iterator_type end_compact() const { - return compact_iterator_type(polygon_traits<T>::end_points(*t), - polygon_traits<T>::end_points(*t)); - } - - /// Get the number of sides of the polygon - inline std::size_t size() const { - return polygon_traits<T>::size(*t); - } - - /// Get the winding direction of the polygon - inline winding_direction winding() const { - return polygon_traits<T>::winding(*t); - } - }; - - template <typename T> - struct geometry_concept<view_of<polygon_90_concept, T> > { - typedef polygon_90_concept type; - }; - - template <typename T> - struct view_of<polygon_45_with_holes_concept, T> { - const T* t; - view_of(const T& obj) : t(&obj) {} - typedef typename polygon_traits<T>::coordinate_type coordinate_type; - typedef typename polygon_traits<T>::iterator_type iterator_type; - typedef typename polygon_traits<T>::point_type point_type; - typedef view_of<polygon_45_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type; - struct iterator_holes_type { - typedef std::forward_iterator_tag iterator_category; - typedef hole_type value_type; - typedef std::ptrdiff_t difference_type; - typedef const hole_type* pointer; //immutable - typedef const hole_type& reference; //immutable - typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht; - iht internal_itr; - iterator_holes_type() : internal_itr() {} - iterator_holes_type(iht iht_in) : internal_itr(iht_in) {} - inline iterator_holes_type& operator++() { - ++internal_itr; - return *this; - } - inline const iterator_holes_type operator++(int) { - iterator_holes_type tmp(*this); - ++(*this); - return tmp; - } - inline bool operator==(const iterator_holes_type& that) const { - return (internal_itr == that.internal_itr); - } - inline bool operator!=(const iterator_holes_type& that) const { - return (internal_itr != that.internal_itr); - } - inline value_type operator*() const { - return view_as<polygon_45_concept>(*internal_itr); - } - }; - - /// Get the begin iterator - inline iterator_type begin() const { - return polygon_traits<T>::begin_points(*t); - } - - /// Get the end iterator - inline iterator_type end() const { - return polygon_traits<T>::end_points(*t); - } - - /// Get the number of sides of the polygon - inline std::size_t size() const { - return polygon_traits<T>::size(*t); - } - - /// Get the winding direction of the polygon - inline winding_direction winding() const { - return polygon_traits<T>::winding(*t); - } - - /// Get the begin iterator - inline iterator_holes_type begin_holes() const { - return polygon_with_holes_traits<T>::begin_holes(*t); - } - - /// Get the end iterator - inline iterator_holes_type end_holes() const { - return polygon_with_holes_traits<T>::end_holes(*t); - } - - /// Get the number of sides of the polygon - inline std::size_t size_holes() const { - return polygon_with_holes_traits<T>::size_holes(*t); - } - - }; - - template <typename T> - struct geometry_concept<view_of<polygon_45_with_holes_concept, T> > { - typedef polygon_45_with_holes_concept type; - }; - - template <typename T> - struct view_of<polygon_90_with_holes_concept, T> { - const T* t; - view_of(const T& obj) : t(&obj) {} - typedef typename polygon_traits<T>::coordinate_type coordinate_type; - typedef typename polygon_traits<T>::iterator_type iterator_type; - typedef typename polygon_traits<T>::point_type point_type; - typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type; - typedef view_of<polygon_90_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type; - struct iterator_holes_type { - typedef std::forward_iterator_tag iterator_category; - typedef hole_type value_type; - typedef std::ptrdiff_t difference_type; - typedef const hole_type* pointer; //immutable - typedef const hole_type& reference; //immutable - typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht; - iht internal_itr; - iterator_holes_type() : internal_itr() {} - iterator_holes_type(iht iht_in) : internal_itr(iht_in) {} - inline iterator_holes_type& operator++() { - ++internal_itr; - return *this; - } - inline const iterator_holes_type operator++(int) { - iterator_holes_type tmp(*this); - ++(*this); - return tmp; - } - inline bool operator==(const iterator_holes_type& that) const { - return (internal_itr == that.internal_itr); - } - inline bool operator!=(const iterator_holes_type& that) const { - return (internal_itr != that.internal_itr); - } - inline value_type operator*() const { - return view_as<polygon_90_concept>(*internal_itr); - } - }; - - /// Get the begin iterator - inline compact_iterator_type begin_compact() const { - return compact_iterator_type(polygon_traits<T>::begin_points(*t), - polygon_traits<T>::end_points(*t)); - } - - /// Get the end iterator - inline compact_iterator_type end_compact() const { - return compact_iterator_type(polygon_traits<T>::end_points(*t), - polygon_traits<T>::end_points(*t)); - } - - /// Get the number of sides of the polygon - inline std::size_t size() const { - return polygon_traits<T>::size(*t); - } - - /// Get the winding direction of the polygon - inline winding_direction winding() const { - return polygon_traits<T>::winding(*t); - } - - /// Get the begin iterator - inline iterator_holes_type begin_holes() const { - return polygon_with_holes_traits<T>::begin_holes(*t); - } - - /// Get the end iterator - inline iterator_holes_type end_holes() const { - return polygon_with_holes_traits<T>::end_holes(*t); - } - - /// Get the number of sides of the polygon - inline std::size_t size_holes() const { - return polygon_with_holes_traits<T>::size_holes(*t); - } - - }; - - template <typename T> - struct geometry_concept<view_of<polygon_90_with_holes_concept, T> > { - typedef polygon_90_with_holes_concept type; - }; - - template <typename T> - struct view_of<polygon_concept, T> { - const T* t; - view_of(const T& obj) : t(&obj) {} - typedef typename polygon_traits<T>::coordinate_type coordinate_type; - typedef typename polygon_traits<T>::iterator_type iterator_type; - typedef typename polygon_traits<T>::point_type point_type; - - /// Get the begin iterator - inline iterator_type begin() const { - return polygon_traits<T>::begin_points(*t); - } - - /// Get the end iterator - inline iterator_type end() const { - return polygon_traits<T>::end_points(*t); - } - - /// Get the number of sides of the polygon - inline std::size_t size() const { - return polygon_traits<T>::size(*t); - } - - /// Get the winding direction of the polygon - inline winding_direction winding() const { - return polygon_traits<T>::winding(*t); - } - }; - - template <typename T> - struct geometry_concept<view_of<polygon_concept, T> > { - typedef polygon_concept type; - }; -} -} - -#endif diff --git a/contrib/restricted/boost/boost/polygon/polygon_with_holes_data.hpp b/contrib/restricted/boost/boost/polygon/polygon_with_holes_data.hpp deleted file mode 100644 index a1a0e1dd2a..0000000000 --- a/contrib/restricted/boost/boost/polygon/polygon_with_holes_data.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - 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_POLYGON_WITH_HOLES_DATA_HPP -#define BOOST_POLYGON_POLYGON_WITH_HOLES_DATA_HPP -#include "isotropy.hpp" -#include "polygon_data.hpp" -namespace boost { namespace polygon{ - struct polygon_with_holes_concept; - template <typename T> - class polygon_with_holes_data { -public: - typedef polygon_with_holes_concept geometry_type; - typedef T coordinate_type; - typedef typename polygon_data<T>::iterator_type iterator_type; - typedef typename std::list<polygon_data<coordinate_type> >::const_iterator iterator_holes_type; - typedef polygon_data<coordinate_type> hole_type; - typedef typename coordinate_traits<T>::coordinate_distance area_type; - typedef point_data<T> point_type; - - // default constructor of point does not initialize x and y - inline polygon_with_holes_data() : self_(), holes_() {} //do nothing default constructor - - template<class iT> - inline polygon_with_holes_data(iT input_begin, iT input_end) : self_(), holes_() { - set(input_begin, input_end); - } - - template<class iT, typename hiT> - inline polygon_with_holes_data(iT input_begin, iT input_end, hiT holes_begin, hiT holes_end) : self_(), holes_() { - set(input_begin, input_end); - set_holes(holes_begin, holes_end); - } - - template<class iT> - inline polygon_with_holes_data& set(iT input_begin, iT input_end) { - self_.set(input_begin, input_end); - return *this; - } - - // initialize a polygon from x,y values, it is assumed that the first is an x - // and that the input is a well behaved polygon - template<class iT> - inline polygon_with_holes_data& set_holes(iT input_begin, iT input_end) { - holes_.clear(); //just in case there was some old data there - for( ; input_begin != input_end; ++ input_begin) { - holes_.push_back(hole_type()); - holes_.back().set((*input_begin).begin(), (*input_begin).end()); - } - return *this; - } - - // copy constructor (since we have dynamic memory) - inline polygon_with_holes_data(const polygon_with_holes_data& that) : self_(that.self_), - holes_(that.holes_) {} - - // assignment operator (since we have dynamic memory do a deep copy) - inline polygon_with_holes_data& operator=(const polygon_with_holes_data& that) { - self_ = that.self_; - holes_ = that.holes_; - return *this; - } - - template <typename T2> - inline polygon_with_holes_data& operator=(const T2& rvalue); - - // get begin iterator, returns a pointer to a const coordinate_type - inline const iterator_type begin() const { - return self_.begin(); - } - - // get end iterator, returns a pointer to a const coordinate_type - inline const iterator_type end() const { - return self_.end(); - } - - inline std::size_t size() const { - return self_.size(); - } - - // get begin iterator, returns a pointer to a const polygon - inline const iterator_holes_type begin_holes() const { - return holes_.begin(); - } - - // get end iterator, returns a pointer to a const polygon - inline const iterator_holes_type end_holes() const { - return holes_.end(); - } - - inline std::size_t size_holes() const { - return holes_.size(); - } - -public: - polygon_data<coordinate_type> self_; - std::list<hole_type> holes_; - }; - - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/rectangle_concept.hpp b/contrib/restricted/boost/boost/polygon/rectangle_concept.hpp deleted file mode 100644 index e82431907b..0000000000 --- a/contrib/restricted/boost/boost/polygon/rectangle_concept.hpp +++ /dev/null @@ -1,1082 +0,0 @@ -/* - 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_RECTANGLE_CONCEPT_HPP -#define BOOST_POLYGON_RECTANGLE_CONCEPT_HPP - -#include "isotropy.hpp" - -//point -#include "point_data.hpp" -#include "point_traits.hpp" -#include "point_concept.hpp" - -//interval -#include "interval_data.hpp" -#include "interval_traits.hpp" -#include "interval_concept.hpp" - -#include "rectangle_data.hpp" -#include "rectangle_traits.hpp" - -namespace boost { namespace polygon{ - struct rectangle_concept {}; - - template <typename T> - struct is_rectangle_concept { typedef gtl_no type; }; - template <> - struct is_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_mutable_rectangle_concept { typedef gtl_no type; }; - template <> - struct is_mutable_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; - - template <> - struct geometry_domain<rectangle_concept> { typedef manhattan_domain type; }; - - template <typename T, typename CT> - struct rectangle_interval_type_by_concept { typedef void type; }; - template <typename T> - struct rectangle_interval_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::interval_type type; }; - - template <typename T> - struct rectangle_interval_type { - typedef typename rectangle_interval_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct rectangle_coordinate_type_by_concept { typedef void type; }; - template <typename T> - struct rectangle_coordinate_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::coordinate_type type; }; - - template <typename T> - struct rectangle_coordinate_type { - typedef typename rectangle_coordinate_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct rectangle_difference_type_by_concept { typedef void type; }; - template <typename T> - struct rectangle_difference_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_difference type; }; - - template <typename T> - struct rectangle_difference_type { - typedef typename rectangle_difference_type_by_concept< - T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct rectangle_distance_type_by_concept { typedef void type; }; - template <typename T> - struct rectangle_distance_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename rectangle_coordinate_type<T>::type>::coordinate_distance type; }; - - template <typename T> - struct rectangle_distance_type { - typedef typename rectangle_distance_type_by_concept< - T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - struct y_r_get_interval : gtl_yes {}; - - template <typename T> - typename enable_if< typename gtl_and<y_r_get_interval, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type, - typename rectangle_interval_type<T>::type>::type - get(const T& rectangle, orientation_2d orient) { - return rectangle_traits<T>::get(rectangle, orient); - } - - struct y_r_h : gtl_yes {}; - - template <typename T> - typename enable_if< typename gtl_and<y_r_h, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type, - typename rectangle_interval_type<T>::type>::type - horizontal(const T& rectangle) { - return rectangle_traits<T>::get(rectangle, HORIZONTAL); - } - - struct y_r_v : gtl_yes {}; - - template <typename T> - typename enable_if< typename gtl_and<y_r_v, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type, - typename rectangle_interval_type<T>::type>::type - vertical(const T& rectangle) { - return rectangle_traits<T>::get(rectangle, VERTICAL); - } - - struct y_r_set : gtl_yes {}; - - template <orientation_2d_enum orient, typename T, typename T2> - typename enable_if< typename gtl_and_3<y_r_set, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, - void>::type - set(T& rectangle, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, orient, interval); - } - - struct y_r_set2 : gtl_yes {}; - - template <typename T, typename T2> - typename enable_if< typename gtl_and_3<y_r_set2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, - void>::type - set(T& rectangle, orientation_2d orient, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, orient, interval); - } - - struct y_r_h2 : gtl_yes {}; - - template <typename T, typename T2> - typename enable_if< typename gtl_and_3<y_r_h2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, - void>::type - horizontal(T& rectangle, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, HORIZONTAL, interval); - } - - struct y_r_v2 : gtl_yes {}; - - template <typename T, typename T2> - typename enable_if< - typename gtl_and_3<y_r_v2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, void>::type - vertical(T& rectangle, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, VERTICAL, interval); - } - - struct y_r_construct : gtl_yes {}; - - template <typename T, typename T2, typename T3> - typename enable_if< typename gtl_and<y_r_construct, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type, - T>::type - construct(const T2& interval_horizontal, - const T3& interval_vertical) { - return rectangle_mutable_traits<T>::construct(interval_horizontal, interval_vertical); } - - struct y_r_construct2 : gtl_yes {}; - - template <typename T, typename coord_type> - typename enable_if< typename gtl_and<y_r_construct2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type, - T>::type - construct(coord_type xl, coord_type yl, coord_type xh, coord_type yh) { - return rectangle_mutable_traits<T>::construct(interval_data<coord_type>(xl, xh), - interval_data<coord_type>(yl, yh)); - } - - struct y_r_cconstruct : gtl_yes {}; - - template <typename T, typename T2> - typename enable_if< - typename gtl_and_3<y_r_cconstruct, - typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type, - typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, - T>::type - copy_construct(const T2& rectangle) { - return construct<T> (get(rectangle, HORIZONTAL), get(rectangle, VERTICAL)); - } - - struct y_r_assign : gtl_yes {}; - - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3< y_r_assign, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - rectangle_type_1>::type & - assign(rectangle_type_1& lvalue, const rectangle_type_2& rvalue) { - set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); - set(lvalue, VERTICAL, get(rvalue, VERTICAL)); - return lvalue; - } - - struct y_r_equiv : gtl_yes {}; - - template <typename T, typename T2> - typename enable_if< - typename gtl_and_3< y_r_equiv, - typename is_rectangle_concept<typename geometry_concept<T>::type>::type, - typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, - bool>::type - equivalence(const T& rect1, const T2& rect2) { - return equivalence(get(rect1, HORIZONTAL), get(rect2, HORIZONTAL)) && - equivalence(get(rect1, VERTICAL), get(rect2, VERTICAL)); - } - - struct y_r_get : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_get, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_coordinate_type<rectangle_type>::type>::type - get(const rectangle_type& rectangle, orientation_2d orient, direction_1d dir) { - return get(rectangle_traits<rectangle_type>::get(rectangle, orient), dir); - } - - struct y_r_set3 : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_set3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type - set(rectangle_type& rectangle, orientation_2d orient, direction_1d dir, - typename rectangle_coordinate_type<rectangle_type>::type value) { - typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); - set(ivl, dir, value); - set(rectangle, orient, ivl); - } - - struct y_r_xl : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_xl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_coordinate_type<rectangle_type>::type>::type - xl(const rectangle_type& rectangle) { - return get(rectangle, HORIZONTAL, LOW); - } - - struct y_r_xl2 : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_xl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type - xl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { - return set(rectangle, HORIZONTAL, LOW, value); - } - - struct y_r_xh : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_xh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_coordinate_type<rectangle_type>::type>::type - xh(const rectangle_type& rectangle) { - return get(rectangle, HORIZONTAL, HIGH); - } - - struct y_r_xh2 : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_xh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type - xh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { - return set(rectangle, HORIZONTAL, HIGH, value); - } - - struct y_r_yl : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_yl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_coordinate_type<rectangle_type>::type>::type - yl(const rectangle_type& rectangle) { - return get(rectangle, VERTICAL, LOW); - } - - struct y_r_yl2 : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_yl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type - yl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { - return set(rectangle, VERTICAL, LOW, value); - } - - struct y_r_yh : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_yh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_coordinate_type<rectangle_type>::type>::type - yh(const rectangle_type& rectangle) { - return get(rectangle, VERTICAL, HIGH); - } - - struct y_r_yh2 : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_yh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type - yh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) { - return set(rectangle, VERTICAL, HIGH, value); - } - - struct y_r_ll : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_ll, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type - ll(const rectangle_type& rectangle) { - return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yl(rectangle)); - } - - struct y_r_lr : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_lr, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type - lr(const rectangle_type& rectangle) { - return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yl(rectangle)); - } - - struct y_r_ul : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_ul, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type - ul(const rectangle_type& rectangle) { - return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yh(rectangle)); - } - - struct y_r_ur : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_ur, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type - ur(const rectangle_type& rectangle) { - return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yh(rectangle)); - } - - struct y_r_contains : gtl_yes {}; - - template <typename rectangle_type, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_contains, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - contains(const rectangle_type& rectangle, const rectangle_type_2 rectangle_contained, - bool consider_touch = true) { - return contains(horizontal(rectangle), horizontal(rectangle_contained), consider_touch) && - contains(vertical(rectangle), vertical(rectangle_contained), consider_touch); - } - - struct y_r_contains2 : gtl_yes {}; - - template <typename rectangle_type, typename point_type> - typename enable_if< typename gtl_and_3<y_r_contains2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type - contains(const rectangle_type& rectangle, const point_type point_contained, - bool consider_touch = true) { - return contains(horizontal(rectangle), x(point_contained), consider_touch) && - contains(vertical(rectangle), y(point_contained), consider_touch); - } - - struct y_r_set_points : gtl_yes {}; - - // set all four coordinates based upon two points - template <typename rectangle_type, typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_4< y_r_set_points, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type_1>::type>::type, - typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type, - rectangle_type>::type & - set_points(rectangle_type& rectangle, const point_type_1& p1, - const point_type_2& p2) { - typedef typename rectangle_coordinate_type<rectangle_type>::type Unit; - Unit x1(x(p1)); - Unit x2(x(p2)); - Unit y1(y(p1)); - Unit y2(y(p2)); - horizontal(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(x1, x2)); - vertical(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(y1, y2)); - return rectangle; - } - - struct y_r_move : gtl_yes {}; - - // move rectangle by delta in orient - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_move, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - move(rectangle_type& rectangle, orientation_2d orient, - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference delta) { - typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); - move(ivl, delta); - set(rectangle, orient, ivl); - return rectangle; - } - - struct y_r_convolve : gtl_yes {}; - - // convolve this with b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3< y_r_convolve, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - rectangle_type_1>::type & - convolve(rectangle_type_1& rectangle, - const rectangle_type_2& convolution_rectangle) { - typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); - horizontal(rectangle, convolve(ivl, horizontal(convolution_rectangle))); - ivl = vertical(rectangle); - vertical(rectangle, convolve(ivl, vertical(convolution_rectangle))); - return rectangle; - } - - struct y_r_deconvolve : gtl_yes {}; - - // deconvolve this with b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3< y_r_deconvolve, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - rectangle_type_1>::type & - deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { - typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); - horizontal(rectangle, deconvolve(ivl, horizontal(convolution_rectangle))); - ivl = vertical(rectangle); - vertical(rectangle, deconvolve(ivl, vertical(convolution_rectangle))); - return rectangle; - } - - struct y_r_reconvolve : gtl_yes {}; - - // reflectedConvolve this with b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_reconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - rectangle_type_1>::type & - reflected_convolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { - typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); - horizontal(rectangle, reflected_convolve(ivl, horizontal(convolution_rectangle))); - ivl = vertical(rectangle); - vertical(rectangle, reflected_convolve(ivl, vertical(convolution_rectangle))); - return rectangle; - } - - struct y_r_redeconvolve : gtl_yes {}; - - // reflectedDeconvolve this with b - // deconvolve this with b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_redeconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - rectangle_type_1>::type & - reflected_deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { - typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle); - horizontal(rectangle, reflected_deconvolve(ivl, horizontal(convolution_rectangle))); - ivl = vertical(rectangle); - vertical(rectangle, reflected_deconvolve(ivl, vertical(convolution_rectangle))); - return rectangle; - } - - struct y_r_convolve2 : gtl_yes {}; - - // convolve with point - template <typename rectangle_type, typename point_type> - typename enable_if< typename gtl_and_3<y_r_convolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - rectangle_type>::type & - convolve(rectangle_type& rectangle, const point_type& convolution_point) { - typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle); - horizontal(rectangle, convolve(ivl, x(convolution_point))); - ivl = vertical(rectangle); - vertical(rectangle, convolve(ivl, y(convolution_point))); - return rectangle; - } - - struct y_r_deconvolve2 : gtl_yes {}; - - // deconvolve with point - template <typename rectangle_type, typename point_type> - typename enable_if< - typename gtl_and_3<y_r_deconvolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type & - deconvolve(rectangle_type& rectangle, const point_type& convolution_point) { - typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle); - horizontal(rectangle, deconvolve(ivl, x(convolution_point))); - ivl = vertical(rectangle); - vertical(rectangle, deconvolve(ivl, y(convolution_point))); - return rectangle; - } - - struct y_r_delta : gtl_yes {}; - - // get the magnitude of the interval range depending on orient - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_delta, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - delta(const rectangle_type& rectangle, orientation_2d orient) { - return delta(get(rectangle, orient)); - } - - struct y_r_area : gtl_yes {}; - - // get the area of the rectangle - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_area, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type>::type - area(const rectangle_type& rectangle) { - typedef typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type area_type; - return (area_type)delta(rectangle, HORIZONTAL) * (area_type)delta(rectangle, VERTICAL); - } - - struct y_r_go : gtl_yes {}; - - // returns the orientation of the longest side - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_go, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - orientation_2d>::type - guess_orientation(const rectangle_type& rectangle) { - return delta(rectangle, HORIZONTAL) >= delta(rectangle, VERTICAL) ? - HORIZONTAL : VERTICAL; - } - - struct y_r_half_p : gtl_yes {}; - - // get the half perimeter of the rectangle - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_half_p, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - half_perimeter(const rectangle_type& rectangle) { - return delta(rectangle, HORIZONTAL) + delta(rectangle, VERTICAL); - } - - struct y_r_perimeter : gtl_yes {}; - - // get the perimeter of the rectangle - template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_perimeter, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - perimeter(const rectangle_type& rectangle) { - return 2 * half_perimeter(rectangle); - } - - struct y_r_intersects : gtl_yes {}; - - // check if Rectangle b intersects `this` Rectangle - // [in] b Rectangle that will be checked - // [in] considerTouch If true, return true even if b touches the boundary - // [ret] . true if `t` intersects b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_intersects, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - intersects(const rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) { - return intersects(horizontal(rectangle), horizontal(b), consider_touch) && - intersects(vertical(rectangle), vertical(b), consider_touch); - } - - struct y_r_b_intersect : gtl_yes {}; - - // Check if boundaries of Rectangle b and `this` Rectangle intersect - // [in] b Rectangle that will be checked - // [in] considerTouch If true, return true even if p is on the foundary - // [ret] . true if `t` contains p - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_b_intersect, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - boundaries_intersect(const rectangle_type_1& rectangle, const rectangle_type_2& b, - bool consider_touch = true) { - return (intersects(rectangle, b, consider_touch) && - !(contains(rectangle, b, !consider_touch)) && - !(contains(b, rectangle, !consider_touch))); - } - - struct y_r_b_abuts : gtl_yes {}; - - // check if b is touching 'this' on the end specified by dir - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_b_abuts, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, - direction_2d dir) { - return - abuts(get(rectangle, orientation_2d(dir)), - get(b, orientation_2d(dir)), - direction_1d(dir)) && - intersects(get(rectangle, orientation_2d(dir).get_perpendicular()), - get(b, orientation_2d(dir).get_perpendicular()), true); - } - - struct y_r_b_abuts2 : gtl_yes {}; - - // check if they are touching in the given orientation - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_b_abuts2, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, - orientation_2d orient) { - return - abuts(get(rectangle, orient), get(b, orient)) && - intersects(get(rectangle, orient.get_perpendicular()), - get(b, orient.get_perpendicular()), true); - } - - struct y_r_b_abuts3 : gtl_yes {}; - - // check if they are touching but not overlapping - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_b_abuts3, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b) { - return abuts(rectangle, b, HORIZONTAL) || abuts(rectangle, b, VERTICAL); - } - - struct y_r_b_intersect2 : gtl_yes {}; - - // intersect rectangle with interval on orient - template <typename rectangle_type, typename interval_type> - typename enable_if< - typename gtl_and_3<y_r_b_intersect2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - bool>::type - intersect(rectangle_type& rectangle, const interval_type& b, - orientation_2d orient, bool consider_touch = true) { - typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); - if(intersect(ivl, b, consider_touch)) { - set(rectangle, orient, ivl); - return true; - } - return false; - } - - struct y_r_b_intersect3 : gtl_yes {}; - - // clip rectangle to b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_b_intersect3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - intersect(rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) { - if(intersects(rectangle, b)) { - intersect(rectangle, horizontal(b), HORIZONTAL, consider_touch); - intersect(rectangle, vertical(b), VERTICAL, consider_touch); - return true; - } - return false; - } - - struct y_r_g_intersect : gtl_yes {}; - - // Sets this to the generalized intersection of this and the given rectangle - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_g_intersect, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - rectangle_type_1>::type & - generalized_intersect(rectangle_type_1& rectangle, const rectangle_type_2& b) { - typename rectangle_interval_type<rectangle_type_1>::type ivl = get(rectangle, HORIZONTAL); - generalized_intersect(ivl, horizontal(b)); - horizontal(rectangle, ivl); - ivl = vertical(rectangle); - generalized_intersect(ivl, vertical(b)); - vertical(rectangle, ivl); - return rectangle; - } - - struct y_r_bloat : gtl_yes {}; - - // bloat the interval specified by orient by bloating - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_bloat, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - bloat(rectangle_type& rectangle, orientation_2d orient, - typename rectangle_coordinate_type<rectangle_type>::type bloating) { - typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); - bloat(ivl, bloating); - set(rectangle, orient, ivl); - return rectangle; - } - - struct y_r_bloat2 : gtl_yes {}; - - // bloat the Rectangle by bloating - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_bloat2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - bloat(rectangle_type& rectangle, - typename rectangle_coordinate_type<rectangle_type>::type bloating) { - bloat(rectangle, HORIZONTAL, bloating); - return bloat(rectangle, VERTICAL, bloating); - } - - struct y_r_bloat3 : gtl_yes {}; - - // bloat the interval cooresponding to orient by bloating in dir direction - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_bloat3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - bloat(rectangle_type& rectangle, direction_2d dir, - typename rectangle_coordinate_type<rectangle_type>::type bloating) { - typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orientation_2d(dir)); - bloat(ivl, direction_1d(dir), bloating); - set(rectangle, orientation_2d(dir), ivl); - return rectangle; - } - - struct y_r_shrink : gtl_yes {}; - - // shrink the interval specified by orient by bloating - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_shrink, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - shrink(rectangle_type& rectangle, orientation_2d orient, - typename rectangle_coordinate_type<rectangle_type>::type shrinking) { - return bloat(rectangle, orient, -shrinking); - } - - struct y_r_shrink2 : gtl_yes {}; - - // shrink the Rectangle by bloating - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_shrink2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - shrink(rectangle_type& rectangle, - typename rectangle_coordinate_type<rectangle_type>::type shrinking) { - return bloat(rectangle, -shrinking); - } - - struct y_r_shrink3 : gtl_yes {}; - - // shrink the interval cooresponding to orient by bloating in dir direction - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_shrink3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - shrink(rectangle_type& rectangle, direction_2d dir, - typename rectangle_coordinate_type<rectangle_type>::type shrinking) { - return bloat(rectangle, dir, -shrinking); - } - - struct y_r_encompass : gtl_yes {}; - - // encompass interval on orient - template <typename rectangle_type, typename interval_type> - typename enable_if<typename gtl_and_3< - y_r_encompass, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - bool>::type - encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) { - typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); - if(encompass(ivl, b)) { - set(rectangle, orient, ivl); - return true; - } - return false; - } - - struct y_r_encompass2 : gtl_yes {}; - - // enlarge rectangle to encompass the Rectangle b - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3< - y_r_encompass2, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type, - bool>::type - encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) { - //note that operator | is intentional because both should be called regardless - return encompass(rectangle, horizontal(b), HORIZONTAL) | - encompass(rectangle, vertical(b), VERTICAL); - } - - struct y_r_encompass3 : gtl_yes {}; - - // enlarge rectangle to encompass the point b - template <typename rectangle_type_1, typename point_type> - typename enable_if<typename gtl_and_3< - y_r_encompass3, - typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - bool>::type - encompass(rectangle_type_1& rectangle, const point_type& b) { - typename rectangle_interval_type<rectangle_type_1>::type hivl, vivl; - hivl = horizontal(rectangle); - vivl = vertical(rectangle); - //note that operator | is intentional because both should be called regardless - bool retval = encompass(hivl, x(b)) | encompass(vivl, y(b)); - if(retval) { - horizontal(rectangle, hivl); - vertical(rectangle, vivl); - } - return retval; - } - - struct y_r_center : gtl_yes {}; - - // returns the center of the rectangle - template <typename point_type, typename rectangle_type> - typename enable_if< - typename gtl_and_3<y_r_center, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - bool>::type - center(point_type& center_point, const rectangle_type& rectangle) { - center_point = construct<point_type>(center(horizontal(rectangle)), - center(vertical(rectangle))); - return true; - } - - struct y_r_get_corner : gtl_yes {}; - - template <typename point_type, typename rectangle_type> - typename enable_if< - typename gtl_and_3<y_r_get_corner, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - bool>::type - get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) { - typedef typename rectangle_coordinate_type<rectangle_type>::type Unit; - Unit u1 = get(rectangle, direction_facing); - Unit u2 = get(rectangle, direction_facing.turn(direction_turning)); - if(orientation_2d(direction_facing).to_int()) std::swap(u1, u2); - corner_point = construct<point_type>(u1, u2); - return true; - } - - struct y_r_get_half : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_get_half, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type - get_half(const rectangle_type& rectangle, direction_2d dir) { - rectangle_type retval(rectangle); - set(retval, orientation_2d(dir), get_half(get(rectangle, orientation_2d(dir)), direction_1d(dir))); - return retval; - } - - struct y_r_join_with : gtl_yes {}; - - template <typename rectangle_type_1, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_join_with, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) { - typedef typename rectangle_interval_type<rectangle_type_1>::type Interval1; - typedef typename rectangle_interval_type<rectangle_type_2>::type Interval2; - Interval1 hi1 = get(rectangle, HORIZONTAL); - Interval1 vi1 = get(rectangle, VERTICAL); - Interval2 hi2 = get(b, HORIZONTAL), vi2 = get(b, VERTICAL); - Interval1 temp; - if (equivalence(hi1, hi2) && join_with(vi1, vi2)) { - vertical(rectangle, vi1); - return true; - } - if (equivalence(vi1, vi2) && join_with(hi1, hi2)) { - horizontal(rectangle, hi1); - return true; - } - return false; - } - - struct y_r_eda2 : gtl_yes {}; - - template <typename rectangle_type, typename point_type> - typename enable_if< typename gtl_and_3<y_r_eda2, - typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - euclidean_distance(const rectangle_type& lvalue, const point_type& rvalue, orientation_2d orient) { - return euclidean_distance(get(lvalue, orient), get(rvalue, orient)); - } - - struct y_r_eda : gtl_yes {}; - - template <typename rectangle_type, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_eda, - typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue, orientation_2d orient) { - return euclidean_distance(get(lvalue, orient), get(rvalue, orient)); - } - - struct y_r_sed : gtl_yes {}; - - template <typename rectangle_type, typename point_type> - typename enable_if< typename gtl_and_3<y_r_sed, - typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - square_euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; - xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); - ydist = euclidean_distance(lvalue, rvalue, VERTICAL); - return (xdist * xdist) + (ydist * ydist); - } - - struct y_r_sed2 : gtl_yes {}; - - template <typename rectangle_type, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_sed2, typename is_rectangle_concept< typename geometry_concept<rectangle_type>::type>::type, - typename is_rectangle_concept< typename geometry_concept<rectangle_type_2>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - square_euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; - xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); - ydist = euclidean_distance(lvalue, rvalue, VERTICAL); - return (xdist * xdist) + (ydist * ydist); - } - - struct y_r_edist : gtl_yes {}; - - template <typename rectangle_type, typename point_type> - typename enable_if< typename gtl_and_3<y_r_edist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - typename rectangle_distance_type<rectangle_type>::type>::type - euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { - return std::sqrt((double)(square_euclidean_distance(lvalue, rvalue))); - } - - struct y_r_edist2 : gtl_yes {}; - - template <typename rectangle_type, typename rectangle_type_2> - typename enable_if< typename gtl_and_3<y_r_edist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - typename rectangle_distance_type<rectangle_type>::type>::type - euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { - double val = (int)square_euclidean_distance(lvalue, rvalue); - return std::sqrt(val); - } - - struct y_r_mdist : gtl_yes {}; - - template <typename rectangle_type, typename point_type> - typename enable_if< - typename gtl_and_3<y_r_mdist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - manhattan_distance(rectangle_type& lvalue, const point_type& rvalue) { - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; - xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); - ydist = euclidean_distance(lvalue, rvalue, VERTICAL); - return xdist + ydist; - } - - struct y_r_mdist2 : gtl_yes {}; - - template <typename rectangle_type, typename rectangle_type_2> - typename enable_if< - typename gtl_and_3<y_r_mdist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - typename rectangle_difference_type<rectangle_type>::type>::type - manhattan_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist; - xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); - ydist = euclidean_distance(lvalue, rvalue, VERTICAL); - return xdist + ydist; - } - - struct y_r_scale_up : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_scale_up, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - scale_up(rectangle_type& rectangle, - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) { - typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle); - horizontal(rectangle, scale_up(h, factor)); - typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle); - vertical(rectangle, scale_up(v, factor)); - return rectangle; - } - - struct y_r_scale_down : gtl_yes {}; - - template <typename rectangle_type> - typename enable_if<typename gtl_and<y_r_scale_down, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - scale_down(rectangle_type& rectangle, - typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) { - typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle); - horizontal(rectangle, scale_down(h, factor)); - typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle); - vertical(rectangle, scale_down(v, factor)); - return rectangle; - } - - struct y_r_scale : gtl_yes {}; - - template <typename rectangle_type, typename scaling_type> - typename enable_if<typename gtl_and<y_r_scale, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - scale(rectangle_type& rectangle, const scaling_type& scaling) { - point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle)); - point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xl(rectangle), yl(rectangle)); - scale(llp, scaling); - scale(urp, scaling); - set_points(rectangle, llp, urp); - return rectangle; - } - - struct y_r_transform : gtl_yes {}; - - template <typename rectangle_type, typename transformation_type> - typename enable_if<typename gtl_and<y_r_transform, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, - rectangle_type>::type & - transform(rectangle_type& rectangle, const transformation_type& transformation) { - point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle)); - point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xh(rectangle), yh(rectangle)); - transform(llp, transformation); - transform(urp, transformation); - set_points(rectangle, llp, urp); - return rectangle; - } - - template <typename rectangle_type_1, typename rectangle_type_2> - class less_rectangle_concept { - private: - orientation_2d orient_; - public: - inline less_rectangle_concept(orientation_2d orient = VERTICAL) : orient_(orient) {} - typename enable_if< - typename gtl_and< typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, - typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, - bool>::type - operator () (const rectangle_type_1& a, - const rectangle_type_2& b) const { - typedef typename rectangle_coordinate_type<rectangle_type_1>::type Unit; - Unit vl1 = get(get(a, orient_), LOW); - Unit vl2 = get(get(b, orient_), LOW); - if(vl1 > vl2) return false; - if(vl1 == vl2) { - orientation_2d perp = orient_.get_perpendicular(); - Unit hl1 = get(get(a, perp), LOW); - Unit hl2 = get(get(b, perp), LOW); - if(hl1 > hl2) return false; - if(hl1 == hl2) { - Unit vh1 = get(get(a, orient_), HIGH); - Unit vh2 = get(get(b, orient_), HIGH); - if(vh1 > vh2) return false; - if(vh1 == vh2) { - Unit hh1 = get(get(a, perp), HIGH); - Unit hh2 = get(get(b, perp), HIGH); - return hh1 < hh2; - } - } - } - return true; - } - - }; - - template <typename T> - template <typename interval_type_1> - inline void rectangle_data<T>::set(orientation_2d orient, const interval_type_1& interval) { - assign(ranges_[orient.to_int()], interval); - } - - template <class T> - template <class T2> - rectangle_data<T>& rectangle_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <class T> - template <class T2> - bool rectangle_data<T>::operator==(const T2& rvalue) const { - return equivalence(*this, rvalue); - } - - template <typename T> - struct geometry_concept<rectangle_data<T> > { - typedef rectangle_concept type; - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/rectangle_data.hpp b/contrib/restricted/boost/boost/polygon/rectangle_data.hpp deleted file mode 100644 index 5a1f99e611..0000000000 --- a/contrib/restricted/boost/boost/polygon/rectangle_data.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - 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_RECTANGLE_DATA_HPP -#define BOOST_POLYGON_RECTANGLE_DATA_HPP - -#include "isotropy.hpp" -//interval -#include "interval_data.hpp" - -namespace boost { namespace polygon{ - -template <typename T> -class rectangle_data { -public: - typedef T coordinate_type; - typedef interval_data<T> interval_type; - inline rectangle_data():ranges_() {} - inline rectangle_data(T xl, T yl, T xh, T yh):ranges_() { - if(xl > xh) std::swap(xl, xh); - if(yl > yh) std::swap(yl, yh); - ranges_[HORIZONTAL] = interval_data<T>(xl, xh); - ranges_[VERTICAL] = interval_data<T>(yl, yh); - } - template <typename interval_type_1, typename interval_type_2> - inline rectangle_data(const interval_type_1& hrange, - const interval_type_2& vrange):ranges_() { - set(HORIZONTAL, hrange); set(VERTICAL, vrange); } - - inline rectangle_data(const rectangle_data& that):ranges_() { (*this) = that; } - inline rectangle_data& operator=(const rectangle_data& that) { - ranges_[0] = that.ranges_[0]; ranges_[1] = that.ranges_[1]; return *this; - } - template <typename T2> - inline rectangle_data& operator=(const T2& rvalue); - - template <typename T2> - inline bool operator==(const T2& rvalue) const; - template <typename T2> - inline bool operator!=(const T2& rvalue) const { return !((*this) == rvalue); } - - inline interval_data<coordinate_type> get(orientation_2d orient) const { - return ranges_[orient.to_int()]; } - inline coordinate_type get(direction_2d dir) const { - return ranges_[orientation_2d(dir).to_int()].get(direction_1d(dir)); - } - inline void set(direction_2d dir, coordinate_type value) { - return ranges_[orientation_2d(dir).to_int()].set(direction_1d(dir), value); - } - template <typename interval_type_1> - inline void set(orientation_2d orient, const interval_type_1& interval); -private: - interval_data<coordinate_type> ranges_[2]; -}; - - -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/rectangle_traits.hpp b/contrib/restricted/boost/boost/polygon/rectangle_traits.hpp deleted file mode 100644 index bd494744af..0000000000 --- a/contrib/restricted/boost/boost/polygon/rectangle_traits.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - 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_RECTANGLE_TRAITS_HPP -#define BOOST_POLYGON_RECTANGLE_TRAITS_HPP - -#include "isotropy.hpp" - -namespace boost { namespace polygon{ - - template <typename T, typename enable = gtl_yes> - struct rectangle_traits {}; - template <typename T> - struct rectangle_traits<T, gtl_no> {}; - - template <typename T> - struct rectangle_traits<T, typename gtl_same_type<typename T::interval_type, typename T::interval_type>::type> { - typedef typename T::coordinate_type coordinate_type; - typedef typename T::interval_type interval_type; - static inline interval_type get(const T& rectangle, orientation_2d orient) { - return rectangle.get(orient); } - }; - - template <typename T> - struct rectangle_mutable_traits { - template <typename T2> - static inline void set(T& rectangle, orientation_2d orient, const T2& interval) { - rectangle.set(orient, interval); } - template <typename T2, typename T3> - static inline T construct(const T2& interval_horizontal, - const T3& interval_vertical) { - return T(interval_horizontal, interval_vertical); } - }; -} -} -#endif diff --git a/contrib/restricted/boost/boost/polygon/segment_concept.hpp b/contrib/restricted/boost/boost/polygon/segment_concept.hpp deleted file mode 100644 index 2f41c1be99..0000000000 --- a/contrib/restricted/boost/boost/polygon/segment_concept.hpp +++ /dev/null @@ -1,696 +0,0 @@ -// Boost.Polygon library segment_concept.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_SEGMENT_CONCEPT_HPP -#define BOOST_POLYGON_SEGMENT_CONCEPT_HPP - -#include "isotropy.hpp" -#include "segment_traits.hpp" -#include "rectangle_concept.hpp" - -namespace boost { -namespace polygon { - -struct segment_concept {}; - -template <typename ConceptType> -struct is_segment_concept { - typedef gtl_no type; -}; - -template <> -struct is_segment_concept<segment_concept> { - typedef gtl_yes type; -}; - -template <typename ConceptType> -struct is_mutable_segment_concept { - typedef gtl_no type; -}; - -template <> -struct is_mutable_segment_concept<segment_concept> { - typedef gtl_yes type; -}; - -template <typename GeometryType, typename BoolType> -struct segment_distance_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct segment_distance_type_by_concept<GeometryType, gtl_yes> { - typedef typename coordinate_traits< - typename segment_traits<GeometryType>::coordinate_type - >::coordinate_distance type; -}; - -template <typename GeometryType> -struct segment_distance_type { - typedef typename segment_distance_type_by_concept< - GeometryType, - typename is_segment_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -template <typename GeometryType, typename BoolType> -struct segment_point_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct segment_point_type_by_concept<GeometryType, gtl_yes> { - typedef typename segment_traits<GeometryType>::point_type type; -}; - -template <typename GeometryType> -struct segment_point_type { - typedef typename segment_point_type_by_concept< - GeometryType, - typename is_segment_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -template <typename GeometryType, typename BoolType> -struct segment_coordinate_type_by_concept { - typedef void type; -}; - -template <typename GeometryType> -struct segment_coordinate_type_by_concept<GeometryType, gtl_yes> { - typedef typename segment_traits<GeometryType>::coordinate_type type; -}; - -template <typename GeometryType> -struct segment_coordinate_type { - typedef typename segment_coordinate_type_by_concept< - GeometryType, - typename is_segment_concept< - typename geometry_concept<GeometryType>::type - >::type - >::type type; -}; - -struct y_s_get : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_get, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -typename segment_point_type<Segment>::type>::type -get(const Segment& segment, direction_1d dir) { - return segment_traits<Segment>::get(segment, dir); -} - -struct y_s_set : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_set, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -void>::type set(Segment& segment, direction_1d dir, const Point& point) { - segment_mutable_traits<Segment>::set(segment, dir, point); -} - -struct y_s_construct : gtl_yes {}; - -template <typename Segment, typename Point1, typename Point2> -typename enable_if< - typename gtl_and_4< - y_s_construct, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point1>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point2>::type - >::type - >::type, -Segment>::type construct(const Point1& low, const Point2& high) { - return segment_mutable_traits<Segment>::construct(low, high); -} - -struct y_s_copy_construct : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_copy_construct, - typename is_mutable_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -Segment1>::type copy_construct(const Segment2& segment) { - return construct<Segment1>(get(segment, LOW), get(segment, HIGH)); -} - -struct y_s_assign : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_assign, - typename is_mutable_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -Segment1>::type& assign(Segment1& segment1, const Segment2& segment2) { - return segment1 = copy_construct<Segment1>(segment2); -} - -struct y_s_equivalence : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_equivalence, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -bool>::type equivalence(const Segment1& segment1, const Segment2& segment2) { - return get(segment1, LOW) == get(segment2, LOW) && - get(segment1, HIGH) == get(segment2, HIGH); -} - -struct y_s_low : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_low, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -typename segment_point_type<Segment>::type>::type low(const Segment& segment) { - return get(segment, LOW); -} - -struct y_s_high : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_high, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -typename segment_point_type<Segment>::type>::type high(const Segment& segment) { - return get(segment, HIGH); -} - -struct y_s_center : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_center, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -typename segment_point_type<Segment>::type>::type -center(const Segment& segment) { - return construct<typename segment_point_type<Segment>::type>( - (x(high(segment)) + x(low(segment)))/2, - (y(high(segment)) + y(low(segment)))/2); -} - -struct y_s_low2 : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_low2, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -void>::type low(Segment& segment, const Point& point) { - set(segment, LOW, point); -} - -struct y_s_high2 : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_high2, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -void>::type high(Segment& segment, const Point& point) { - set(segment, HIGH, point); -} - -struct y_s_orientation1 : gtl_yes {}; - -// -1 for CW, 0 for collinear and 1 for CCW. -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_orientation1, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -int>::type orientation(const Segment1& segment1, const Segment2& segment2) { - typedef typename coordinate_traits< - typename segment_traits<Segment1>::coordinate_type - >::manhattan_area_type int_x2; - typedef typename coordinate_traits< - typename segment_traits<Segment1>::coordinate_type - >::unsigned_area_type uint_x2; - int_x2 a1 = (int_x2)x(high(segment1)) - (int_x2)x(low(segment1)); - int_x2 b1 = (int_x2)y(high(segment1)) - (int_x2)y(low(segment1)); - int_x2 a2 = (int_x2)x(high(segment2)) - (int_x2)x(low(segment2)); - int_x2 b2 = (int_x2)y(high(segment2)) - (int_x2)y(low(segment2)); - - int sign1 = 0; - int sign2 = 0; - if (a1 && b2) - sign1 = ((a1 > 0) ^ (b2 > 0)) ? -1 : 1; - if (a2 && b1) - sign2 = ((a2 > 0) ^ (b1 > 0)) ? -1 : 1; - - if (sign1 != sign2) - return (sign1 < sign2) ? -1 : 1; - uint_x2 a3 = (uint_x2)(a1 < 0 ? -a1 : a1) * (uint_x2)(b2 < 0 ? -b2 : b2); - uint_x2 b3 = (uint_x2)(b1 < 0 ? -b1 : b1) * (uint_x2)(a2 < 0 ? -a2 : a2); - if (a3 == b3) - return 0; - return ((a3 < b3) ^ (sign1 == 1)) ? 1 : -1; -} - -struct y_s_orientation2 : gtl_yes {}; - -// -1 for right, 0 for collinear and 1 for left. -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_orientation2, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -int>::type orientation(const Segment& segment, const Point& point) { - Segment segment2 = construct<Segment>(high(segment), point); - return orientation(segment, segment2); -} - -struct y_s_contains : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_contains, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -bool>::type contains(const Segment& segment, - const Point& point, bool consider_touch = true ) { - if (orientation(segment, point)) - return false; - rectangle_data<typename segment_coordinate_type<Segment>::type> rect; - set_points(rect, low(segment), high(segment)); - if (!contains(rect, point, true)) - return false; - if (!consider_touch && - (equivalence(low(segment), point) || - equivalence(high(segment), point))) - return false; - return true; -} - -struct y_s_contains2 : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_contains2, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -bool>::type contains(const Segment1& segment1, - const Segment2& segment2, bool consider_touch = true) { - return contains(segment1, get(segment2, LOW), consider_touch) && - contains(segment1, get(segment2, HIGH), consider_touch); -} - -struct y_s_length : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_length, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -typename segment_distance_type<Segment>::type>::type -length(const Segment& segment) { - return euclidean_distance(low(segment), high(segment)); -} - -struct y_s_scale_up : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_scale_up, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -Segment>::type& scale_up(Segment& segment, - typename coordinate_traits< - typename segment_coordinate_type<Segment>::type - >::unsigned_area_type factor) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, scale_up(l, factor)); - high(segment, scale_up(h, factor)); - return segment; -} - -struct y_s_scale_down : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_scale_down, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -Segment>::type& scale_down(Segment& segment, - typename coordinate_traits< - typename segment_coordinate_type<Segment>::type - >::unsigned_area_type factor) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, scale_down(l, factor)); - high(segment, scale_down(h, factor)); - return segment; -} - -struct y_s_scale : gtl_yes {}; - -template <typename Segment, typename Scale> -typename enable_if< - typename gtl_and< - y_s_scale, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -Segment>::type& scale(Segment& segment, const Scale& sc) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, scale(l, sc)); - high(segment, scale(h, sc)); - return segment; -} - -struct y_s_transform : gtl_yes {}; - -template <typename Segment, typename Transform> -typename enable_if< - typename gtl_and< - y_s_transform, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -Segment>::type& transform(Segment& segment, const Transform& tr) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, transform(l, tr)); - high(segment, transform(h, tr)); - return segment; -} - -struct y_s_move : gtl_yes {}; - -template <typename Segment> -typename enable_if< - typename gtl_and< - y_s_move, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, -Segment>::type& move(Segment& segment, orientation_2d orient, - typename segment_coordinate_type<Segment>::type displacement) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, move(l, orient, displacement)); - high(segment, move(h, orient, displacement)); - return segment; -} - -struct y_s_convolve : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_convolve, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -Segment>::type& convolve(Segment& segment, const Point& point) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, convolve(l, point)); - high(segment, convolve(h, point)); - return segment; -} - -struct y_s_deconvolve : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_deconvolve, - typename is_mutable_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -Segment>::type& deconvolve(Segment& segment, const Point& point) { - typename segment_point_type<Segment>::type l = low(segment); - typename segment_point_type<Segment>::type h = high(segment); - low(segment, deconvolve(l, point)); - high(segment, deconvolve(h, point)); - return segment; -} - -struct y_s_abuts1 : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_abuts1, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -bool>::type abuts(const Segment1& segment1, - const Segment2& segment2, direction_1d dir) { - return dir.to_int() ? equivalence(low(segment2) , high(segment1)) : - equivalence(low(segment1) , high(segment2)); -} - -struct y_s_abuts2 : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_abuts2, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -bool>::type abuts(const Segment1& segment1, const Segment2& segment2) { - return abuts(segment1, segment2, HIGH) || abuts(segment1, segment2, LOW); -} - -struct y_s_e_intersects : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_e_intersects, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -bool ->::type intersects(const Segment1& segment1, const Segment2& segment2, - bool consider_touch = true) { - rectangle_data<typename segment_coordinate_type<Segment1>::type> rect1, rect2; - set_points(rect1, low(segment1), high(segment1)); - set_points(rect2, low(segment2), high(segment2)); - // Check if axis-parallel rectangles containing segments intersect. - if (!intersects(rect1, rect2, true)) - return false; - int or1_1 = orientation(segment1, low(segment2)); - int or1_2 = orientation(segment1, high(segment2)); - if (or1_1 * or1_2 > 0) - return false; - int or2_1 = orientation(segment2, low(segment1)); - int or2_2 = orientation(segment2, high(segment1)); - if (or2_1 * or2_2 > 0) - return false; - if (consider_touch || (or1_1 && or1_2) || (or2_1 && or2_2)) - return true; - if (or1_1 || or1_2) - return false; - return intersects(vertical(rect1), vertical(rect2), false) || - intersects(horizontal(rect1), horizontal(rect2), false); -} - -struct y_s_e_dist : gtl_yes {}; - -template <typename Segment, typename Point> -typename enable_if< - typename gtl_and_3< - y_s_e_dist, - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type, - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, -typename segment_distance_type<Segment>::type>::type -euclidean_distance(const Segment& segment, const Point& point) { - typedef typename segment_distance_type<Segment>::type Unit; - Unit x1 = x(low(segment)); - Unit y1 = y(low(segment)); - Unit x2 = x(high(segment)); - Unit y2 = y(high(segment)); - Unit X = x(point); - Unit Y = y(point); - Unit A = X - x1; - Unit B = Y - y1; - Unit C = x2 - x1; - Unit D = y2 - y1; - Unit param = (A * C + B * D); - Unit length_sq = C * C + D * D; - if (param > length_sq) { - return euclidean_distance(high(segment), point); - } else if (param < 0.0) { - return euclidean_distance(low(segment), point); - } - if (length_sq == 0.0) - return 0.0; - Unit denom = std::sqrt(length_sq); - Unit result = (A * D - C * B) / denom; - return (result < 0.0) ? -result : result; -} - -struct y_s_e_dist2 : gtl_yes {}; - -template <typename Segment1, typename Segment2> -typename enable_if< - typename gtl_and_3< - y_s_e_dist2, - typename is_segment_concept< - typename geometry_concept<Segment1>::type - >::type, - typename is_segment_concept< - typename geometry_concept<Segment2>::type - >::type - >::type, -typename segment_distance_type<Segment1>::type>::type -euclidean_distance(const Segment1& segment1, const Segment2& segment2) { - if (intersects(segment1, segment2)) - return 0.0; - typename segment_distance_type<Segment1>::type - result1 = euclidean_distance(segment1, low(segment2)), - result2 = euclidean_distance(segment1, high(segment2)), - result3 = euclidean_distance(segment2, low(segment1)), - result4 = euclidean_distance(segment2, high(segment1)); - if (result2 < result1) - result1 = result2; - if (result4 < result3) - result3 = result4; - return (result1 < result3) ? result1 : result3; -} -} // polygon -} // boost - -#endif // BOOST_POLYGON_SEGMENT_CONCEPT_HPP diff --git a/contrib/restricted/boost/boost/polygon/segment_data.hpp b/contrib/restricted/boost/boost/polygon/segment_data.hpp deleted file mode 100644 index 2bcfe11f97..0000000000 --- a/contrib/restricted/boost/boost/polygon/segment_data.hpp +++ /dev/null @@ -1,121 +0,0 @@ -// Boost.Polygon library segment_data.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_SEGMENT_DATA_HPP -#define BOOST_POLYGON_SEGMENT_DATA_HPP - -#include "isotropy.hpp" -#include "segment_concept.hpp" - -namespace boost { -namespace polygon { - -template <typename T> -class segment_data { - public: - typedef T coordinate_type; - typedef point_data<T> point_type; - - segment_data() -#ifndef BOOST_POLYGON_MSVC - : points_() -#endif - {} - - segment_data(const point_type& low, const point_type& high) { - points_[LOW] = low; - points_[HIGH] = high; - } - - segment_data(const segment_data& that) { - points_[0] = that.points_[0]; - points_[1] = that.points_[1]; - } - - segment_data& operator=(const segment_data& that) { - points_[0] = that.points_[0]; - points_[1] = that.points_[1]; - return *this; - } - - template <typename SegmentType> - segment_data& operator=(const SegmentType& that) { - assign(*this, that); - return *this; - } - - point_type get(direction_1d dir) const { - return points_[dir.to_int()]; - } - - void set(direction_1d dir, const point_type& point) { - points_[dir.to_int()] = point; - } - - point_type low() const { - return points_[LOW]; - } - - segment_data& low(const point_type& point) { - points_[LOW] = point; - return *this; - } - - point_type high() const { - return points_[HIGH]; - } - - segment_data& high(const point_type& point) { - points_[HIGH] = point; - return *this; - } - - bool operator==(const segment_data& that) const { - return (points_[0] == that.points_[0]) && - (points_[1] == that.points_[1]); - } - - bool operator!=(const segment_data& that) const { - return (points_[0] != that.points_[0]) || - (points_[1] != that.points_[1]); - } - - bool operator<(const segment_data& that) const { - if (points_[0] != that.points_[0]) { - return points_[0] < that.points_[0]; - } - return points_[1] < that.points_[1]; - } - - bool operator<=(const segment_data& that) const { - return !(that < *this); - } - - bool operator>(const segment_data& that) const { - return that < *this; - } - - bool operator>=(const segment_data& that) const { - return !((*this) < that); - } - - private: - point_type points_[2]; -}; - -template <typename CType> -struct geometry_concept<segment_data<CType> > { - typedef segment_concept type; -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_SEGMENT_DATA_HPP diff --git a/contrib/restricted/boost/boost/polygon/segment_traits.hpp b/contrib/restricted/boost/boost/polygon/segment_traits.hpp deleted file mode 100644 index cb092bd408..0000000000 --- a/contrib/restricted/boost/boost/polygon/segment_traits.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Boost.Polygon library segment_traits.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_SEGMENT_TRAITS_HPP -#define BOOST_POLYGON_SEGMENT_TRAITS_HPP - -#include "isotropy.hpp" - -namespace boost { -namespace polygon { - -template <typename Segment> -struct segment_traits { - typedef Segment segment_type; - typedef typename segment_type::point_type point_type; - typedef typename segment_type::coordinate_type coordinate_type; - - static point_type get( - const segment_type& segment, direction_1d dir) { - return segment.get(dir); - } -}; - -template <typename Segment> -struct segment_mutable_traits { - typedef Segment segment_type; - typedef typename segment_type::point_type point_type; - typedef typename segment_type::coordinate_type coordinate_type; - - static void set( - segment_type& segment, direction_1d dir, const point_type& point) { - segment.set(dir, point); - } - - static segment_type construct(const point_type& low, const point_type& high) { - return segment_type(low, high); - } -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_SEGMENT_TRAITS_HPP diff --git a/contrib/restricted/boost/boost/polygon/segment_utils.hpp b/contrib/restricted/boost/boost/polygon/segment_utils.hpp deleted file mode 100644 index 075f7c32d2..0000000000 --- a/contrib/restricted/boost/boost/polygon/segment_utils.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright 2012 Lucanus Simonson - - 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_SEGMENT_UTILS_HPP -#define BOOST_POLYGON_SEGMENT_UTILS_HPP - -#include <iterator> -#include <set> -#include <vector> - -#include "detail/scan_arbitrary.hpp" -#include "isotropy.hpp" -#include "rectangle_concept.hpp" -#include "segment_concept.hpp" - -namespace boost { -namespace polygon { - -template <typename Segment, typename SegmentIterator> -typename enable_if< - typename gtl_and< - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename std::iterator_traits<SegmentIterator>::value_type - >::type - >::type - >::type, - typename gtl_if< - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type - >::type, - void ->::type -intersect_segments( - std::vector<std::pair<std::size_t, Segment> >& result, - SegmentIterator first, SegmentIterator last) { - typedef typename segment_traits<Segment>::coordinate_type Unit; - typedef typename scanline_base<Unit>::Point Point; - typedef typename scanline_base<Unit>::half_edge half_edge; - typedef int segment_id; - std::vector<std::pair<half_edge, segment_id> > half_edges; - std::vector<std::pair<half_edge, segment_id> > half_edges_out; - segment_id id_in = 0; - half_edges.reserve(std::distance(first, last)); - for (; first != last; ++first) { - Point l, h; - assign(l, low(*first)); - assign(h, high(*first)); - half_edges.push_back(std::make_pair(half_edge(l, h), id_in++)); - } - half_edges_out.reserve(half_edges.size()); - // Apparently no need to pre-sort data when calling validate_scan. - if (half_edges.size() != 0) { - line_intersection<Unit>::validate_scan( - half_edges_out, half_edges.begin(), half_edges.end()); - } - - result.reserve(result.size() + half_edges_out.size()); - for (std::size_t i = 0; i < half_edges_out.size(); ++i) { - std::size_t id = (std::size_t)(half_edges_out[i].second); - Point l = half_edges_out[i].first.first; - Point h = half_edges_out[i].first.second; - result.push_back(std::make_pair(id, construct<Segment>(l, h))); - } -} - -template <typename SegmentContainer, typename SegmentIterator> -typename enable_if< - typename gtl_and< - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename std::iterator_traits<SegmentIterator>::value_type - >::type - >::type - >::type, - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename SegmentContainer::value_type - >::type - >::type - >::type - >::type, - void ->::type -intersect_segments( - SegmentContainer& result, - SegmentIterator first, - SegmentIterator last) { - typedef typename SegmentContainer::value_type segment_type; - typedef typename segment_traits<segment_type>::coordinate_type Unit; - typedef typename scanline_base<Unit>::Point Point; - typedef typename scanline_base<Unit>::half_edge half_edge; - typedef int segment_id; - std::vector<std::pair<half_edge, segment_id> > half_edges; - std::vector<std::pair<half_edge, segment_id> > half_edges_out; - segment_id id_in = 0; - half_edges.reserve(std::distance(first, last)); - for (; first != last; ++first) { - Point l, h; - assign(l, low(*first)); - assign(h, high(*first)); - half_edges.push_back(std::make_pair(half_edge(l, h), id_in++)); - } - half_edges_out.reserve(half_edges.size()); - // Apparently no need to pre-sort data when calling validate_scan. - if (half_edges.size() != 0) { - line_intersection<Unit>::validate_scan( - half_edges_out, half_edges.begin(), half_edges.end()); - } - - result.reserve(result.size() + half_edges_out.size()); - for (std::size_t i = 0; i < half_edges_out.size(); ++i) { - Point l = half_edges_out[i].first.first; - Point h = half_edges_out[i].first.second; - result.push_back(construct<segment_type>(l, h)); - } -} - -template <typename Rectangle, typename SegmentIterator> -typename enable_if< - typename gtl_and< - typename gtl_if< - typename is_rectangle_concept< - typename geometry_concept<Rectangle>::type - >::type - >::type, - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename std::iterator_traits<SegmentIterator>::value_type - >::type - >::type - >::type - >::type, - bool ->::type -envelope_segments( - Rectangle& rect, - SegmentIterator first, - SegmentIterator last) { - for (SegmentIterator it = first; it != last; ++it) { - if (it == first) { - set_points(rect, low(*it), high(*it)); - } else { - encompass(rect, low(*it)); - encompass(rect, high(*it)); - } - } - return first != last; -} -} // polygon -} // boost - -#endif // BOOST_POLYGON_SEGMENT_UTILS_HPP diff --git a/contrib/restricted/boost/boost/polygon/transform.hpp b/contrib/restricted/boost/boost/polygon/transform.hpp deleted file mode 100644 index 1bb0cd9d59..0000000000 --- a/contrib/restricted/boost/boost/polygon/transform.hpp +++ /dev/null @@ -1,476 +0,0 @@ -// Boost.Polygon library transform.hpp header file - -// Copyright (c) Intel Corporation 2008. -// Copyright (c) 2008-2012 Simonson Lucanus. -// Copyright (c) 2012-2012 Andrii Sydorchuk. - -// See http://www.boost.org for updates, documentation, and revision history. -// Use, modification and distribution is 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_TRANSFORM_HPP -#define BOOST_POLYGON_TRANSFORM_HPP - -#include "isotropy.hpp" - -namespace boost { -namespace polygon { -// Transformation of Coordinate System. -// Enum meaning: -// Select which direction_2d to change the positive direction of each -// axis in the old coordinate system to map it to the new coordiante system. -// The first direction_2d listed for each enum is the direction to map the -// positive horizontal direction to. -// The second direction_2d listed for each enum is the direction to map the -// positive vertical direction to. -// The zero position bit (LSB) indicates whether the horizontal axis flips -// when transformed. -// The 1st postion bit indicates whether the vertical axis flips when -// transformed. -// The 2nd position bit indicates whether the horizontal and vertical axis -// swap positions when transformed. -// Enum Values: -// 000 EAST NORTH -// 001 WEST NORTH -// 010 EAST SOUTH -// 011 WEST SOUTH -// 100 NORTH EAST -// 101 SOUTH EAST -// 110 NORTH WEST -// 111 SOUTH WEST -class axis_transformation { - public: - enum ATR { -#ifdef BOOST_POLYGON_ENABLE_DEPRECATED - EN = 0, - WN = 1, - ES = 2, - WS = 3, - NE = 4, - SE = 5, - NW = 6, - SW = 7, -#endif - NULL_TRANSFORM = 0, - BEGIN_TRANSFORM = 0, - EAST_NORTH = 0, - WEST_NORTH = 1, FLIP_X = 1, - EAST_SOUTH = 2, FLIP_Y = 2, - WEST_SOUTH = 3, FLIP_XY = 3, - NORTH_EAST = 4, SWAP_XY = 4, - SOUTH_EAST = 5, ROTATE_LEFT = 5, - NORTH_WEST = 6, ROTATE_RIGHT = 6, - SOUTH_WEST = 7, FLIP_SWAP_XY = 7, - END_TRANSFORM = 7 - }; - - // Individual axis enum values indicate which axis an implicit individual - // axis will be mapped to. - // The value of the enum paired with an axis provides the information - // about what the axis will transform to. - // Three individual axis values, one for each axis, are equivalent to one - // ATR enum value, but easier to work with because they are independent. - // Converting to and from the individual axis values from the ATR value - // is a convenient way to implement tranformation related functionality. - // Enum meanings: - // PX: map to positive x axis - // NX: map to negative x axis - // PY: map to positive y axis - // NY: map to negative y axis - enum INDIVIDUAL_AXIS { - PX = 0, - NX = 1, - PY = 2, - NY = 3 - }; - - axis_transformation() : atr_(NULL_TRANSFORM) {} - explicit axis_transformation(ATR atr) : atr_(atr) {} - axis_transformation(const axis_transformation& atr) : atr_(atr.atr_) {} - - explicit axis_transformation(const orientation_2d& orient) { - const ATR tmp[2] = { - NORTH_EAST, // sort x, then y - EAST_NORTH // sort y, then x - }; - atr_ = tmp[orient.to_int()]; - } - - explicit axis_transformation(const direction_2d& dir) { - const ATR tmp[4] = { - SOUTH_EAST, // sort x, then y - NORTH_EAST, // sort x, then y - EAST_SOUTH, // sort y, then x - EAST_NORTH // sort y, then x - }; - atr_ = tmp[dir.to_int()]; - } - - // assignment operator - axis_transformation& operator=(const axis_transformation& a) { - atr_ = a.atr_; - return *this; - } - - // assignment operator - axis_transformation& operator=(const ATR& atr) { - atr_ = atr; - return *this; - } - - // equivalence operator - bool operator==(const axis_transformation& a) const { - return atr_ == a.atr_; - } - - // inequivalence operator - bool operator!=(const axis_transformation& a) const { - return !(*this == a); - } - - // ordering - bool operator<(const axis_transformation& a) const { - return atr_ < a.atr_; - } - - // concatenate this with that - axis_transformation& operator+=(const axis_transformation& a) { - bool abit2 = (a.atr_ & 4) != 0; - bool abit1 = (a.atr_ & 2) != 0; - bool abit0 = (a.atr_ & 1) != 0; - bool bit2 = (atr_ & 4) != 0; - bool bit1 = (atr_ & 2) != 0; - bool bit0 = (atr_ & 1) != 0; - int indexes[2][2] = { - { (int)bit2, (int)(!bit2) }, - { (int)abit2, (int)(!abit2) } - }; - int zero_bits[2][2] = { - {bit0, bit1}, {abit0, abit1} - }; - int nbit1 = zero_bits[0][1] ^ zero_bits[1][indexes[0][1]]; - int nbit0 = zero_bits[0][0] ^ zero_bits[1][indexes[0][0]]; - indexes[0][0] = indexes[1][indexes[0][0]]; - indexes[0][1] = indexes[1][indexes[0][1]]; - int nbit2 = indexes[0][0] & 1; // swap xy - atr_ = (ATR)((nbit2 << 2) + (nbit1 << 1) + nbit0); - return *this; - } - - // concatenation operator - axis_transformation operator+(const axis_transformation& a) const { - axis_transformation retval(*this); - return retval+=a; - } - - // populate_axis_array writes the three INDIVIDUAL_AXIS values that the - // ATR enum value of 'this' represent into axis_array - void populate_axis_array(INDIVIDUAL_AXIS axis_array[]) const { - bool bit2 = (atr_ & 4) != 0; - bool bit1 = (atr_ & 2) != 0; - bool bit0 = (atr_ & 1) != 0; - axis_array[1] = (INDIVIDUAL_AXIS)(((int)(!bit2) << 1) + bit1); - axis_array[0] = (INDIVIDUAL_AXIS)(((int)(bit2) << 1) + bit0); - } - - // it is recommended that the directions stored in an array - // in the caller code for easier isotropic access by orientation value - void get_directions(direction_2d& horizontal_dir, - direction_2d& vertical_dir) const { - bool bit2 = (atr_ & 4) != 0; - bool bit1 = (atr_ & 2) != 0; - bool bit0 = (atr_ & 1) != 0; - vertical_dir = direction_2d((direction_2d_enum)(((int)(!bit2) << 1) + !bit1)); - horizontal_dir = direction_2d((direction_2d_enum)(((int)(bit2) << 1) + !bit0)); - } - - // combine_axis_arrays concatenates this_array and that_array overwriting - // the result into this_array - static void combine_axis_arrays(INDIVIDUAL_AXIS this_array[], - const INDIVIDUAL_AXIS that_array[]) { - int indexes[2] = { this_array[0] >> 1, this_array[1] >> 1 }; - int zero_bits[2][2] = { - { this_array[0] & 1, this_array[1] & 1 }, - { that_array[0] & 1, that_array[1] & 1 } - }; - this_array[0] = (INDIVIDUAL_AXIS)((int)this_array[0] | - ((int)zero_bits[0][0] ^ - (int)zero_bits[1][indexes[0]])); - this_array[1] = (INDIVIDUAL_AXIS)((int)this_array[1] | - ((int)zero_bits[0][1] ^ - (int)zero_bits[1][indexes[1]])); - } - - // write_back_axis_array converts an array of three INDIVIDUAL_AXIS values - // to the ATR enum value and sets 'this' to that value - void write_back_axis_array(const INDIVIDUAL_AXIS this_array[]) { - int bit2 = ((int)this_array[0] & 2) != 0; // swap xy - int bit1 = ((int)this_array[1] & 1); - int bit0 = ((int)this_array[0] & 1); - atr_ = ATR((bit2 << 2) + (bit1 << 1) + bit0); - } - - // behavior is deterministic but undefined in the case where illegal - // combinations of directions are passed in. - axis_transformation& set_directions(const direction_2d& horizontal_dir, - const direction_2d& vertical_dir) { - int bit2 = (static_cast<orientation_2d>(horizontal_dir).to_int()) != 0; - int bit1 = !(vertical_dir.to_int() & 1); - int bit0 = !(horizontal_dir.to_int() & 1); - atr_ = ATR((bit2 << 2) + (bit1 << 1) + bit0); - return *this; - } - - // transform the three coordinates by reference - template <typename coordinate_type> - void transform(coordinate_type& x, coordinate_type& y) const { - int bit2 = (atr_ & 4) != 0; - int bit1 = (atr_ & 2) != 0; - int bit0 = (atr_ & 1) != 0; - x *= -((bit0 << 1) - 1); - y *= -((bit1 << 1) - 1); - predicated_swap(bit2 != 0, x, y); - } - - // invert this axis_transformation - axis_transformation& invert() { - int bit2 = ((atr_ & 4) != 0); - int bit1 = ((atr_ & 2) != 0); - int bit0 = ((atr_ & 1) != 0); - // swap bit 0 and bit 1 if bit2 is 1 - predicated_swap(bit2 != 0, bit0, bit1); - bit1 = bit1 << 1; - atr_ = (ATR)(atr_ & (32+16+8+4)); // mask away bit0 and bit1 - atr_ = (ATR)(atr_ | bit0 | bit1); - return *this; - } - - // get the inverse axis_transformation of this - axis_transformation inverse() const { - axis_transformation retval(*this); - return retval.invert(); - } - - private: - ATR atr_; -}; - -// Scaling object to be used to store the scale factor for each axis. -// For use by the transformation object, in that context the scale factor -// is the amount that each axis scales by when transformed. -template <typename scale_factor_type> -class anisotropic_scale_factor { - public: - anisotropic_scale_factor() { - scale_[0] = 1; - scale_[1] = 1; - } - anisotropic_scale_factor(scale_factor_type xscale, - scale_factor_type yscale) { - scale_[0] = xscale; - scale_[1] = yscale; - } - - // get a component of the anisotropic_scale_factor by orientation - scale_factor_type get(orientation_2d orient) const { - return scale_[orient.to_int()]; - } - - // set a component of the anisotropic_scale_factor by orientation - void set(orientation_2d orient, scale_factor_type value) { - scale_[orient.to_int()] = value; - } - - scale_factor_type x() const { - return scale_[HORIZONTAL]; - } - - scale_factor_type y() const { - return scale_[VERTICAL]; - } - - void x(scale_factor_type value) { - scale_[HORIZONTAL] = value; - } - - void y(scale_factor_type value) { - scale_[VERTICAL] = value; - } - - // concatination operator (convolve scale factors) - anisotropic_scale_factor operator+(const anisotropic_scale_factor& s) const { - anisotropic_scale_factor<scale_factor_type> retval(*this); - return retval += s; - } - - // concatinate this with that - const anisotropic_scale_factor& operator+=( - const anisotropic_scale_factor& s) { - scale_[0] *= s.scale_[0]; - scale_[1] *= s.scale_[1]; - return *this; - } - - // transform this scale with an axis_transform - anisotropic_scale_factor& transform(axis_transformation atr) { - direction_2d dirs[2]; - atr.get_directions(dirs[0], dirs[1]); - scale_factor_type tmp[2] = {scale_[0], scale_[1]}; - for (int i = 0; i < 2; ++i) { - scale_[orientation_2d(dirs[i]).to_int()] = tmp[i]; - } - return *this; - } - - // scale the two coordinates - template <typename coordinate_type> - void scale(coordinate_type& x, coordinate_type& y) const { - x = scaling_policy<coordinate_type>::round( - (scale_factor_type)x * get(HORIZONTAL)); - y = scaling_policy<coordinate_type>::round( - (scale_factor_type)y * get(HORIZONTAL)); - } - - // invert this scale factor to give the reverse scale factor - anisotropic_scale_factor& invert() { - x(1/x()); - y(1/y()); - return *this; - } - - private: - scale_factor_type scale_[2]; -}; - -// Transformation object, stores and provides services for transformations. -// Consits of axis transformation, scale factor and translation. -// The tranlation is the position of the origin of the new coordinate system of -// in the old system. Coordinates are scaled before they are transformed. -template <typename coordinate_type> -class transformation { - public: - transformation() : atr_(), p_(0, 0) {} - explicit transformation(axis_transformation atr) : atr_(atr), p_(0, 0) {} - explicit transformation(axis_transformation::ATR atr) : atr_(atr), p_(0, 0) {} - transformation(const transformation& tr) : atr_(tr.atr_), p_(tr.p_) {} - - template <typename point_type> - explicit transformation(const point_type& p) : atr_(), p_(0, 0) { - set_translation(p); - } - - template <typename point_type> - transformation(axis_transformation atr, - const point_type& p) : atr_(atr), p_(0, 0) { - set_translation(p); - } - - template <typename point_type> - transformation(axis_transformation atr, - const point_type& referencePt, - const point_type& destinationPt) : atr_(), p_(0, 0) { - transformation<coordinate_type> tmp(referencePt); - transformation<coordinate_type> rotRef(atr); - transformation<coordinate_type> tmpInverse = tmp.inverse(); - point_type decon(referencePt); - deconvolve(decon, destinationPt); - transformation<coordinate_type> displacement(decon); - tmp += rotRef; - tmp += tmpInverse; - tmp += displacement; - (*this) = tmp; - } - - // equivalence operator - bool operator==(const transformation& tr) const { - return (atr_ == tr.atr_) && (p_ == tr.p_); - } - - // inequivalence operator - bool operator!=(const transformation& tr) const { - return !(*this == tr); - } - - // ordering - bool operator<(const transformation& tr) const { - return (atr_ < tr.atr_) || ((atr_ == tr.atr_) && (p_ < tr.p_)); - } - - // concatenation operator - transformation operator+(const transformation& tr) const { - transformation<coordinate_type> retval(*this); - return retval+=tr; - } - - // concatenate this with that - const transformation& operator+=(const transformation& tr) { - coordinate_type x, y; - transformation<coordinate_type> inv = inverse(); - inv.transform(x, y); - p_.set(HORIZONTAL, p_.get(HORIZONTAL) + x); - p_.set(VERTICAL, p_.get(VERTICAL) + y); - // concatenate axis transforms - atr_ += tr.atr_; - return *this; - } - - // get the axis_transformation portion of this - axis_transformation get_axis_transformation() const { - return atr_; - } - - // set the axis_transformation portion of this - void set_axis_transformation(const axis_transformation& atr) { - atr_ = atr; - } - - // get the translation - template <typename point_type> - void get_translation(point_type& p) const { - assign(p, p_); - } - - // set the translation - template <typename point_type> - void set_translation(const point_type& p) { - assign(p_, p); - } - - // apply the 2D portion of this transformation to the two coordinates given - void transform(coordinate_type& x, coordinate_type& y) const { - y -= p_.get(VERTICAL); - x -= p_.get(HORIZONTAL); - atr_.transform(x, y); - } - - // invert this transformation - transformation& invert() { - coordinate_type x = p_.get(HORIZONTAL), y = p_.get(VERTICAL); - atr_.transform(x, y); - x *= -1; - y *= -1; - p_ = point_data<coordinate_type>(x, y); - atr_.invert(); - return *this; - } - - // get the inverse of this transformation - transformation inverse() const { - transformation<coordinate_type> ret_val(*this); - return ret_val.invert(); - } - - void get_directions(direction_2d& horizontal_dir, - direction_2d& vertical_dir) const { - return atr_.get_directions(horizontal_dir, vertical_dir); - } - - private: - axis_transformation atr_; - point_data<coordinate_type> p_; -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_TRANSFORM_HPP diff --git a/contrib/restricted/boost/boost/polygon/voronoi.hpp b/contrib/restricted/boost/boost/polygon/voronoi.hpp deleted file mode 100644 index bca6add873..0000000000 --- a/contrib/restricted/boost/boost/polygon/voronoi.hpp +++ /dev/null @@ -1,157 +0,0 @@ -// Boost.Polygon library voronoi.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_VORONOI -#define BOOST_POLYGON_VORONOI - -#include "isotropy.hpp" -#include "point_concept.hpp" -#include "segment_concept.hpp" - -#include "voronoi_builder.hpp" -#include "voronoi_diagram.hpp" - -// Public methods to compute Voronoi diagram of a set of points and segments. -// Coordinates of the points and of the endpoints of the segments should belong -// to the 32-bit signed integer range [-2^31, 2^31-1]. To use wider input -// coordinate range voronoi_builder configuration via coordinate type traits -// is required. -// Complexity - O(N*logN), memory usage - O(N), N - number of input objects. -namespace boost { -namespace polygon { - -template <typename Point, typename VB> -typename enable_if< - typename gtl_if< - typename is_point_concept< - typename geometry_concept<Point>::type - >::type - >::type, - std::size_t ->::type insert(const Point& point, VB* vb) { - return vb->insert_point(x(point), y(point)); -} - -template <typename PointIterator, typename VB> -typename enable_if< - typename gtl_if< - typename is_point_concept< - typename geometry_concept< - typename std::iterator_traits<PointIterator>::value_type - >::type - >::type - >::type, - void ->::type insert(const PointIterator first, const PointIterator last, VB* vb) { - for (PointIterator it = first; it != last; ++it) { - insert(*it, vb); - } -} - -template <typename Segment, typename VB> -typename enable_if< - typename gtl_if< - typename is_segment_concept< - typename geometry_concept<Segment>::type - >::type - >::type, - std::size_t ->::type insert(const Segment& segment, VB* vb) { - return vb->insert_segment( - x(low(segment)), y(low(segment)), - x(high(segment)), y(high(segment))); -} - -template <typename SegmentIterator, typename VB> -typename enable_if< - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename std::iterator_traits<SegmentIterator>::value_type - >::type - >::type - >::type, - void ->::type insert(const SegmentIterator first, - const SegmentIterator last, - VB* vb) { - for (SegmentIterator it = first; it != last; ++it) { - insert(*it, vb); - } -} - -template <typename PointIterator, typename VD> -typename enable_if< - typename gtl_if< - typename is_point_concept< - typename geometry_concept< - typename std::iterator_traits<PointIterator>::value_type - >::type - >::type - >::type, - void ->::type construct_voronoi(const PointIterator first, - const PointIterator last, - VD* vd) { - default_voronoi_builder builder; - insert(first, last, &builder); - builder.construct(vd); -} - -template <typename SegmentIterator, typename VD> -typename enable_if< - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename std::iterator_traits<SegmentIterator>::value_type - >::type - >::type - >::type, - void ->::type construct_voronoi(const SegmentIterator first, - const SegmentIterator last, - VD* vd) { - default_voronoi_builder builder; - insert(first, last, &builder); - builder.construct(vd); -} - -template <typename PointIterator, typename SegmentIterator, typename VD> -typename enable_if< - typename gtl_and< - typename gtl_if< - typename is_point_concept< - typename geometry_concept< - typename std::iterator_traits<PointIterator>::value_type - >::type - >::type - >::type, - typename gtl_if< - typename is_segment_concept< - typename geometry_concept< - typename std::iterator_traits<SegmentIterator>::value_type - >::type - >::type - >::type - >::type, - void ->::type construct_voronoi(const PointIterator p_first, - const PointIterator p_last, - const SegmentIterator s_first, - const SegmentIterator s_last, - VD* vd) { - default_voronoi_builder builder; - insert(p_first, p_last, &builder); - insert(s_first, s_last, &builder); - builder.construct(vd); -} -} // polygon -} // boost - -#endif // BOOST_POLYGON_VORONOI diff --git a/contrib/restricted/boost/boost/polygon/voronoi_builder.hpp b/contrib/restricted/boost/boost/polygon/voronoi_builder.hpp deleted file mode 100644 index 7da638e499..0000000000 --- a/contrib/restricted/boost/boost/polygon/voronoi_builder.hpp +++ /dev/null @@ -1,521 +0,0 @@ -// Boost.Polygon library voronoi_builder.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_VORONOI_BUILDER -#define BOOST_POLYGON_VORONOI_BUILDER - -#include <algorithm> -#include <map> -#include <queue> -#include <utility> -#include <vector> - -#include "detail/voronoi_ctypes.hpp" -#include "detail/voronoi_predicates.hpp" -#include "detail/voronoi_structures.hpp" - -#include "voronoi_geometry_type.hpp" - -namespace boost { -namespace polygon { -// GENERAL INFO: -// The sweepline algorithm implementation to compute Voronoi diagram of -// points and non-intersecting segments (excluding endpoints). -// Complexity - O(N*logN), memory usage - O(N), where N is the total number -// of input geometries. -// -// CONTRACT: -// 1) Input geometries should have integral (e.g. int32, int64) coordinate type. -// 2) Input geometries should not intersect except their endpoints. -// -// IMPLEMENTATION DETAILS: -// Each input point creates one input site. Each input segment creates three -// input sites: two for its endpoints and one for the segment itself (this is -// made to simplify output construction). All the site objects are constructed -// and sorted at the algorithm initialization step. Priority queue is used to -// dynamically hold circle events. At each step of the algorithm execution the -// leftmost event is retrieved by comparing the current site event and the -// topmost element from the circle event queue. STL map (red-black tree) -// container was chosen to hold state of the beach line. The keys of the map -// correspond to the neighboring sites that form a bisector and values map to -// the corresponding Voronoi edges in the output data structure. -template <typename T, - typename CTT = detail::voronoi_ctype_traits<T>, - typename VP = detail::voronoi_predicates<CTT> > -class voronoi_builder { - public: - typedef typename CTT::int_type int_type; - typedef typename CTT::fpt_type fpt_type; - - voronoi_builder() : index_(0) {} - - // Each point creates a single site event. - std::size_t insert_point(const int_type& x, const int_type& y) { - site_events_.push_back(site_event_type(x, y)); - site_events_.back().initial_index(index_); - site_events_.back().source_category(SOURCE_CATEGORY_SINGLE_POINT); - return index_++; - } - - // Each segment creates three site events that correspond to: - // 1) the start point of the segment; - // 2) the end point of the segment; - // 3) the segment itself defined by its start point. - std::size_t insert_segment( - const int_type& x1, const int_type& y1, - const int_type& x2, const int_type& y2) { - // Set up start point site. - point_type p1(x1, y1); - site_events_.push_back(site_event_type(p1)); - site_events_.back().initial_index(index_); - site_events_.back().source_category(SOURCE_CATEGORY_SEGMENT_START_POINT); - - // Set up end point site. - point_type p2(x2, y2); - site_events_.push_back(site_event_type(p2)); - site_events_.back().initial_index(index_); - site_events_.back().source_category(SOURCE_CATEGORY_SEGMENT_END_POINT); - - // Set up segment site. - if (point_comparison_(p1, p2)) { - site_events_.push_back(site_event_type(p1, p2)); - site_events_.back().source_category(SOURCE_CATEGORY_INITIAL_SEGMENT); - } else { - site_events_.push_back(site_event_type(p2, p1)); - site_events_.back().source_category(SOURCE_CATEGORY_REVERSE_SEGMENT); - } - site_events_.back().initial_index(index_); - return index_++; - } - - // Run sweepline algorithm and fill output data structure. - template <typename OUTPUT> - void construct(OUTPUT* output) { - // Init structures. - output->_reserve(site_events_.size()); - init_sites_queue(); - init_beach_line(output); - - // The algorithm stops when there are no events to process. - event_comparison_predicate event_comparison; - while (!circle_events_.empty() || - !(site_event_iterator_ == site_events_.end())) { - if (circle_events_.empty()) { - process_site_event(output); - } else if (site_event_iterator_ == site_events_.end()) { - process_circle_event(output); - } else { - if (event_comparison(*site_event_iterator_, - circle_events_.top().first)) { - process_site_event(output); - } else { - process_circle_event(output); - } - } - while (!circle_events_.empty() && - !circle_events_.top().first.is_active()) { - circle_events_.pop(); - } - } - beach_line_.clear(); - - // Finish construction. - output->_build(); - } - - void clear() { - index_ = 0; - site_events_.clear(); - } - - private: - typedef detail::point_2d<int_type> point_type; - typedef detail::site_event<int_type> site_event_type; - typedef typename std::vector<site_event_type>::const_iterator - site_event_iterator_type; - typedef detail::circle_event<fpt_type> circle_event_type; - typedef typename VP::template point_comparison_predicate<point_type> - point_comparison_predicate; - typedef typename VP:: - template event_comparison_predicate<site_event_type, circle_event_type> - event_comparison_predicate; - typedef typename VP:: - template circle_formation_predicate<site_event_type, circle_event_type> - circle_formation_predicate_type; - typedef void edge_type; - typedef detail::beach_line_node_key<site_event_type> key_type; - typedef detail::beach_line_node_data<edge_type, circle_event_type> - value_type; - typedef typename VP::template node_comparison_predicate<key_type> - node_comparer_type; - typedef std::map< key_type, value_type, node_comparer_type > beach_line_type; - typedef typename beach_line_type::iterator beach_line_iterator; - typedef std::pair<circle_event_type, beach_line_iterator> event_type; - typedef struct { - bool operator()(const event_type& lhs, const event_type& rhs) const { - return predicate(rhs.first, lhs.first); - } - event_comparison_predicate predicate; - } event_comparison_type; - typedef detail::ordered_queue<event_type, event_comparison_type> - circle_event_queue_type; - typedef std::pair<point_type, beach_line_iterator> end_point_type; - - void init_sites_queue() { - // Sort site events. - std::sort(site_events_.begin(), site_events_.end(), - event_comparison_predicate()); - - // Remove duplicates. - site_events_.erase(std::unique( - site_events_.begin(), site_events_.end()), site_events_.end()); - - // Index sites. - for (std::size_t cur = 0; cur < site_events_.size(); ++cur) { - site_events_[cur].sorted_index(cur); - } - - // Init site iterator. - site_event_iterator_ = site_events_.begin(); - } - - template <typename OUTPUT> - void init_beach_line(OUTPUT* output) { - if (site_events_.empty()) - return; - if (site_events_.size() == 1) { - // Handle single site event case. - output->_process_single_site(site_events_[0]); - ++site_event_iterator_; - } else { - int skip = 0; - - while (site_event_iterator_ != site_events_.end() && - VP::is_vertical(site_event_iterator_->point0(), - site_events_.begin()->point0()) && - VP::is_vertical(*site_event_iterator_)) { - ++site_event_iterator_; - ++skip; - } - - if (skip == 1) { - // Init beach line with the first two sites. - init_beach_line_default(output); - } else { - // Init beach line with collinear vertical sites. - init_beach_line_collinear_sites(output); - } - } - } - - // Init beach line with the two first sites. - // The first site is always a point. - template <typename OUTPUT> - void init_beach_line_default(OUTPUT* output) { - // Get the first and the second site event. - site_event_iterator_type it_first = site_events_.begin(); - site_event_iterator_type it_second = site_events_.begin(); - ++it_second; - insert_new_arc( - *it_first, *it_first, *it_second, beach_line_.end(), output); - // The second site was already processed. Move the iterator. - ++site_event_iterator_; - } - - // Init beach line with collinear sites. - template <typename OUTPUT> - void init_beach_line_collinear_sites(OUTPUT* output) { - site_event_iterator_type it_first = site_events_.begin(); - site_event_iterator_type it_second = site_events_.begin(); - ++it_second; - while (it_second != site_event_iterator_) { - // Create a new beach line node. - key_type new_node(*it_first, *it_second); - - // Update the output. - edge_type* edge = output->_insert_new_edge(*it_first, *it_second).first; - - // Insert a new bisector into the beach line. - beach_line_.insert(beach_line_.end(), - std::pair<key_type, value_type>(new_node, value_type(edge))); - - // Update iterators. - ++it_first; - ++it_second; - } - } - - void deactivate_circle_event(value_type* value) { - if (value->circle_event()) { - value->circle_event()->deactivate(); - value->circle_event(NULL); - } - } - - template <typename OUTPUT> - void process_site_event(OUTPUT* output) { - // Get next site event to process. - site_event_type site_event = *site_event_iterator_; - - // Move site iterator. - site_event_iterator_type last = site_event_iterator_ + 1; - - // If a new site is an end point of some segment, - // remove temporary nodes from the beach line data structure. - if (!site_event.is_segment()) { - while (!end_points_.empty() && - end_points_.top().first == site_event.point0()) { - beach_line_iterator b_it = end_points_.top().second; - end_points_.pop(); - beach_line_.erase(b_it); - } - } else { - while (last != site_events_.end() && - last->is_segment() && last->point0() == site_event.point0()) - ++last; - } - - // Find the node in the binary search tree with left arc - // lying above the new site point. - key_type new_key(*site_event_iterator_); - beach_line_iterator right_it = beach_line_.lower_bound(new_key); - - for (; site_event_iterator_ != last; ++site_event_iterator_) { - site_event = *site_event_iterator_; - beach_line_iterator left_it = right_it; - - // Do further processing depending on the above node position. - // For any two neighboring nodes the second site of the first node - // is the same as the first site of the second node. - if (right_it == beach_line_.end()) { - // The above arc corresponds to the second arc of the last node. - // Move the iterator to the last node. - --left_it; - - // Get the second site of the last node - const site_event_type& site_arc = left_it->first.right_site(); - - // Insert new nodes into the beach line. Update the output. - right_it = insert_new_arc( - site_arc, site_arc, site_event, right_it, output); - - // Add a candidate circle to the circle event queue. - // There could be only one new circle event formed by - // a new bisector and the one on the left. - activate_circle_event(left_it->first.left_site(), - left_it->first.right_site(), - site_event, right_it); - } else if (right_it == beach_line_.begin()) { - // The above arc corresponds to the first site of the first node. - const site_event_type& site_arc = right_it->first.left_site(); - - // Insert new nodes into the beach line. Update the output. - left_it = insert_new_arc( - site_arc, site_arc, site_event, right_it, output); - - // If the site event is a segment, update its direction. - if (site_event.is_segment()) { - site_event.inverse(); - } - - // Add a candidate circle to the circle event queue. - // There could be only one new circle event formed by - // a new bisector and the one on the right. - activate_circle_event(site_event, right_it->first.left_site(), - right_it->first.right_site(), right_it); - right_it = left_it; - } else { - // The above arc corresponds neither to the first, - // nor to the last site in the beach line. - const site_event_type& site_arc2 = right_it->first.left_site(); - const site_event_type& site3 = right_it->first.right_site(); - - // Remove the candidate circle from the event queue. - deactivate_circle_event(&right_it->second); - --left_it; - const site_event_type& site_arc1 = left_it->first.right_site(); - const site_event_type& site1 = left_it->first.left_site(); - - // Insert new nodes into the beach line. Update the output. - beach_line_iterator new_node_it = - insert_new_arc(site_arc1, site_arc2, site_event, right_it, output); - - // Add candidate circles to the circle event queue. - // There could be up to two circle events formed by - // a new bisector and the one on the left or right. - activate_circle_event(site1, site_arc1, site_event, new_node_it); - - // If the site event is a segment, update its direction. - if (site_event.is_segment()) { - site_event.inverse(); - } - activate_circle_event(site_event, site_arc2, site3, right_it); - right_it = new_node_it; - } - } - } - - // In general case circle event is made of the three consecutive sites - // that form two bisectors in the beach line data structure. - // Let circle event sites be A, B, C, two bisectors that define - // circle event are (A, B), (B, C). During circle event processing - // we remove (A, B), (B, C) and insert (A, C). As beach line comparison - // works correctly only if one of the nodes is a new one we remove - // (B, C) bisector and change (A, B) bisector to the (A, C). That's - // why we use const_cast there and take all the responsibility that - // map data structure keeps correct ordering. - template <typename OUTPUT> - void process_circle_event(OUTPUT* output) { - // Get the topmost circle event. - const event_type& e = circle_events_.top(); - const circle_event_type& circle_event = e.first; - beach_line_iterator it_first = e.second; - beach_line_iterator it_last = it_first; - - // Get the C site. - site_event_type site3 = it_first->first.right_site(); - - // Get the half-edge corresponding to the second bisector - (B, C). - edge_type* bisector2 = it_first->second.edge(); - - // Get the half-edge corresponding to the first bisector - (A, B). - --it_first; - edge_type* bisector1 = it_first->second.edge(); - - // Get the A site. - site_event_type site1 = it_first->first.left_site(); - - if (!site1.is_segment() && site3.is_segment() && - site3.point1() == site1.point0()) { - site3.inverse(); - } - - // Change the (A, B) bisector node to the (A, C) bisector node. - const_cast<key_type&>(it_first->first).right_site(site3); - - // Insert the new bisector into the beach line. - it_first->second.edge(output->_insert_new_edge( - site1, site3, circle_event, bisector1, bisector2).first); - - // Remove the (B, C) bisector node from the beach line. - beach_line_.erase(it_last); - it_last = it_first; - - // Pop the topmost circle event from the event queue. - circle_events_.pop(); - - // Check new triplets formed by the neighboring arcs - // to the left for potential circle events. - if (it_first != beach_line_.begin()) { - deactivate_circle_event(&it_first->second); - --it_first; - const site_event_type& site_l1 = it_first->first.left_site(); - activate_circle_event(site_l1, site1, site3, it_last); - } - - // Check the new triplet formed by the neighboring arcs - // to the right for potential circle events. - ++it_last; - if (it_last != beach_line_.end()) { - deactivate_circle_event(&it_last->second); - const site_event_type& site_r1 = it_last->first.right_site(); - activate_circle_event(site1, site3, site_r1, it_last); - } - } - - // Insert new nodes into the beach line. Update the output. - template <typename OUTPUT> - beach_line_iterator insert_new_arc( - const site_event_type& site_arc1, const site_event_type &site_arc2, - const site_event_type& site_event, beach_line_iterator position, - OUTPUT* output) { - // Create two new bisectors with opposite directions. - key_type new_left_node(site_arc1, site_event); - key_type new_right_node(site_event, site_arc2); - - // Set correct orientation for the first site of the second node. - if (site_event.is_segment()) { - new_right_node.left_site().inverse(); - } - - // Update the output. - std::pair<edge_type*, edge_type*> edges = - output->_insert_new_edge(site_arc2, site_event); - position = beach_line_.insert(position, - typename beach_line_type::value_type( - new_right_node, value_type(edges.second))); - - if (site_event.is_segment()) { - // Update the beach line with temporary bisector, that will - // disappear after processing site event corresponding to the - // second endpoint of the segment site. - key_type new_node(site_event, site_event); - new_node.right_site().inverse(); - position = beach_line_.insert(position, - typename beach_line_type::value_type(new_node, value_type(NULL))); - - // Update the data structure that holds temporary bisectors. - end_points_.push(std::make_pair(site_event.point1(), position)); - } - - position = beach_line_.insert(position, - typename beach_line_type::value_type( - new_left_node, value_type(edges.first))); - - return position; - } - - // Add a new circle event to the event queue. - // bisector_node corresponds to the (site2, site3) bisector. - void activate_circle_event(const site_event_type& site1, - const site_event_type& site2, - const site_event_type& site3, - beach_line_iterator bisector_node) { - circle_event_type c_event; - // Check if the three input sites create a circle event. - if (circle_formation_predicate_(site1, site2, site3, c_event)) { - // Add the new circle event to the circle events queue. - // Update bisector's circle event iterator to point to the - // new circle event in the circle event queue. - event_type& e = circle_events_.push( - std::pair<circle_event_type, beach_line_iterator>( - c_event, bisector_node)); - bisector_node->second.circle_event(&e.first); - } - } - - private: - point_comparison_predicate point_comparison_; - struct end_point_comparison { - bool operator() (const end_point_type& end1, - const end_point_type& end2) const { - return point_comparison(end2.first, end1.first); - } - point_comparison_predicate point_comparison; - }; - - std::vector<site_event_type> site_events_; - site_event_iterator_type site_event_iterator_; - std::priority_queue< end_point_type, std::vector<end_point_type>, - end_point_comparison > end_points_; - circle_event_queue_type circle_events_; - beach_line_type beach_line_; - circle_formation_predicate_type circle_formation_predicate_; - std::size_t index_; - - // Disallow copy constructor and operator= - voronoi_builder(const voronoi_builder&); - void operator=(const voronoi_builder&); -}; - -typedef voronoi_builder<detail::int32> default_voronoi_builder; -} // polygon -} // boost - -#endif // BOOST_POLYGON_VORONOI_BUILDER diff --git a/contrib/restricted/boost/boost/polygon/voronoi_diagram.hpp b/contrib/restricted/boost/boost/polygon/voronoi_diagram.hpp deleted file mode 100644 index 33803f4eba..0000000000 --- a/contrib/restricted/boost/boost/polygon/voronoi_diagram.hpp +++ /dev/null @@ -1,620 +0,0 @@ -// Boost.Polygon library voronoi_diagram.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_VORONOI_DIAGRAM -#define BOOST_POLYGON_VORONOI_DIAGRAM - -#include <vector> -#include <utility> - -#include "detail/voronoi_ctypes.hpp" -#include "detail/voronoi_structures.hpp" - -#include "voronoi_geometry_type.hpp" - -namespace boost { -namespace polygon { - -// Forward declarations. -template <typename T> -class voronoi_edge; - -// Represents Voronoi cell. -// Data members: -// 1) index of the source within the initial input set -// 2) pointer to the incident edge -// 3) mutable color member -// Cell may contain point or segment site inside. -template <typename T> -class voronoi_cell { - public: - typedef T coordinate_type; - typedef std::size_t color_type; - typedef voronoi_edge<coordinate_type> voronoi_edge_type; - typedef std::size_t source_index_type; - typedef SourceCategory source_category_type; - - voronoi_cell(source_index_type source_index, - source_category_type source_category) : - source_index_(source_index), - incident_edge_(NULL), - color_(source_category) {} - - // Returns true if the cell contains point site, false else. - bool contains_point() const { - source_category_type source_category = this->source_category(); - return belongs(source_category, GEOMETRY_CATEGORY_POINT); - } - - // Returns true if the cell contains segment site, false else. - bool contains_segment() const { - source_category_type source_category = this->source_category(); - return belongs(source_category, GEOMETRY_CATEGORY_SEGMENT); - } - - source_index_type source_index() const { - return source_index_; - } - - source_category_type source_category() const { - return static_cast<source_category_type>(color_ & SOURCE_CATEGORY_BITMASK); - } - - // Degenerate cells don't have any incident edges. - bool is_degenerate() const { return incident_edge_ == NULL; } - - voronoi_edge_type* incident_edge() { return incident_edge_; } - const voronoi_edge_type* incident_edge() const { return incident_edge_; } - void incident_edge(voronoi_edge_type* e) { incident_edge_ = e; } - - color_type color() const { return color_ >> BITS_SHIFT; } - void color(color_type color) const { - color_ &= BITS_MASK; - color_ |= color << BITS_SHIFT; - } - - private: - // 5 color bits are reserved. - enum Bits { - BITS_SHIFT = 0x5, - BITS_MASK = 0x1F - }; - - source_index_type source_index_; - voronoi_edge_type* incident_edge_; - mutable color_type color_; -}; - -// Represents Voronoi vertex. -// Data members: -// 1) vertex coordinates -// 2) pointer to the incident edge -// 3) mutable color member -template <typename T> -class voronoi_vertex { - public: - typedef T coordinate_type; - typedef std::size_t color_type; - typedef voronoi_edge<coordinate_type> voronoi_edge_type; - - voronoi_vertex(const coordinate_type& x, const coordinate_type& y) : - x_(x), - y_(y), - incident_edge_(NULL), - color_(0) {} - - const coordinate_type& x() const { return x_; } - const coordinate_type& y() const { return y_; } - - bool is_degenerate() const { return incident_edge_ == NULL; } - - voronoi_edge_type* incident_edge() { return incident_edge_; } - const voronoi_edge_type* incident_edge() const { return incident_edge_; } - void incident_edge(voronoi_edge_type* e) { incident_edge_ = e; } - - color_type color() const { return color_ >> BITS_SHIFT; } - void color(color_type color) const { - color_ &= BITS_MASK; - color_ |= color << BITS_SHIFT; - } - - private: - // 5 color bits are reserved. - enum Bits { - BITS_SHIFT = 0x5, - BITS_MASK = 0x1F - }; - - coordinate_type x_; - coordinate_type y_; - voronoi_edge_type* incident_edge_; - mutable color_type color_; -}; - -// Half-edge data structure. Represents Voronoi edge. -// Data members: -// 1) pointer to the corresponding cell -// 2) pointer to the vertex that is the starting -// point of the half-edge -// 3) pointer to the twin edge -// 4) pointer to the CCW next edge -// 5) pointer to the CCW prev edge -// 6) mutable color member -template <typename T> -class voronoi_edge { - public: - typedef T coordinate_type; - typedef voronoi_cell<coordinate_type> voronoi_cell_type; - typedef voronoi_vertex<coordinate_type> voronoi_vertex_type; - typedef voronoi_edge<coordinate_type> voronoi_edge_type; - typedef std::size_t color_type; - - voronoi_edge(bool is_linear, bool is_primary) : - cell_(NULL), - vertex_(NULL), - twin_(NULL), - next_(NULL), - prev_(NULL), - color_(0) { - if (is_linear) - color_ |= BIT_IS_LINEAR; - if (is_primary) - color_ |= BIT_IS_PRIMARY; - } - - voronoi_cell_type* cell() { return cell_; } - const voronoi_cell_type* cell() const { return cell_; } - void cell(voronoi_cell_type* c) { cell_ = c; } - - voronoi_vertex_type* vertex0() { return vertex_; } - const voronoi_vertex_type* vertex0() const { return vertex_; } - void vertex0(voronoi_vertex_type* v) { vertex_ = v; } - - voronoi_vertex_type* vertex1() { return twin_->vertex0(); } - const voronoi_vertex_type* vertex1() const { return twin_->vertex0(); } - - voronoi_edge_type* twin() { return twin_; } - const voronoi_edge_type* twin() const { return twin_; } - void twin(voronoi_edge_type* e) { twin_ = e; } - - voronoi_edge_type* next() { return next_; } - const voronoi_edge_type* next() const { return next_; } - void next(voronoi_edge_type* e) { next_ = e; } - - voronoi_edge_type* prev() { return prev_; } - const voronoi_edge_type* prev() const { return prev_; } - void prev(voronoi_edge_type* e) { prev_ = e; } - - // Returns a pointer to the rotation next edge - // over the starting point of the half-edge. - voronoi_edge_type* rot_next() { return prev_->twin(); } - const voronoi_edge_type* rot_next() const { return prev_->twin(); } - - // Returns a pointer to the rotation prev edge - // over the starting point of the half-edge. - voronoi_edge_type* rot_prev() { return twin_->next(); } - const voronoi_edge_type* rot_prev() const { return twin_->next(); } - - // Returns true if the edge is finite (segment, parabolic arc). - // Returns false if the edge is infinite (ray, line). - bool is_finite() const { return vertex0() && vertex1(); } - - // Returns true if the edge is infinite (ray, line). - // Returns false if the edge is finite (segment, parabolic arc). - bool is_infinite() const { return !vertex0() || !vertex1(); } - - // Returns true if the edge is linear (segment, ray, line). - // Returns false if the edge is curved (parabolic arc). - bool is_linear() const { - return (color_ & BIT_IS_LINEAR) ? true : false; - } - - // Returns true if the edge is curved (parabolic arc). - // Returns false if the edge is linear (segment, ray, line). - bool is_curved() const { - return (color_ & BIT_IS_LINEAR) ? false : true; - } - - // Returns false if edge goes through the endpoint of the segment. - // Returns true else. - bool is_primary() const { - return (color_ & BIT_IS_PRIMARY) ? true : false; - } - - // Returns true if edge goes through the endpoint of the segment. - // Returns false else. - bool is_secondary() const { - return (color_ & BIT_IS_PRIMARY) ? false : true; - } - - color_type color() const { return color_ >> BITS_SHIFT; } - void color(color_type color) const { - color_ &= BITS_MASK; - color_ |= color << BITS_SHIFT; - } - - private: - // 5 color bits are reserved. - enum Bits { - BIT_IS_LINEAR = 0x1, // linear is opposite to curved - BIT_IS_PRIMARY = 0x2, // primary is opposite to secondary - - BITS_SHIFT = 0x5, - BITS_MASK = 0x1F - }; - - voronoi_cell_type* cell_; - voronoi_vertex_type* vertex_; - voronoi_edge_type* twin_; - voronoi_edge_type* next_; - voronoi_edge_type* prev_; - mutable color_type color_; -}; - -template <typename T> -struct voronoi_diagram_traits { - typedef T coordinate_type; - typedef voronoi_cell<coordinate_type> cell_type; - typedef voronoi_vertex<coordinate_type> vertex_type; - typedef voronoi_edge<coordinate_type> edge_type; - typedef class { - public: - enum { ULPS = 128 }; - bool operator()(const vertex_type& v1, const vertex_type& v2) const { - return (ulp_cmp(v1.x(), v2.x(), ULPS) == - detail::ulp_comparison<T>::EQUAL) && - (ulp_cmp(v1.y(), v2.y(), ULPS) == - detail::ulp_comparison<T>::EQUAL); - } - private: - typename detail::ulp_comparison<T> ulp_cmp; - } vertex_equality_predicate_type; -}; - -// Voronoi output data structure. -// CCW ordering is used on the faces perimeter and around the vertices. -template <typename T, typename TRAITS = voronoi_diagram_traits<T> > -class voronoi_diagram { - public: - typedef typename TRAITS::coordinate_type coordinate_type; - typedef typename TRAITS::cell_type cell_type; - typedef typename TRAITS::vertex_type vertex_type; - typedef typename TRAITS::edge_type edge_type; - - typedef std::vector<cell_type> cell_container_type; - typedef typename cell_container_type::const_iterator const_cell_iterator; - - typedef std::vector<vertex_type> vertex_container_type; - typedef typename vertex_container_type::const_iterator const_vertex_iterator; - - typedef std::vector<edge_type> edge_container_type; - typedef typename edge_container_type::const_iterator const_edge_iterator; - - voronoi_diagram() {} - - void clear() { - cells_.clear(); - vertices_.clear(); - edges_.clear(); - } - - const cell_container_type& cells() const { - return cells_; - } - - const vertex_container_type& vertices() const { - return vertices_; - } - - const edge_container_type& edges() const { - return edges_; - } - - std::size_t num_cells() const { - return cells_.size(); - } - - std::size_t num_edges() const { - return edges_.size(); - } - - std::size_t num_vertices() const { - return vertices_.size(); - } - - void _reserve(std::size_t num_sites) { - cells_.reserve(num_sites); - vertices_.reserve(num_sites << 1); - edges_.reserve((num_sites << 2) + (num_sites << 1)); - } - - template <typename CT> - void _process_single_site(const detail::site_event<CT>& site) { - cells_.push_back(cell_type(site.initial_index(), site.source_category())); - } - - // Insert a new half-edge into the output data structure. - // Takes as input left and right sites that form a new bisector. - // Returns a pair of pointers to a new half-edges. - template <typename CT> - std::pair<void*, void*> _insert_new_edge( - const detail::site_event<CT>& site1, - const detail::site_event<CT>& site2) { - // Get sites' indexes. - std::size_t site_index1 = site1.sorted_index(); - std::size_t site_index2 = site2.sorted_index(); - - bool is_linear = is_linear_edge(site1, site2); - bool is_primary = is_primary_edge(site1, site2); - - // Create a new half-edge that belongs to the first site. - edges_.push_back(edge_type(is_linear, is_primary)); - edge_type& edge1 = edges_.back(); - - // Create a new half-edge that belongs to the second site. - edges_.push_back(edge_type(is_linear, is_primary)); - edge_type& edge2 = edges_.back(); - - // Add the initial cell during the first edge insertion. - if (cells_.empty()) { - cells_.push_back(cell_type( - site1.initial_index(), site1.source_category())); - } - - // The second site represents a new site during site event - // processing. Add a new cell to the cell records. - cells_.push_back(cell_type( - site2.initial_index(), site2.source_category())); - - // Set up pointers to cells. - edge1.cell(&cells_[site_index1]); - edge2.cell(&cells_[site_index2]); - - // Set up twin pointers. - edge1.twin(&edge2); - edge2.twin(&edge1); - - // Return a pointer to the new half-edge. - return std::make_pair(&edge1, &edge2); - } - - // Insert a new half-edge into the output data structure with the - // start at the point where two previously added half-edges intersect. - // Takes as input two sites that create a new bisector, circle event - // that corresponds to the intersection point of the two old half-edges, - // pointers to those half-edges. Half-edges' direction goes out of the - // new Voronoi vertex point. Returns a pair of pointers to a new half-edges. - template <typename CT1, typename CT2> - std::pair<void*, void*> _insert_new_edge( - const detail::site_event<CT1>& site1, - const detail::site_event<CT1>& site3, - const detail::circle_event<CT2>& circle, - void* data12, void* data23) { - edge_type* edge12 = static_cast<edge_type*>(data12); - edge_type* edge23 = static_cast<edge_type*>(data23); - - // Add a new Voronoi vertex. - vertices_.push_back(vertex_type(circle.x(), circle.y())); - vertex_type& new_vertex = vertices_.back(); - - // Update vertex pointers of the old edges. - edge12->vertex0(&new_vertex); - edge23->vertex0(&new_vertex); - - bool is_linear = is_linear_edge(site1, site3); - bool is_primary = is_primary_edge(site1, site3); - - // Add a new half-edge. - edges_.push_back(edge_type(is_linear, is_primary)); - edge_type& new_edge1 = edges_.back(); - new_edge1.cell(&cells_[site1.sorted_index()]); - - // Add a new half-edge. - edges_.push_back(edge_type(is_linear, is_primary)); - edge_type& new_edge2 = edges_.back(); - new_edge2.cell(&cells_[site3.sorted_index()]); - - // Update twin pointers. - new_edge1.twin(&new_edge2); - new_edge2.twin(&new_edge1); - - // Update vertex pointer. - new_edge2.vertex0(&new_vertex); - - // Update Voronoi prev/next pointers. - edge12->prev(&new_edge1); - new_edge1.next(edge12); - edge12->twin()->next(edge23); - edge23->prev(edge12->twin()); - edge23->twin()->next(&new_edge2); - new_edge2.prev(edge23->twin()); - - // Return a pointer to the new half-edge. - return std::make_pair(&new_edge1, &new_edge2); - } - - void _build() { - // Remove degenerate edges. - edge_iterator last_edge = edges_.begin(); - for (edge_iterator it = edges_.begin(); it != edges_.end(); it += 2) { - const vertex_type* v1 = it->vertex0(); - const vertex_type* v2 = it->vertex1(); - if (v1 && v2 && vertex_equality_predicate_(*v1, *v2)) { - remove_edge(&(*it)); - } else { - if (it != last_edge) { - edge_type* e1 = &(*last_edge = *it); - edge_type* e2 = &(*(last_edge + 1) = *(it + 1)); - e1->twin(e2); - e2->twin(e1); - if (e1->prev()) { - e1->prev()->next(e1); - e2->next()->prev(e2); - } - if (e2->prev()) { - e1->next()->prev(e1); - e2->prev()->next(e2); - } - } - last_edge += 2; - } - } - edges_.erase(last_edge, edges_.end()); - - // Set up incident edge pointers for cells and vertices. - for (edge_iterator it = edges_.begin(); it != edges_.end(); ++it) { - it->cell()->incident_edge(&(*it)); - if (it->vertex0()) { - it->vertex0()->incident_edge(&(*it)); - } - } - - // Remove degenerate vertices. - vertex_iterator last_vertex = vertices_.begin(); - for (vertex_iterator it = vertices_.begin(); it != vertices_.end(); ++it) { - if (it->incident_edge()) { - if (it != last_vertex) { - *last_vertex = *it; - vertex_type* v = &(*last_vertex); - edge_type* e = v->incident_edge(); - do { - e->vertex0(v); - e = e->rot_next(); - } while (e != v->incident_edge()); - } - ++last_vertex; - } - } - vertices_.erase(last_vertex, vertices_.end()); - - // Set up next/prev pointers for infinite edges. - if (vertices_.empty()) { - if (!edges_.empty()) { - // Update prev/next pointers for the line edges. - edge_iterator edge_it = edges_.begin(); - edge_type* edge1 = &(*edge_it); - edge1->next(edge1); - edge1->prev(edge1); - ++edge_it; - edge1 = &(*edge_it); - ++edge_it; - - while (edge_it != edges_.end()) { - edge_type* edge2 = &(*edge_it); - ++edge_it; - - edge1->next(edge2); - edge1->prev(edge2); - edge2->next(edge1); - edge2->prev(edge1); - - edge1 = &(*edge_it); - ++edge_it; - } - - edge1->next(edge1); - edge1->prev(edge1); - } - } else { - // Update prev/next pointers for the ray edges. - for (cell_iterator cell_it = cells_.begin(); - cell_it != cells_.end(); ++cell_it) { - if (cell_it->is_degenerate()) - continue; - // Move to the previous edge while - // it is possible in the CW direction. - edge_type* left_edge = cell_it->incident_edge(); - while (left_edge->prev() != NULL) { - left_edge = left_edge->prev(); - // Terminate if this is not a boundary cell. - if (left_edge == cell_it->incident_edge()) - break; - } - - if (left_edge->prev() != NULL) - continue; - - edge_type* right_edge = cell_it->incident_edge(); - while (right_edge->next() != NULL) - right_edge = right_edge->next(); - left_edge->prev(right_edge); - right_edge->next(left_edge); - } - } - } - - private: - typedef typename cell_container_type::iterator cell_iterator; - typedef typename vertex_container_type::iterator vertex_iterator; - typedef typename edge_container_type::iterator edge_iterator; - typedef typename TRAITS::vertex_equality_predicate_type - vertex_equality_predicate_type; - - template <typename SEvent> - bool is_primary_edge(const SEvent& site1, const SEvent& site2) const { - bool flag1 = site1.is_segment(); - bool flag2 = site2.is_segment(); - if (flag1 && !flag2) { - return (site1.point0() != site2.point0()) && - (site1.point1() != site2.point0()); - } - if (!flag1 && flag2) { - return (site2.point0() != site1.point0()) && - (site2.point1() != site1.point0()); - } - return true; - } - - template <typename SEvent> - bool is_linear_edge(const SEvent& site1, const SEvent& site2) const { - if (!is_primary_edge(site1, site2)) { - return true; - } - return !(site1.is_segment() ^ site2.is_segment()); - } - - // Remove degenerate edge. - void remove_edge(edge_type* edge) { - // Update the endpoints of the incident edges to the second vertex. - vertex_type* vertex = edge->vertex0(); - edge_type* updated_edge = edge->twin()->rot_next(); - while (updated_edge != edge->twin()) { - updated_edge->vertex0(vertex); - updated_edge = updated_edge->rot_next(); - } - - edge_type* edge1 = edge; - edge_type* edge2 = edge->twin(); - - edge_type* edge1_rot_prev = edge1->rot_prev(); - edge_type* edge1_rot_next = edge1->rot_next(); - - edge_type* edge2_rot_prev = edge2->rot_prev(); - edge_type* edge2_rot_next = edge2->rot_next(); - - // Update prev/next pointers for the incident edges. - edge1_rot_next->twin()->next(edge2_rot_prev); - edge2_rot_prev->prev(edge1_rot_next->twin()); - edge1_rot_prev->prev(edge2_rot_next->twin()); - edge2_rot_next->twin()->next(edge1_rot_prev); - } - - cell_container_type cells_; - vertex_container_type vertices_; - edge_container_type edges_; - vertex_equality_predicate_type vertex_equality_predicate_; - - // Disallow copy constructor and operator= - voronoi_diagram(const voronoi_diagram&); - void operator=(const voronoi_diagram&); -}; -} // polygon -} // boost - -#endif // BOOST_POLYGON_VORONOI_DIAGRAM diff --git a/contrib/restricted/boost/boost/polygon/voronoi_geometry_type.hpp b/contrib/restricted/boost/boost/polygon/voronoi_geometry_type.hpp deleted file mode 100644 index 1de80e59ef..0000000000 --- a/contrib/restricted/boost/boost/polygon/voronoi_geometry_type.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Boost.Polygon library voronoi_geometry_type.hpp header file - -// Copyright Andrii Sydorchuk 2010-2012. -// Distributed under 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifndef BOOST_POLYGON_VORONOI_GEOMETRY_TYPE -#define BOOST_POLYGON_VORONOI_GEOMETRY_TYPE - -#include <cstddef> - -namespace boost { -namespace polygon { -// Represents topology type of the voronoi site. -enum GeometryCategory { - GEOMETRY_CATEGORY_POINT = 0x0, - GEOMETRY_CATEGORY_SEGMENT = 0x1 -}; - -// Represents category of the input source that forms Voronoi cell. -enum SourceCategory { - // Point subtypes. - SOURCE_CATEGORY_SINGLE_POINT = 0x0, - SOURCE_CATEGORY_SEGMENT_START_POINT = 0x1, - SOURCE_CATEGORY_SEGMENT_END_POINT = 0x2, - - // Segment subtypes. - SOURCE_CATEGORY_INITIAL_SEGMENT = 0x8, - SOURCE_CATEGORY_REVERSE_SEGMENT = 0x9, - - SOURCE_CATEGORY_GEOMETRY_SHIFT = 0x3, - SOURCE_CATEGORY_BITMASK = 0x1F -}; - -inline bool belongs( - SourceCategory source_category, - GeometryCategory geometry_category) { - return (static_cast<std::size_t>(source_category) >> - SOURCE_CATEGORY_GEOMETRY_SHIFT) == - static_cast<std::size_t>(geometry_category); -} -} // polygon -} // boost - -#endif // BOOST_POLYGON_VORONOI_GEOMETRY_TYPE diff --git a/contrib/restricted/boost/polygon/CMakeLists.txt b/contrib/restricted/boost/polygon/CMakeLists.txt new file mode 100644 index 0000000000..bdee2a86e8 --- /dev/null +++ b/contrib/restricted/boost/polygon/CMakeLists.txt @@ -0,0 +1,20 @@ + +# This file was gererated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_library(restricted-boost-polygon INTERFACE) +target_include_directories(restricted-boost-polygon INTERFACE + ${CMAKE_SOURCE_DIR}/contrib/restricted/boost/polygon/include +) +target_link_libraries(restricted-boost-polygon INTERFACE + contrib-libs-cxxsupp + yutil + restricted-boost-config + restricted-boost-core + restricted-boost-mpl +) |