diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-12-11 18:55:56 +0900 |
commit | 08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch) | |
tree | 7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/polygon | |
parent | bb4dd8289b351fae6b55e303f189127a394a1edd (diff) | |
download | boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2 boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip |
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/polygon')
66 files changed, 10209 insertions, 4437 deletions
diff --git a/boost/polygon/detail/boolean_op.hpp b/boost/polygon/detail/boolean_op.hpp index 400825eb1f..d3e3614fe5 100644 --- a/boost/polygon/detail/boolean_op.hpp +++ b/boost/polygon/detail/boolean_op.hpp @@ -1,6 +1,6 @@ /* 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). @@ -30,8 +30,8 @@ namespace boolean_op { 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); - + inline BooleanOp& operator=(const BooleanOp& that); + //moves scanline forward inline void advanceScan() { nextItr_ = scanData_.begin(); } @@ -39,7 +39,7 @@ namespace boolean_op { //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) { @@ -47,9 +47,9 @@ namespace boolean_op { } return nextItr_ = scanData_.lower_bound(pos); } - inline typename ScanData::iterator insert_(Unit pos, T count){ - return nextItr_ = scanData_.insert(nextItr_, ElementType(pos, count)); - } + 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); }; @@ -78,29 +78,29 @@ namespace boolean_op { //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 + //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_() + 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_() + 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& operator=(const BinaryCount& that); inline BinaryCount(const BinaryCount& that) #ifndef BOOST_POLYGON_MSVC - : counts_() + : counts_() #endif { *this = that; } inline bool operator==(const BinaryCount& that) const; @@ -141,13 +141,13 @@ namespace boolean_op { }; template <class T, typename Unit> - inline BooleanOp<T, Unit>& BooleanOp<T, Unit>::operator=(const BooleanOp& that) { - scanData_ = that.scanData_; + 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> @@ -214,7 +214,7 @@ namespace boolean_op { template <class T, typename Unit> template <class cT> - inline void BooleanOp<T, Unit>::evaluateInterval_(cT& outputContainer, interval_data<Unit> ivl, + 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; @@ -225,13 +225,13 @@ namespace boolean_op { } template <class T> - inline BinaryCount<T>& BinaryCount<T>::operator=(const BinaryCount<T>& that) { + 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 { + inline bool BinaryCount<T>::operator==(const BinaryCount<T>& that) const { return counts_[0] == that.counts_[0] && counts_[1] == that.counts_[1]; } @@ -290,7 +290,7 @@ namespace boolean_op { count[0] += (*itr1).second.second; } if(itr2 != itr2_end) { - if((*itr2).first < prevCoord || + if((*itr2).first < prevCoord || ((*itr2).first == prevCoord && (*itr2).second.first < prevPosition)) { prevCoord = (*itr2).first; prevPosition = (*itr2).second.first; @@ -307,7 +307,7 @@ namespace boolean_op { } else { if(itr1 != itr1_end) ++itr1; } - + while(itr1 != itr1_end || itr2 != itr2_end) { Unit curCoord = UnitMax; Unit curPosition = UnitMax; @@ -318,7 +318,7 @@ namespace boolean_op { curCount[0] += (*itr1).second.second; } if(itr2 != itr2_end) { - if((*itr2).first < curCoord || + if((*itr2).first < curCoord || ((*itr2).first == curCoord && (*itr2).second.first < curPosition)) { curCoord = (*itr2).first; curPosition = (*itr2).second.first; @@ -349,15 +349,15 @@ namespace boolean_op { 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 && + 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(), + 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(), + output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevCoord, std::pair<Unit, int>(element.first.high(), element.second * -1))); } } @@ -379,11 +379,11 @@ namespace boolean_op { } inputOutput.insert(inputOutput.end(), output.begin(), output.end()); } - + template <typename Unit> inline void applyUnaryXOr(std::vector<std::pair<Unit, std::pair<Unit, int> > >& input) { BooleanOp<UnaryCount, Unit> booleanXOr; - + } template <typename count_type = int> @@ -416,15 +416,15 @@ namespace boolean_op { 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 && + 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(), + 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(), + output.push_back(std::pair<Unit, std::pair<Unit, int> >(prevPos, std::pair<Unit, int>(element.first.high(), element.second * -1))); } } @@ -435,7 +435,7 @@ namespace boolean_op { input = std::vector<std::pair<Unit, std::pair<Unit, int> > >(); } else { input.clear(); - } + } input.insert(input.end(), output.begin(), output.end()); } }; diff --git a/boost/polygon/detail/boolean_op_45.hpp b/boost/polygon/detail/boolean_op_45.hpp index b4a82d8633..b2130ce857 100644 --- a/boost/polygon/detail/boolean_op_45.hpp +++ b/boost/polygon/detail/boolean_op_45.hpp @@ -1,6 +1,6 @@ /* 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). @@ -16,20 +16,20 @@ namespace boost { namespace polygon{ class Count2 { public: - inline Count2() -#ifndef BOOST_POLYGON_MSVC - : counts() + 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() + 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() + 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]; } @@ -108,7 +108,7 @@ namespace boost { namespace polygon{ 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; + x = that.x; y = that.y; rise = that.rise; count = that.count; return *this; } inline Unit evalAtX(Unit xIn) const { @@ -142,7 +142,7 @@ namespace boost { namespace polygon{ return true; } }; - + typedef Scan45ElementT<Count2> Scan45Element; // inline std::ostream& operator<< (std::ostream& o, const Scan45Element& c) { @@ -168,7 +168,7 @@ namespace boost { namespace polygon{ 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, + inline bool operator () (const Scan45ElementT<CountType>& elm1, const Scan45ElementT<CountType>& elm2) const { Unit y1 = elm1.evalAtX(*x_); Unit y2 = elm2.evalAtX(*x_); @@ -190,42 +190,42 @@ namespace boost { namespace polygon{ 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; + 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; + counts[3] = count4; } - inline Scan45CountT(const Scan45CountT& count) : counts() { + inline Scan45CountT(const Scan45CountT& count) : counts() { (*this) = count; } - inline bool operator==(const Scan45CountT& count) const { + inline bool operator==(const Scan45CountT& count) const { for(unsigned int i = 0; i < 4; ++i) { - if(counts[i] != count.counts[i]) return false; + 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) { + 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]; + counts[i] = count.counts[i]; } - return *this; + 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]; + 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]; + counts[i] -= count.counts[i]; } return *this; } @@ -270,7 +270,7 @@ namespace boost { namespace polygon{ 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){ + inline Vertex45T& operator=(const Vertex45T& vertex){ pt = vertex.pt; rise = vertex.rise; count = vertex.count; return *this; } inline Vertex45T(const std::pair<Point, Point>& vertex) : pt(), rise(), count() {} inline Vertex45T& operator=(const std::pair<Point, Point>& vertex){ return *this; } @@ -307,13 +307,13 @@ namespace boost { namespace polygon{ 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_); @@ -370,6 +370,7 @@ namespace boost { namespace polygon{ 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 @@ -383,21 +384,21 @@ namespace boost { namespace polygon{ } else return false; #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#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, + 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 << std::endl; + //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) << std::endl; + //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n"; } } }; @@ -405,6 +406,7 @@ namespace boost { namespace polygon{ 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 @@ -416,21 +418,21 @@ namespace boost { namespace polygon{ } else return false; #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#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, + 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 << std::endl; + //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) << std::endl; + //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n"; } } }; @@ -445,7 +447,7 @@ namespace boost { namespace polygon{ }; template <typename S45V> static inline void sortScan45Vector(S45V& vec) { - gtlsort(vec.begin(), vec.end(), lessScan45Vertex()); + polygon_sort(vec.begin(), vec.end(), lessScan45Vertex()); } template <typename CountType, typename output_functor> @@ -453,12 +455,12 @@ namespace boost { namespace polygon{ 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 std::binary_function<Point, Point, bool> { public: inline lessScan45Point() {} //default constructor is only constructor @@ -466,7 +468,7 @@ namespace boost { namespace polygon{ return (v1.x() < v2.x()) || (v1.x() == v2.x() && v1.y() < v2.y()); } }; - + typedef std::vector<Scan45Vertex> Scan45Vector; //definitions @@ -474,7 +476,7 @@ namespace boost { namespace polygon{ typedef typename Scan45Data::iterator iterator; typedef typename Scan45Data::const_iterator const_iterator; typedef std::set<Point, lessScan45Point> CrossQueue; - + //data Scan45Data scanData_; CrossQueue crossQueue_; @@ -482,19 +484,19 @@ namespace boost { namespace polygon{ Unit x_; int justBefore_; public: - inline Scan45() : scanData_(), crossQueue_(), crossVector_(), + 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_(), + 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_; + 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){ @@ -502,7 +504,7 @@ namespace boost { namespace polygon{ } return *this; } - + //cT is an output container of Vertex45 //iT is an iterator over Scan45Vertex elements template <class cT, class iT> @@ -510,18 +512,18 @@ namespace boost { namespace polygon{ //std::cout << "1\n"; while(inputBegin != inputEnd) { //std::cout << "2\n"; - //std::cout << "x_ = " << x_ << std::endl; - //std::cout << "scan line size: " << scanData_.size() << std::endl; + //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_) << std::endl; + // std::cout << *iter << " " << iter->evalAtX(x_) << "\n"; // } - // std::cout << "cross queue size: " << crossQueue_.size() << std::endl; - // std::cout << "cross vector size: " << crossVector_.size() << std::endl; + // 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 << std::endl; + //} std::cout << "\n"; Unit nextX = (*inputBegin).first.x(); if(!crossVector_.empty() && crossVector_[0].first.x() < nextX) nextX = crossVector_[0].first.x(); if(nextX != x_) { @@ -567,18 +569,18 @@ namespace boost { namespace polygon{ //std::cout << "loop\n"; //pop point off the cross queue Point crossPoint = *(crossQueue_.begin()); - //std::cout << crossPoint << std::endl; + //std::cout << crossPoint << "\n"; //for(iterator iter = scanData_.begin(); // iter != scanData_.end(); ++iter) { // std::cout << "scan element\n"; - // std::cout << *iter << " " << iter->evalAtX(x_) << std::endl; + // 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() << std::endl; + //std::cout << "searching at: " << vertex.first.y() << "\n"; //if(lowIter == scanData_.end()) std::cout << "could not find\n"; - //else std::cout << "found: " << *lowIter << std::endl; + //else std::cout << "found: " << *lowIter << "\n"; if(lowIter == scanData_.end() || lowIter->evalAtX(x_) != vertex.first.y()) { // std::cout << "skipping\n"; @@ -593,7 +595,7 @@ namespace boost { namespace polygon{ --searchDownItr; countBelow = searchDownItr->count; } - //std::cout << "Below Count: " << countBelow << std::endl; + //std::cout << "Below Count: " << countBelow << "\n"; Scan45Count count(countBelow); std::size_t numEdges = 0; iterator eraseItrs[3]; @@ -601,7 +603,7 @@ namespace boost { namespace polygon{ lowIter->evalAtX(x_) == vertex.first.y()) { for(int index = lowIter->rise +1; index >= 0; --index) count[index] = lowIter->count; - //std::cout << count << std::endl; + //std::cout << count << "\n"; eraseItrs[numEdges] = lowIter; ++numEdges; ++lowIter; @@ -623,15 +625,15 @@ namespace boost { namespace polygon{ 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 << std::endl; - //std::cout << vertex << std::endl; + //std::cout << count << "\n"; + //std::cout << vertex << "\n"; crossVector_.push_back(vertex); } //erase crossing elements @@ -650,7 +652,7 @@ namespace boost { namespace polygon{ findCross_(searchVec[i]); } } - + template <class iT> inline iT mergeCross_(iT inputBegin, iT inputEnd) { Scan45Vector vec; @@ -677,7 +679,7 @@ namespace boost { namespace polygon{ } return inputBegin; } - + template <class cT, class iT> inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) { //std::cout << "processEvent_\n"; @@ -686,36 +688,36 @@ namespace boost { namespace polygon{ iterator prevIter = scanData_.end(); while(inputBegin != inputEnd && (*inputBegin).first.x() == x_) { - //std::cout << (*inputBegin) << std::endl; + //std::cout << (*inputBegin) << "\n"; //std::cout << "loop\n"; Scan45Vertex vertex = *inputBegin; - //std::cout << vertex.first << std::endl; + //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; + } else { + ++inputBegin; //std::cout << "after increment\n"; //accumulate overlapping changes in Scan45Count while(inputBegin != inputEnd && - (*inputBegin).first.x() == x_ && + (*inputBegin).first.x() == x_ && (*inputBegin).first.y() == vertex.first.y()) { //std::cout << "accumulate\n"; vertex.second += (*inputBegin).second; ++inputBegin; } } - //std::cout << vertex.second << std::endl; + //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 << std::endl; + //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()); @@ -725,8 +727,8 @@ namespace boost { namespace polygon{ countBelow = lowIter->count; ++lowIter; } - //std::cout << "Count Below: " << countBelow[0] << " " << countBelow[1] << std::endl; - //std::cout << "vertical count: " << verticalCount[0] << " " << verticalCount[1] << std::endl; + //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()) { @@ -756,23 +758,23 @@ namespace boost { namespace polygon{ } verticalCount += vertex.second[3]; prevPoint = vertex.first; - //std::cout << "new vertical count: " << verticalCount[0] << " " << verticalCount[1] << std::endl; + //std::cout << "new vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n"; prevIter = lowIter; //count represents the current state at this point - //std::cout << vertex.second << std::endl; - //std::cout << countAt << std::endl; + //std::cout << vertex.second << "\n"; + //std::cout << countAt << "\n"; //std::cout << "ADD\n"; vertex.second += countAt; - //std::cout << vertex.second << std::endl; - + //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] << std::endl; - iterator insertIter = scanData_.insert(scanData_.end(), - Scan45ElementT<CountType>(vertex.first.x(), - vertex.first.y(), + // " " << 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; @@ -784,7 +786,7 @@ namespace boost { namespace polygon{ //std::cout << "end processEvent\n"; return inputBegin; } - + //iter1 is horizontal inline void scheduleCross0_(iterator iter1, iterator iter2) { //std::cout << "0, "; @@ -815,7 +817,7 @@ namespace boost { namespace polygon{ 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); + 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))); @@ -823,13 +825,13 @@ namespace boost { namespace polygon{ } } } else { - LongUnit halfDelta = (LongUnit)((((LongUnit)y1) - y2)/2); + 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; @@ -839,7 +841,7 @@ namespace boost { namespace polygon{ if(iter->rise == 0){ if(iteratorBelow->rise == 1) { scheduleCross0_(iter, iteratorBelow); - } + } } else { //iter->rise == -1 if(iteratorBelow->rise == 1) { @@ -863,10 +865,10 @@ namespace boost { namespace polygon{ scheduleCross0_(iteratorAbove, iter); } } - } - //std::cout << std::endl; - } - + } + //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_)); @@ -874,11 +876,11 @@ namespace boost { namespace polygon{ }; //template <typename CountType> - //static inline void print45Data(const std::set<Scan45ElementT<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 << std::endl; + // std::cout << iter->x << " " << iter->y << " " << iter->rise << "\n"; // } //} @@ -920,7 +922,7 @@ namespace boost { namespace polygon{ stdcout << "done testing Scan45Data\n"; return true; } - + template <typename stream_type> static inline bool testScan45Rect(stream_type& stdcout) { stdcout << "testing Scan45Rect\n"; @@ -957,13 +959,13 @@ namespace boost { namespace polygon{ 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() << std::endl; + stdcout << "result size == " << result.size() << "\n"; for(std::size_t i = 0; i < result.size(); ++i) { - //std::cout << "result == " << result[i]<< std::endl; + //std::cout << "result == " << result[i]<< "\n"; } - stdcout << "reference size == " << reference.size() << std::endl; + stdcout << "reference size == " << reference.size() << "\n"; for(std::size_t i = 0; i < reference.size(); ++i) { - //std::cout << "reference == " << reference[i]<< std::endl; + //std::cout << "reference == " << reference[i]<< "\n"; } return false; } @@ -1007,13 +1009,13 @@ namespace boost { namespace polygon{ 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() << std::endl; + stdcout << "result size == " << result.size() << "\n"; for(std::size_t i = 0; i < result.size(); ++i) { - //std::cout << "result == " << result[i]<< std::endl; + //std::cout << "result == " << result[i]<< "\n"; } - stdcout << "reference size == " << reference.size() << std::endl; + stdcout << "reference size == " << reference.size() << "\n"; for(std::size_t i = 0; i < reference.size(); ++i) { - //std::cout << "reference == " << reference[i]<< std::endl; + //std::cout << "reference == " << reference[i]<< "\n"; } return false; } @@ -1057,13 +1059,13 @@ namespace boost { namespace polygon{ 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() << std::endl; + stdcout << "result size == " << result.size() << "\n"; for(std::size_t i = 0; i < result.size(); ++i) { - //stdcout << "result == " << result[i]<< std::endl; + //stdcout << "result == " << result[i]<< "\n"; } - stdcout << "reference size == " << reference.size() << std::endl; + stdcout << "reference size == " << reference.size() << "\n"; for(std::size_t i = 0; i < reference.size(); ++i) { - //stdcout << "reference == " << reference[i]<< std::endl; + //stdcout << "reference == " << reference[i]<< "\n"; } return false; } @@ -1114,13 +1116,13 @@ namespace boost { namespace polygon{ 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() << std::endl; + stdcout << "result size == " << result.size() << "\n"; for(std::size_t i = 0; i < result.size(); ++i) { - //stdcout << "result == " << result[i]<< std::endl; + //stdcout << "result == " << result[i]<< "\n"; } - stdcout << "reference size == " << reference.size() << std::endl; + stdcout << "reference size == " << reference.size() << "\n"; for(std::size_t i = 0; i < reference.size(); ++i) { - //stdcout << "reference == " << reference[i]<< std::endl; + //stdcout << "reference == " << reference[i]<< "\n"; } return false; } @@ -1176,8 +1178,8 @@ namespace boost { namespace polygon{ // result == 12 8 1 -1 // result == 12 8 -1 1 if(result.size() != 24) { - //stdcout << "result size == " << result.size() << std::endl; - //stdcout << "reference size == " << 24 << std::endl; + //stdcout << "result size == " << result.size() << "\n"; + //stdcout << "reference size == " << 24 << "\n"; return false; } stdcout << "done testing Scan45Star1\n"; @@ -1232,8 +1234,8 @@ namespace boost { namespace polygon{ // result == 16 8 1 -1 // result == 16 8 0 1 if(result.size() != 24) { - //std::cout << "result size == " << result.size() << std::endl; - //std::cout << "reference size == " << 24 << std::endl; + //std::cout << "result size == " << result.size() << "\n"; + //std::cout << "reference size == " << 24 << "\n"; return false; } stdcout << "done testing Scan45Star2\n"; @@ -1297,8 +1299,8 @@ namespace boost { namespace polygon{ // result == 12 14 2 1 // result == 12 14 0 1 if(result.size() != 28) { - //std::cout << "result size == " << result.size() << std::endl; - //std::cout << "reference size == " << 28 << std::endl; + //std::cout << "result size == " << result.size() << "\n"; + //std::cout << "reference size == " << 28 << "\n"; return false; } @@ -1306,7 +1308,7 @@ namespace boost { namespace polygon{ return true; } - + template <typename stream_type> static inline bool testScan45Star4(stream_type& stdcout) { stdcout << "testing Scan45Star4\n"; @@ -1364,8 +1366,8 @@ namespace boost { namespace polygon{ // result == 16 12 2 1 // result == 16 12 0 1 if(result.size() != 28) { - //stdcout << "result size == " << result.size() << std::endl; - //stdcout << "reference size == " << 28 << std::endl; + //stdcout << "result size == " << result.size() << "\n"; + //stdcout << "reference size == " << 28 << "\n"; return false; } diff --git a/boost/polygon/detail/iterator_compact_to_points.hpp b/boost/polygon/detail/iterator_compact_to_points.hpp index 9634e6f75e..bed03d3f74 100644 --- a/boost/polygon/detail/iterator_compact_to_points.hpp +++ b/boost/polygon/detail/iterator_compact_to_points.hpp @@ -1,6 +1,6 @@ /* 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). @@ -24,7 +24,7 @@ public: 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) : + 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_; @@ -66,4 +66,3 @@ public: } } #endif - diff --git a/boost/polygon/detail/iterator_geometry_to_set.hpp b/boost/polygon/detail/iterator_geometry_to_set.hpp index 4f6287309a..95840e2001 100644 --- a/boost/polygon/detail/iterator_geometry_to_set.hpp +++ b/boost/polygon/detail/iterator_geometry_to_set.hpp @@ -1,6 +1,6 @@ /* 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). @@ -28,8 +28,8 @@ private: 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) : + 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; @@ -67,7 +67,7 @@ public: vertex_.second.second = 1; if(is_hole_) vertex_.second.second *= -1; } - return vertex_; + return vertex_; } }; @@ -93,9 +93,9 @@ private: 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(), + 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); @@ -116,7 +116,7 @@ public: evaluate_(); } } - iterator_geometry_to_set(const iterator_geometry_to_set& that) : + 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_; @@ -176,7 +176,7 @@ public: return !(*this == that); } inline reference operator*() const { - return vertex_; + return vertex_; } inline void evaluate_() { @@ -185,7 +185,7 @@ public: if(pts[1] == pts[2]) { vertex_.second.second = 0; } else if(pts[0].get(HORIZONTAL) != pts[1].get(HORIZONTAL)) { - vertex_.second.second = -1; + vertex_.second.second = -1; } else if(pts[0].get(VERTICAL) != pts[1].get(VERTICAL)) { vertex_.second.second = 1; } else { @@ -213,8 +213,8 @@ private: 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) : + 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); @@ -228,7 +228,7 @@ public: started_holes = false; } } - iterator_geometry_to_set(const iterator_geometry_to_set& that) : + 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; @@ -247,9 +247,9 @@ public: if(itrb == itre) { if(itrhib == itrhie) { if(itrhb != itrhe) { - itrhib = iterator_geometry_to_set<polygon_90_concept, + 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, + 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 { @@ -258,21 +258,21 @@ public: //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, + //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, + 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, + 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, + //itrhib = itrhie = iterator_geometry_to_set<polygon_90_concept, // typename polygon_with_holes_traits<polygon_with_holes_type>::hole_type>(); } } @@ -281,9 +281,9 @@ public: ++itrb; if(itrb == itre) { if(itrhb != itrhe) { - itrhib = iterator_geometry_to_set<polygon_90_concept, + 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, + 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; } @@ -312,4 +312,3 @@ public: } } #endif - diff --git a/boost/polygon/detail/max_cover.hpp b/boost/polygon/detail/max_cover.hpp index 343e29a795..e61725c4d4 100644 --- a/boost/polygon/detail/max_cover.hpp +++ b/boost/polygon/detail/max_cover.hpp @@ -1,6 +1,6 @@ /* 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). @@ -35,7 +35,7 @@ namespace boost { namespace polygon{ }; typedef std::pair<std::pair<Unit, Interval>, Node* > EdgeAssociation; - + class lessEdgeAssociation : public std::binary_function<const EdgeAssociation&, const EdgeAssociation&, bool> { public: inline lessEdgeAssociation() {} @@ -83,7 +83,7 @@ namespace boost { namespace polygon{ }; template <class cT> - static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient, + static inline void getMaxCover(cT& outputContainer, Node* node, orientation_2d orient, Rectangle rect) { //std::cout << "New Root\n"; std::vector<stack_element> stack; @@ -170,7 +170,7 @@ namespace boost { namespace polygon{ 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, + 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); @@ -205,7 +205,7 @@ namespace boost { namespace polygon{ template <class iT> static inline void computeDag(iT beginNode, iT endNode, orientation_2d orient, std::size_t size) { - std::vector<EdgeAssociation> leadingEdges; + std::vector<EdgeAssociation> leadingEdges; leadingEdges.reserve(size); for(iT iter = beginNode; iter != endNode; ++iter) { Node* nodep = &(*iter); @@ -213,7 +213,7 @@ namespace boost { namespace polygon{ Interval rectIvl = nodep->rect.get(orient); leadingEdges.push_back(EdgeAssociation(std::pair<Unit, Interval>(leading, rectIvl), nodep)); } - gtlsort(leadingEdges.begin(), leadingEdges.end(), lessEdgeAssociation()); + polygon_sort(leadingEdges.begin(), leadingEdges.end(), lessEdgeAssociation()); typename std::vector<EdgeAssociation>::iterator leadingBegin = leadingEdges.begin(); iT trailingBegin = beginNode; while(leadingBegin != leadingEdges.end()) { diff --git a/boost/polygon/detail/minkowski.hpp b/boost/polygon/detail/minkowski.hpp index 312d9a284d..ce349472c6 100644 --- a/boost/polygon/detail/minkowski.hpp +++ b/boost/polygon/detail/minkowski.hpp @@ -1,4 +1,10 @@ +/* + 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> @@ -62,11 +68,11 @@ struct minkowski_offset { 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]), + 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), + 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) { @@ -100,9 +106,9 @@ struct minkowski_offset { ::boost::polygon::bloat(rect, 10); (*this) = rect - (*this); //invert } - //make_arc(std::vector<point_data< T> >& return_points, + //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) + //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), diff --git a/boost/polygon/detail/polygon_45_formation.hpp b/boost/polygon/detail/polygon_45_formation.hpp index e814a1584f..2e16570137 100644 --- a/boost/polygon/detail/polygon_45_formation.hpp +++ b/boost/polygon/detail/polygon_45_formation.hpp @@ -1,6 +1,6 @@ /* 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). @@ -30,7 +30,7 @@ namespace boost { namespace polygon{ 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; @@ -52,7 +52,7 @@ namespace boost { namespace polygon{ // 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; @@ -68,31 +68,31 @@ namespace boost { namespace polygon{ inline std::size_t size() const { return points.size(); } //public data member - std::list<Point> points; + std::list<Point> points; }; class ActiveTail45 { private: //data - PolyLine45* tailp_; + 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) { @@ -110,7 +110,7 @@ namespace boost { namespace polygon{ tailp_->points.push_back(point); head_ = head; otherTailp_ = otherTailp; - + } inline ActiveTail45(ActiveTail45* otherTailp) : tailp_(0), otherTailp_(0), holesList_(), head_(0) { @@ -155,7 +155,7 @@ namespace boost { namespace polygon{ * @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 */ @@ -298,7 +298,7 @@ namespace boost { namespace polygon{ */ template <class cT> - static inline ActiveTail45* joinChains(Point point, ActiveTail45* at1, ActiveTail45* at2, bool solid, + 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"; @@ -311,7 +311,7 @@ namespace boost { namespace polygon{ at1->copyHoles(*(at1->otherTailp_)); //std::cout << "test2\n"; //Polygon45WithHolesImpl<PolyLine45PolygonData> poly(polyData); - //std::cout << poly << std::endl; + //std::cout << poly << "\n"; //std::cout << "test3\n"; typedef typename cT::value_type pType; output.push_back(pType()); @@ -319,14 +319,14 @@ namespace boost { namespace polygon{ typename PolyLineByConcept<Unit, cType>::type polyData(at1); assign(output.back(), polyData); //std::cout << "test4\n"; - //std::cout << "delete " << at1->otherTailp_ << std::endl; + //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 << std::endl; + //std::cout << "delete " << at1 << "\n"; delete at1; //std::cout << "test6\n"; return 0; @@ -345,7 +345,7 @@ namespace boost { namespace polygon{ inline void destroyContents() { if(otherTailp_) { - //std::cout << "delete p " << tailp_ << std::endl; + //std::cout << "delete p " << tailp_ << "\n"; if(tailp_) delete tailp_; tailp_ = 0; otherTailp_->otherTailp_ = 0; @@ -353,7 +353,7 @@ namespace boost { namespace polygon{ otherTailp_ = 0; } for(typename std::list<ActiveTail45*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) { - //std::cout << "delete p " << (*itr) << std::endl; + //std::cout << "delete p " << (*itr) << "\n"; if(*itr) { if((*itr)->otherTailp_) { delete (*itr)->otherTailp_; @@ -367,10 +367,10 @@ namespace boost { namespace polygon{ } // inline void print() { -// std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << std::endl; +// std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n"; // } - static inline std::pair<ActiveTail45*, ActiveTail45*> createActiveTail45sAsPair(Point point, bool solid, + static inline std::pair<ActiveTail45*, ActiveTail45*> createActiveTail45sAsPair(Point point, bool solid, ActiveTail45* phole, bool fractureHoles) { ActiveTail45* at1 = 0; ActiveTail45* at2 = 0; @@ -386,7 +386,7 @@ namespace boost { namespace polygon{ at2 = new ActiveTail45(at1); at1->otherTailp_ = at2; at2->head_ = !solid; - if(phole) + if(phole) at2->addHole(phole); //assert fractureHoles == false } return std::pair<ActiveTail45*, ActiveTail45*>(at1, at2); @@ -398,64 +398,64 @@ namespace boost { namespace polygon{ class Vertex45CountT { public: typedef ct count_type; - inline Vertex45CountT() -#ifndef BOOST_POLYGON_MSVC - : counts() + 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, + 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; +#ifndef BOOST_POLYGON_MSVC + : counts() +#endif + { + counts[0] = count1; + counts[1] = count2; counts[2] = count3; - counts[3] = count4; + counts[3] = count4; } inline Vertex45CountT(const Vertex45& vertex) -#ifndef BOOST_POLYGON_MSVC - : counts() -#endif - { +#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 - { +#ifndef BOOST_POLYGON_MSVC + : counts() +#endif + { (*this) = count; } - inline bool operator==(const Vertex45CountT& count) const { + inline bool operator==(const Vertex45CountT& count) const { for(unsigned int i = 0; i < 4; ++i) { - if(counts[i] != count.counts[i]) return false; + 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) { + 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]; + counts[i] = count.counts[i]; } - return *this; + 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]; + 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]; + counts[i] -= count.counts[i]; } return *this; } @@ -501,7 +501,7 @@ namespace boost { namespace polygon{ count[vertex.rise+1] = vertex.count; } inline Vertex45CompactT(const Vertex45CompactT& vertex) : pt(vertex.pt), count(vertex.count) {} - inline Vertex45CompactT& operator=(const Vertex45CompactT& vertex){ + 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; } @@ -536,12 +536,12 @@ namespace boost { namespace polygon{ 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_; + int fractureHoles_; public: inline Polygon45Formation() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { lessVertex45 lessElm(&x_, &justBefore_); @@ -564,7 +564,7 @@ namespace boost { namespace polygon{ } 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 @@ -575,9 +575,9 @@ namespace boost { namespace polygon{ while(inputBegin != inputEnd) { //std::cout << "2\n"; x_ = (*inputBegin).pt.x(); - //std::cout << "SCAN FORMATION " << x_ << std::endl; - //std::cout << "x_ = " << x_ << std::endl; - //std::cout << "scan line size: " << scanData_.size() << std::endl; + //std::cout << "SCAN FORMATION " << x_ << "\n"; + //std::cout << "x_ = " << x_ << "\n"; + //std::cout << "scan line size: " << scanData_.size() << "\n"; inputBegin = processEvent_(output, inputBegin, inputEnd); } } @@ -585,9 +585,9 @@ namespace boost { namespace polygon{ 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 << std::endl; + 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] << " "; @@ -600,16 +600,16 @@ namespace boost { namespace polygon{ ActiveTail45* returnValue = 0; int returnCount = 0; for(int i = 0; i < 3; ++i) { - //std::cout << i << std::endl; + //std::cout << i << "\n"; if(counts[i] == -1) { //std::cout << "fixed i\n"; for(int j = i + 1; j < 4; ++j) { - //std::cout << j << std::endl; + //std::cout << j << "\n"; if(counts[j]) { if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << std::endl; + //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); + ActiveTail45::joinChains(point, tails[i], tails[j], true, output); counts[i] = 0; counts[j] = 0; tails[i] = 0; @@ -623,16 +623,16 @@ namespace boost { namespace polygon{ //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 << std::endl; + //std::cout << i << "\n"; if(incoming[i] == 1) { //std::cout << "fixed i\n"; for(int j = i + 1; j < 4; ++j) { - //std::cout << j << std::endl; + //std::cout << j << "\n"; if(incoming[j]) { if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << std::endl; + //std::cout << "case2: " << i << " " << j << "\n"; //std::cout << "creating active tail pair\n"; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = + std::pair<ActiveTail45*, ActiveTail45*> tailPair = ActiveTail45::createActiveTail45sAsPair(point, true, 0, fractureHoles_ != 0); //tailPair.first->print(); //tailPair.second->print(); @@ -642,10 +642,10 @@ namespace boost { namespace polygon{ returnCount = 1; } else { Vertex45 vertex(point, i -1, incoming[i]); - //std::cout << "new element " << j-1 << " " << -1 << std::endl; + //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 << std::endl; + //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; @@ -662,14 +662,14 @@ namespace boost { namespace polygon{ //find pass through with solid on top //std::cout << "checking case 3\n"; for(int i = 0; i < 4; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << "case3: " << i << " " << j << "\n"; //tails[i]->print(); //pass through solid on top tails[i]->pushPoint(point); @@ -699,14 +699,14 @@ namespace boost { namespace polygon{ for(int j = 0; j < 4; ++j) { if(incoming[j] != 0) { if(incoming[j] == -1) { - //std::cout << "case4: " << i << " " << j << std::endl; + //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] << std::endl; + //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; @@ -728,7 +728,7 @@ namespace boost { namespace polygon{ if(counts[i] != 0) { for(int j = i+1; j < 4; ++j) { if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << std::endl; + //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; @@ -740,26 +740,26 @@ namespace boost { namespace polygon{ } 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 << std::endl; + //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 = + 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] << std::endl; + //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] << std::endl; + //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; @@ -798,7 +798,7 @@ namespace boost { namespace polygon{ //std::cout << "loop2\n"; elementIters.push_back(iter); int index = iter->first.rise + 1; - //std::cout << index << " " << iter->first.count << std::endl; + //std::cout << index << " " << iter->first.count << "\n"; counts[index] = iter->first.count; tails[index] = iter->second; ++iter; @@ -834,12 +834,12 @@ namespace boost { namespace polygon{ verticalCount = result.first; verticalTail = result.second; //if(verticalTail) std::cout << "have vertical tail\n"; - //std::cout << "verticalCount: " << verticalCount << std::endl; + //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 || + if(currentIter == inputEnd || currentIter->pt.x() != x_ || currentIter->pt.y() >= iter->first.evalAtX(x_)) { //std::cout << "handle hole here\n"; @@ -882,12 +882,12 @@ namespace boost { namespace polygon{ //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> @@ -904,11 +904,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -928,14 +928,14 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } //polygon45set class @@ -952,15 +952,15 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + 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() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } //polygon45set class @@ -1018,14 +1018,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(12, 8), 1, -1)); // result == 12 8 -1 1 data.push_back(Vertex45(Point(12, 8), -1, 1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } template <typename stream_type> @@ -1050,15 +1050,15 @@ namespace boost { namespace polygon{ sortScan45Vector(vertices); stdcout << "scanning\n"; scan45.scan(result, vertices.begin(), vertices.end()); - - gtlsort(result.begin(), result.end()); + + polygon_sort(result.begin(), result.end()); pf.scan(polys, result.begin(), result.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } template <typename stream_type> @@ -1123,14 +1123,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(8, 6), -1, -1)); data.push_back(Vertex45(Point(8, 6), 1, 1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } template <typename stream_type> @@ -1195,14 +1195,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(10, 8), -1, -1)); data.push_back(Vertex45(Point(10, 8), 1, 1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } template <typename stream_type> @@ -1211,7 +1211,7 @@ namespace boost { namespace polygon{ 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)); @@ -1239,14 +1239,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(10, 22), 2, -1)); data.push_back(Vertex45(Point(10, 22), 0, -1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; - return true; + return true; } @@ -1256,7 +1256,7 @@ namespace boost { namespace polygon{ typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData; typedef typename Polygon45FormationData::iterator iterator; typedef typename Polygon45FormationData::const_iterator const_iterator; - + //data Polygon45FormationData scanData_; Unit x_; @@ -1266,7 +1266,7 @@ namespace boost { namespace polygon{ lessVertex45 lessElm(&x_, &justBefore_); scanData_ = Polygon45FormationData(lessElm); } - inline Polygon45Tiling(const Polygon45Tiling& that) : + 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_; @@ -1278,7 +1278,7 @@ namespace boost { namespace polygon{ } 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 @@ -1289,22 +1289,22 @@ namespace boost { namespace polygon{ while(inputBegin != inputEnd) { //std::cout << "2\n"; x_ = (*inputBegin).pt.x(); - //std::cout << "SCAN FORMATION " << x_ << std::endl; - //std::cout << "x_ = " << x_ << std::endl; - //std::cout << "scan line size: " << scanData_.size() << std::endl; + //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, + + 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 = + std::pair<ActiveTail45*, ActiveTail45*> tailPair = ActiveTail45::createActiveTail45sAsPair(prevPoint, true, 0, false); verticalPair.first = iterTail; verticalPair.second = tailPair.first; @@ -1312,11 +1312,11 @@ namespace boost { namespace polygon{ } 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 << std::endl; + 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] << " "; @@ -1332,16 +1332,16 @@ namespace boost { namespace polygon{ verticalPairOut.second = 0; int returnCount = 0; for(int i = 0; i < 3; ++i) { - //std::cout << i << std::endl; + //std::cout << i << "\n"; if(counts[i] == -1) { //std::cout << "fixed i\n"; for(int j = i + 1; j < 4; ++j) { - //std::cout << j << std::endl; + //std::cout << j << "\n"; if(counts[j]) { if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << std::endl; + //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); + ActiveTail45::joinChains(point, tails[i], tails[j], true, output); counts[i] = 0; counts[j] = 0; tails[i] = 0; @@ -1355,16 +1355,16 @@ namespace boost { namespace polygon{ //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 << std::endl; + //std::cout << i << "\n"; if(incoming[i] == 1) { //std::cout << "fixed i\n"; for(int j = i + 1; j < 4; ++j) { - //std::cout << j << std::endl; + //std::cout << j << "\n"; if(incoming[j]) { if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << std::endl; + //std::cout << "case2: " << i << " " << j << "\n"; //std::cout << "creating active tail pair\n"; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = + std::pair<ActiveTail45*, ActiveTail45*> tailPair = ActiveTail45::createActiveTail45sAsPair(point, true, 0, false); //tailPair.first->print(); //tailPair.second->print(); @@ -1374,10 +1374,10 @@ namespace boost { namespace polygon{ returnCount = 1; } else { Vertex45 vertex(point, i -1, incoming[i]); - //std::cout << "new element " << j-1 << " " << -1 << std::endl; + //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 << std::endl; + //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; @@ -1394,14 +1394,14 @@ namespace boost { namespace polygon{ //find pass through with solid on top //std::cout << "checking case 3\n"; for(int i = 0; i < 4; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << "case3: " << i << " " << j << "\n"; //tails[i]->print(); //pass through solid on top if(i != 3) @@ -1412,10 +1412,10 @@ namespace boost { namespace polygon{ returnCount = -1; } else { verticalPairOut.first = tails[i]; - std::pair<ActiveTail45*, ActiveTail45*> tailPair = + 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]), + elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.second)); } tails[i] = 0; @@ -1437,10 +1437,10 @@ namespace boost { namespace polygon{ for(int j = 0; j < 4; ++j) { if(incoming[j] != 0) { if(incoming[j] == -1) { - //std::cout << "case4: " << i << " " << j << std::endl; + //std::cout << "case4: " << i << " " << j << "\n"; //pass through solid on bottom if(i == 3) { - //std::cout << "new element " << j-1 << " " << incoming[j] << std::endl; + //std::cout << "new element " << j-1 << " " << incoming[j] << "\n"; if(j == 3) { returnValue = tails[i]; returnCount = 1; @@ -1452,16 +1452,16 @@ namespace boost { namespace polygon{ if(verticalPair.first == 0) { getVerticalPair_(verticalPair, previter); } - ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output); + 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); + 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]), + elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), verticalPair.second)); } tails[i] = 0; @@ -1483,7 +1483,7 @@ namespace boost { namespace polygon{ if(counts[i] != 0) { for(int j = i+1; j < 4; ++j) { if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << std::endl; + //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]; @@ -1493,7 +1493,7 @@ namespace boost { namespace polygon{ if(verticalPair.first == 0) { getVerticalPair_(verticalPair, previter); } - ActiveTail45::joinChains(point, tails[j], verticalPair.first, true, output); + ActiveTail45::joinChains(point, tails[j], verticalPair.first, true, output); verticalPairOut.second = verticalPair.second; } tails[i] = 0; @@ -1505,13 +1505,13 @@ namespace boost { namespace polygon{ } 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 << std::endl; + //std::cout << "case6: " << i << " " << j << "\n"; //we are beginning a empty space if(verticalPair.first == 0) { getVerticalPair_(verticalPair, previter); @@ -1521,14 +1521,14 @@ namespace boost { namespace polygon{ returnValue = verticalPair.first; returnCount = -1; } else { - std::pair<ActiveTail45*, ActiveTail45*> tailPair = + std::pair<ActiveTail45*, ActiveTail45*> tailPair = ActiveTail45::createActiveTail45sAsPair(point, true, 0, false); - //std::cout << "new element " << j-1 << " " << incoming[j] << std::endl; + //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] << std::endl; + //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; @@ -1578,7 +1578,7 @@ namespace boost { namespace polygon{ //std::cout << "loop2\n"; elementIters.push_back(iter); int index = iter->first.rise + 1; - //std::cout << index << " " << iter->first.count << std::endl; + //std::cout << index << " " << iter->first.count << "\n"; counts[index] = iter->first.count; tails[index] = iter->second; ++iter; @@ -1646,12 +1646,12 @@ namespace boost { namespace polygon{ //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> @@ -1668,11 +1668,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; return true; @@ -1692,14 +1692,14 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -1715,15 +1715,15 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + 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() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -1742,14 +1742,14 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -1768,14 +1768,14 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -1800,12 +1800,12 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + 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() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; return true; @@ -1835,11 +1835,11 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(2, 2), 2, -1)); data.push_back(Vertex45(Point(2, 2), 0, -1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; return true; @@ -1899,14 +1899,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(12, 8), 1, -1)); // result == 12 8 -1 1 data.push_back(Vertex45(Point(12, 8), -1, 1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -1932,15 +1932,15 @@ namespace boost { namespace polygon{ sortScan45Vector(vertices); stdcout << "scanning\n"; scan45.scan(result, vertices.begin(), vertices.end()); - - gtlsort(result.begin(), result.end()); + + polygon_sort(result.begin(), result.end()); pf.scan(polys, result.begin(), result.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -2005,14 +2005,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(8, 6), -1, -1)); data.push_back(Vertex45(Point(8, 6), 1, 1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -2077,14 +2077,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(10, 8), -1, -1)); data.push_back(Vertex45(Point(10, 8), 1, 1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } template <typename stream_type> @@ -2093,7 +2093,7 @@ namespace boost { namespace polygon{ 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)); @@ -2121,14 +2121,14 @@ namespace boost { namespace polygon{ data.push_back(Vertex45(Point(10, 22), 2, -1)); data.push_back(Vertex45(Point(10, 22), 0, -1)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon tiling\n"; - return true; + return true; } }; @@ -2137,7 +2137,7 @@ namespace boost { namespace polygon{ 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; @@ -2145,7 +2145,7 @@ namespace boost { namespace polygon{ // 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 @@ -2166,7 +2166,7 @@ namespace boost { namespace polygon{ 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; @@ -2187,7 +2187,7 @@ namespace boost { namespace polygon{ 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(const iteratorHoles& that) : itr_(that.itr_) {} inline iteratorHoles& operator=(const iteratorHoles& that) { itr_ = that.itr_; return *this; @@ -2208,8 +2208,8 @@ namespace boost { namespace polygon{ } }; typedef iteratorHoles iterator_holes_type; - - + + inline PolyLine45PolygonData() : p_(0) {} inline PolyLine45PolygonData(ActiveTail45* p) : p_(p) {} //use default copy and assign @@ -2225,7 +2225,7 @@ namespace boost { namespace polygon{ inline PolyLine45PolygonData& set(iT inputBegin, iT inputEnd) { 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> diff --git a/boost/polygon/detail/polygon_45_set_view.hpp b/boost/polygon/detail/polygon_45_set_view.hpp index 34423862b6..a0dc0463bc 100644 --- a/boost/polygon/detail/polygon_45_set_view.hpp +++ b/boost/polygon/detail/polygon_45_set_view.hpp @@ -1,6 +1,6 @@ /* 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). @@ -18,11 +18,11 @@ namespace boost { namespace polygon{ 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 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, + 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); @@ -39,6 +39,7 @@ namespace boost { namespace polygon{ 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) @@ -50,7 +51,7 @@ namespace boost { namespace polygon{ else output_ -= rinput_; #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#pragma warning (pop) #endif } }; @@ -62,6 +63,7 @@ namespace boost { namespace polygon{ 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) @@ -73,7 +75,7 @@ namespace boost { namespace polygon{ else output_ -= rvalue_; #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#pragma warning (pop) #endif } }; @@ -114,12 +116,12 @@ namespace boost { namespace polygon{ 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, + // 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); - // gtlsort(output_.begin(), output_.end()); + // polygon_sort(output_.begin(), output_.end()); // } }; @@ -137,7 +139,7 @@ namespace boost { namespace polygon{ } 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) { + 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> @@ -153,6 +155,7 @@ namespace boost { namespace polygon{ 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) @@ -164,7 +167,7 @@ namespace boost { namespace polygon{ else output_ -= rinput_; #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#pragma warning (pop) #endif polygon_45_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end()); return lvalue_; @@ -194,32 +197,32 @@ namespace boost { namespace polygon{ 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 + 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 + 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 + 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); @@ -231,7 +234,7 @@ namespace boost { namespace polygon{ 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 + 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); @@ -243,30 +246,30 @@ namespace boost { namespace polygon{ 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 + 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 + 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, + 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); @@ -275,8 +278,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -286,8 +289,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -296,8 +299,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -306,9 +309,9 @@ namespace boost { namespace polygon{ 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, + 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); @@ -317,8 +320,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -327,8 +330,8 @@ namespace boost { namespace polygon{ 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, + 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) { @@ -338,8 +341,8 @@ namespace boost { namespace polygon{ 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, + 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) { @@ -349,8 +352,8 @@ namespace boost { namespace polygon{ 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, + 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) { @@ -362,8 +365,8 @@ namespace boost { namespace polygon{ 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, + 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) { @@ -375,4 +378,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/detail/polygon_45_touch.hpp b/boost/polygon/detail/polygon_45_touch.hpp index e50912ac9b..90717e1cca 100644 --- a/boost/polygon/detail/polygon_45_touch.hpp +++ b/boost/polygon/detail/polygon_45_touch.hpp @@ -1,6 +1,6 @@ /* 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). @@ -32,7 +32,7 @@ namespace boost { namespace polygon{ } else { int count = mp[i].second; if(subtract) count -= mp2[j].second; - else count += mp2[j].second; + else count += mp2[j].second; if(count) { newmp.push_back(mp[i]); newmp.back().second = count; @@ -63,8 +63,10 @@ namespace boost { namespace polygon{ 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 = lower_bound(counts.begin(), counts.end(), std::make_pair(index, int(0))); + 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; } @@ -102,8 +104,8 @@ namespace boost { namespace polygon{ 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; + 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) { @@ -124,10 +126,10 @@ namespace boost { namespace polygon{ } y_prop_map.clear(); } - + struct touch_45_output_functor { template <typename cT> - void operator()(cT& output, const CountTouch& count1, const CountTouch& count2, + 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; @@ -138,7 +140,7 @@ namespace boost { namespace polygon{ 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) { @@ -148,16 +150,16 @@ namespace boost { namespace polygon{ } } }; - typedef typename std::pair<Point, + 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) { @@ -185,8 +187,8 @@ namespace boost { namespace polygon{ template <typename graph_type> static void performTouch(graph_type& graph, TouchSetData& tsd) { - - gtlsort(tsd.begin(), tsd.end(), lessVertex45Compact()); + + 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()); @@ -227,10 +229,10 @@ namespace boost { namespace polygon{ } } } - + }; } } -#endif +#endif diff --git a/boost/polygon/detail/polygon_90_set_view.hpp b/boost/polygon/detail/polygon_90_set_view.hpp index 53beec8da1..f6ee36c5b6 100644 --- a/boost/polygon/detail/polygon_90_set_view.hpp +++ b/boost/polygon/detail/polygon_90_set_view.hpp @@ -1,6 +1,6 @@ /* 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). @@ -23,7 +23,7 @@ namespace boost { namespace polygon{ 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 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); @@ -46,7 +46,7 @@ namespace boost { namespace polygon{ 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>()); + rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); } }; @@ -65,23 +65,23 @@ namespace boost { namespace polygon{ lvalue_.sort(); rvalue_.sort(); output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), - rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); + 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>()); + 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>()); + 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>()); + rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); } } }; @@ -98,7 +98,7 @@ namespace boost { namespace polygon{ // << "," << 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>()); + rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); } }; @@ -115,7 +115,7 @@ namespace boost { namespace polygon{ // << "," << orient_.to_int() << std::endl; output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), - rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); + rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); } }; @@ -159,12 +159,12 @@ namespace boost { namespace polygon{ 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, +// 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); -// gtlsort(output_.begin(), output_.end()); +// polygon_sort(output_.begin(), output_.end()); // } void sort() const {} //is always sorted }; @@ -189,22 +189,22 @@ namespace boost { namespace polygon{ // 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, +// 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) { + 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) { + clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { return true; } 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) { + sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { return true; } template <typename value_type, typename arg_type> @@ -216,7 +216,7 @@ namespace boost { namespace polygon{ 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) { @@ -225,22 +225,22 @@ namespace boost { namespace polygon{ 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; @@ -257,7 +257,7 @@ namespace boost { namespace polygon{ // 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_); + 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_ @@ -265,11 +265,11 @@ namespace boost { namespace polygon{ 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>()); + 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 {}; @@ -279,27 +279,27 @@ namespace boost { namespace polygon{ 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, + 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 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, + 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> @@ -308,12 +308,12 @@ namespace boost { namespace polygon{ 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, + 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> @@ -322,8 +322,8 @@ namespace boost { namespace polygon{ 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, + 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()); } @@ -336,12 +336,12 @@ namespace boost { namespace polygon{ 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, + 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> @@ -350,12 +350,12 @@ namespace boost { namespace polygon{ 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, + 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> @@ -366,11 +366,11 @@ namespace boost { namespace polygon{ 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, + 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; @@ -380,8 +380,8 @@ namespace boost { namespace polygon{ //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, + 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); @@ -390,8 +390,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -400,18 +400,18 @@ namespace boost { namespace polygon{ 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, + 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, + 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); @@ -420,8 +420,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -430,8 +430,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -441,7 +441,7 @@ namespace boost { namespace polygon{ 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 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) { @@ -452,7 +452,7 @@ namespace boost { namespace polygon{ 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 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) { @@ -463,7 +463,7 @@ namespace boost { namespace polygon{ 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 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) { @@ -476,7 +476,7 @@ namespace boost { namespace polygon{ 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 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) { @@ -488,4 +488,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/detail/polygon_90_touch.hpp b/boost/polygon/detail/polygon_90_touch.hpp index 7671602404..77a516b777 100644 --- a/boost/polygon/detail/polygon_90_touch.hpp +++ b/boost/polygon/detail/polygon_90_touch.hpp @@ -1,6 +1,6 @@ /* 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). @@ -30,7 +30,7 @@ namespace boost { namespace polygon{ bool incremented_; public: inline iterator() : itr_(), ivlIds_(), incremented_(false) {} - inline iterator(typename EventData::const_iterator itr, + 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); @@ -61,7 +61,7 @@ namespace boost { namespace polygon{ } 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) { @@ -77,7 +77,7 @@ namespace boost { namespace polygon{ ++(*this); return tmpItr; } - inline std::pair<Interval, std::set<int> >& operator*() { + 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)); @@ -98,13 +98,13 @@ namespace boost { namespace polygon{ 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); @@ -121,7 +121,7 @@ namespace boost { namespace polygon{ (*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; @@ -129,9 +129,9 @@ namespace boost { namespace polygon{ eventData_[(*itr).first].insert(itr->second.begin(), itr->second.end()); } } - + //Get the begin iterator over event data - inline iterator begin() const { + inline iterator begin() const { //std::cout << "begin\n"; if(eventData_.empty()) return end(); typename EventData::const_iterator itr = eventData_.begin(); @@ -140,18 +140,18 @@ namespace boost { namespace polygon{ ++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 { + + 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; @@ -166,8 +166,8 @@ namespace boost { namespace polygon{ 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); - + inline TouchOp& operator=(const TouchOp& that); + //moves scanline forward inline void advanceScan() { nextItr_ = scanData_.begin(); } @@ -252,7 +252,7 @@ namespace boost { namespace polygon{ //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; @@ -279,7 +279,7 @@ namespace boost { namespace polygon{ // std::cout << std::endl; // } // } - + private: inline typename ScanData::iterator lookup_(Unit pos){ if(nextItr_ != scanData_.end() && nextItr_->first >= pos) { @@ -294,7 +294,7 @@ namespace boost { namespace polygon{ } template <typename graphT> - inline void evaluateInterval_(graphT& outputContainer, std::set<int>& ids, + 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; diff --git a/boost/polygon/detail/polygon_arbitrary_formation.hpp b/boost/polygon/detail/polygon_arbitrary_formation.hpp index 5adabb8078..6f9eb7394f 100644 --- a/boost/polygon/detail/polygon_arbitrary_formation.hpp +++ b/boost/polygon/detail/polygon_arbitrary_formation.hpp @@ -1,6 +1,6 @@ /* 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). @@ -40,7 +40,7 @@ namespace boost { namespace polygon{ 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, @@ -96,7 +96,7 @@ namespace boost { namespace polygon{ 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 + //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; @@ -173,9 +173,9 @@ namespace boost { namespace polygon{ return false; } - static inline Unit evalAtXforYlazy(Unit xIn, Point pt, Point other_pt) { + static inline Unit evalAtXforYlazy(Unit xIn, Point pt, Point other_pt) { long double - evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx, + 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 @@ -190,16 +190,16 @@ namespace boost { namespace polygon{ 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) { + 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, + 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 @@ -215,18 +215,18 @@ namespace boost { namespace polygon{ 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, + 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) { + 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 @@ -243,7 +243,7 @@ namespace boost { namespace polygon{ 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); @@ -254,7 +254,7 @@ namespace boost { namespace polygon{ 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); } @@ -274,10 +274,10 @@ namespace boost { namespace polygon{ 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_; + 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())) @@ -346,8 +346,8 @@ namespace boost { namespace polygon{ 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_sign < 0) switcher += 1; + if(b_sign < 0) switcher += 2; if(a < b) switcher += 4; switch (switcher) { case 0: //both positive @@ -388,7 +388,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -419,13 +419,13 @@ namespace boost { namespace polygon{ } } //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point - dy2 = (he2.second.get(VERTICAL)) - + dy2 = (he2.second.get(VERTICAL)) - (he2.first.get(VERTICAL)); - dy1 = (he1.second.get(VERTICAL)) - + dy1 = (he1.second.get(VERTICAL)) - (he1.first.get(VERTICAL)); - dx2 = (he2.second.get(HORIZONTAL)) - + dx2 = (he2.second.get(HORIZONTAL)) - (he2.first.get(HORIZONTAL)); - dx1 = (he1.second.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 @@ -436,14 +436,14 @@ namespace boost { namespace polygon{ 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_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 << std::endl; - //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl; + //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) { @@ -460,17 +460,17 @@ namespace boost { namespace polygon{ if(is_horizontal(he2)) y_unit = he2.first.y(); //if(x != exp_x || y != exp_y) - // std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl; + // 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 << std::endl; + //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)(), + 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; @@ -482,11 +482,11 @@ namespace boost { namespace polygon{ return true; } - inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2, + 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); + bool lazy_success = compute_lazy_intersection(intersection, he1, he2, projected); if(!projected) { if(lazy_success) { if(intersects_grid(intersection, he1) && @@ -499,7 +499,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -531,13 +531,13 @@ namespace boost { namespace polygon{ } } //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)) - + dy2 = (high_precision)(he2.second.get(VERTICAL)) - (high_precision)(he2.first.get(VERTICAL)); - dy1 = (high_precision)(he1.second.get(VERTICAL)) - + dy1 = (high_precision)(he1.second.get(VERTICAL)) - (high_precision)(he1.first.get(VERTICAL)); - dx2 = (high_precision)(he2.second.get(HORIZONTAL)) - + dx2 = (high_precision)(he2.second.get(HORIZONTAL)) - (high_precision)(he2.first.get(HORIZONTAL)); - dx1 = (high_precision)(he1.second.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 @@ -548,15 +548,15 @@ namespace boost { namespace polygon{ 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_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 << std::endl; - //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << std::endl; - //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl; + //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) { @@ -573,10 +573,10 @@ namespace boost { namespace polygon{ if(is_horizontal(he2)) y_unit = he2.first.y(); //if(x != exp_x || y != exp_y) - // std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl; + // 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 << std::endl; + //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; @@ -621,13 +621,13 @@ namespace boost { namespace polygon{ } } //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 dy2 = (high_precision)(he2.second.get(VERTICAL)) - (high_precision)(he2.first.get(VERTICAL)); - high_precision dy1 = (high_precision)(he1.second.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 dx2 = (high_precision)(he2.second.get(HORIZONTAL)) - (high_precision)(he2.first.get(HORIZONTAL)); - high_precision dx1 = (high_precision)(he1.second.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 @@ -638,14 +638,14 @@ namespace boost { namespace polygon{ 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_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 << std::endl; - //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << std::endl; + //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); @@ -658,10 +658,10 @@ namespace boost { namespace polygon{ if(is_horizontal(he2)) y_unit = he2.first.y(); //if(x != exp_x || y != exp_y) - // std::cout << exp_x << " " << exp_y << " " << x << " " << y << std::endl; + // 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 << std::endl; + //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; @@ -708,14 +708,14 @@ namespace boost { namespace polygon{ } } int oab1 = on_above_or_below(he1.first, he2); - if(oab1 == 0 && between(he1.first, he2.first, he2.second)) return true; + 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(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; + 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(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 } @@ -737,7 +737,7 @@ namespace boost { namespace polygon{ 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){ + inline vertex_half_edge& operator=(const vertex_half_edge& vertex){ pt = vertex.pt; other_pt = vertex.other_pt; count = vertex.count; return *this; } inline vertex_half_edge(const std::pair<Point, Point>& vertex) : pt(), other_pt(), count() {} inline vertex_half_edge& operator=(const std::pair<Point, Point>& vertex){ return *this; } @@ -846,7 +846,7 @@ namespace boost { namespace polygon{ 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; @@ -868,7 +868,7 @@ namespace boost { namespace polygon{ // 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; @@ -884,31 +884,31 @@ namespace boost { namespace polygon{ inline std::size_t size() const { return points.size(); } //public data member - std::list<Point> points; + std::list<Point> points; }; class active_tail_arbitrary { protected: //data - poly_line_arbitrary* tailp_; + 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; @@ -925,7 +925,7 @@ namespace boost { namespace polygon{ tailp_->points.push_back(point); head_ = head; otherTailp_ = otherTailp; - + } inline active_tail_arbitrary(active_tail_arbitrary* otherTailp) : tailp_(), otherTailp_(), holesList_(), head_() { @@ -970,7 +970,7 @@ namespace boost { namespace polygon{ * @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 */ @@ -1107,7 +1107,7 @@ namespace boost { namespace polygon{ * 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, + 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"; @@ -1121,21 +1121,20 @@ namespace boost { namespace polygon{ 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 << std::endl; + //std::cout << poly << "\n"; //std::cout << "test3\n"; typedef typename cT::value_type result_type; - typedef typename geometry_concept<result_type>::type result_concept; output.push_back(result_type()); assign(output.back(), polyData); //std::cout << "test4\n"; - //std::cout << "delete " << at1->otherTailp_ << std::endl; + //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 << std::endl; + //std::cout << "delete " << at1 << "\n"; delete at1; //std::cout << "test6\n"; return 0; @@ -1154,7 +1153,7 @@ namespace boost { namespace polygon{ inline void destroyContents() { if(otherTailp_) { - //std::cout << "delete p " << tailp_ << std::endl; + //std::cout << "delete p " << tailp_ << "\n"; if(tailp_) delete tailp_; tailp_ = 0; otherTailp_->otherTailp_ = 0; @@ -1162,7 +1161,7 @@ namespace boost { namespace polygon{ otherTailp_ = 0; } for(typename std::list<active_tail_arbitrary*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) { - //std::cout << "delete p " << (*itr) << std::endl; + //std::cout << "delete p " << (*itr) << "\n"; if(*itr) { if((*itr)->otherTailp_) { delete (*itr)->otherTailp_; @@ -1176,10 +1175,10 @@ namespace boost { namespace polygon{ } inline void print() { - //std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << std::endl; + //std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n"; } - static inline std::pair<active_tail_arbitrary*, active_tail_arbitrary*> createActiveTailsAsPair(Point point, bool solid, + 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; @@ -1195,7 +1194,7 @@ namespace boost { namespace polygon{ at2 = new active_tail_arbitrary(at1); at1->otherTailp_ = at2; at2->head_ = !solid; - if(phole) + if(phole) at2->addHole(phole); //assert fractureHoles == false } return std::pair<active_tail_arbitrary*, active_tail_arbitrary*>(at1, at2); @@ -1219,19 +1218,19 @@ namespace boost { namespace polygon{ static inline void sort_vertex_arbitrary_count(vertex_arbitrary_count& count, const Point& pt) { less_half_edge_count lfec(pt); - gtlsort(count.begin(), count.end(), lfec); + 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 : public std::binary_function<std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>, + class less_incoming_count : public std::binary_function<std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>, std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>, bool> { private: Point pt_; public: 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, + 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); @@ -1243,7 +1242,7 @@ namespace boost { namespace polygon{ static inline void sort_incoming_count(incoming_count& count, const Point& pt) { less_incoming_count lfec(pt); - gtlsort(count.begin(), count.end(), lfec); + polygon_sort(count.begin(), count.end(), lfec); } static inline void compact_vertex_arbitrary_count(const Point& pt, vertex_arbitrary_count &count) { @@ -1282,7 +1281,7 @@ namespace boost { namespace polygon{ 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){ + inline vertex_arbitrary_compact& operator=(const vertex_arbitrary_compact& vertex){ pt = vertex.pt; count = vertex.count; return *this; } //inline vertex_arbitrary_compact(const std::pair<Point, Point>& vertex) {} inline vertex_arbitrary_compact& operator=(const std::pair<Point, Point>& vertex){ return *this; } @@ -1315,24 +1314,24 @@ namespace boost { namespace polygon{ 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_; + int fractureHoles_; public: - inline polygon_arbitrary_formation() : + 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) : + 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) : + 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_; @@ -1345,7 +1344,7 @@ namespace boost { namespace polygon{ } 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 @@ -1356,20 +1355,20 @@ namespace boost { namespace polygon{ while(inputBegin != inputEnd) { //std::cout << "2\n"; x_ = (*inputBegin).pt.get(HORIZONTAL); - //std::cout << "SCAN FORMATION " << x_ << std::endl; - //std::cout << "x_ = " << x_ << std::endl; - //std::cout << "scan line size: " << scanData_.size() << std::endl; + //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() << std::endl; + //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 << std::endl; + 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; @@ -1387,7 +1386,7 @@ namespace boost { namespace polygon{ 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; @@ -1401,27 +1400,27 @@ namespace boost { namespace polygon{ 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() << std::endl; + //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 << std::endl; + // } std::cout << "\n"; // print(incoming_count); { for(int i = 0; i < c_size_less_1; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << j << "\n"; if(counts[j]) { if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << std::endl; + //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); + active_tail_arbitrary::joinChains(point, tails[i], tails[j], true, output); counts[i] = 0; counts[j] = 0; tails[i] = 0; @@ -1437,17 +1436,17 @@ namespace boost { namespace polygon{ //std::cout << "checking case2\n"; { for(int i = 0; i < i_size_less_1; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << j << "\n"; if(incoming[j]) { - //std::cout << incoming[j] << std::endl; + //std::cout << incoming[j] << "\n"; if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << std::endl; + //std::cout << "case2: " << i << " " << j << "\n"; //std::cout << "creating active tail pair\n"; - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = + std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, fractureHoles_ != 0); //tailPair.first->print(); //tailPair.second->print(); @@ -1457,15 +1456,15 @@ namespace boost { namespace polygon{ returnCount.first = point; returnCount.second = 1; } else { - //std::cout << "new element " << j-1 << " " << -1 << std::endl; - //std::cout << point << " " << incoming_count[j].first << std::endl; - elements.push_back(std::pair<vertex_half_edge, + //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 << std::endl; - //std::cout << point << " " << incoming_count[i].first << std::endl; - elements.push_back(std::pair<vertex_half_edge, + //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; @@ -1484,14 +1483,14 @@ namespace boost { namespace polygon{ { //std::cout << "checking case 3\n"; for(int i = 0; i < c_size; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << "case3: " << i << " " << j << "\n"; //tails[i]->print(); //pass through solid on top tails[i]->pushPoint(point); @@ -1501,8 +1500,8 @@ namespace boost { namespace polygon{ returnCount.first = point; returnCount.second = -1; } else { - elements.push_back(std::pair<vertex_half_edge, - active_tail_arbitrary*>(vertex_half_edge(point, + 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; @@ -1521,13 +1520,13 @@ namespace boost { namespace polygon{ //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] << std::endl; + //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 << std::endl; + //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)) { @@ -1535,8 +1534,8 @@ namespace boost { namespace polygon{ returnCount.first = point; returnCount.second = 1; } else { - //std::cout << "new element " << j-1 << " " << incoming[j] << std::endl; - //std::cout << point << " " << incoming_count[j].first << std::endl; + //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])); @@ -1561,11 +1560,11 @@ namespace boost { namespace polygon{ if(counts[i] != 0) { for(int j = i+1; j < c_size; ++j) { if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << std::endl; + //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 << std::endl; + //std::cout << returnValue << "\n"; tails[i] = 0; tails[j] = 0; counts[i] = 0; @@ -1575,7 +1574,7 @@ namespace boost { namespace polygon{ } break; } - } + } } //find beginning of a hole { @@ -1583,34 +1582,34 @@ namespace boost { namespace polygon{ if(incoming[i] != 0) { for(int j = i+1; j < i_size; ++j) { if(incoming[j] != 0) { - //std::cout << "case6: " << i << " " << j << std::endl; + //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(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 = + 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 << std::endl; + //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] << std::endl; - //std::cout << point << " " << incoming_count[j].first << std::endl; - elements.push_back(std::pair<vertex_half_edge, + //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] << std::endl; - //std::cout << point << " " << incoming_count[i].first << std::endl; - elements.push_back(std::pair<vertex_half_edge, + //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; @@ -1639,13 +1638,13 @@ namespace boost { namespace polygon{ //std::cout << count[i].first.get(HORIZONTAL) << ","; //std::cout << count[i].first.get(VERTICAL) << ":"; //std::cout << count[i].second << " "; - } //std::cout << std::endl; + } //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 << std::endl; + } //std::cout << "\n"; } template <class cT, class iT> @@ -1664,16 +1663,16 @@ namespace boost { namespace polygon{ while(currentIter != inputEnd && currentIter->pt.get(HORIZONTAL) == x_) { //std::cout << "loop\n"; Unit currentY = (*currentIter).pt.get(VERTICAL); - //std::cout << "current Y " << currentY << std::endl; - //std::cout << "scanline size " << scanData_.size() << std::endl; + //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()) << std::endl; + //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_) << std::endl; + // 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))) { @@ -1682,13 +1681,13 @@ namespace boost { namespace polygon{ 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.other_pt), iter->first.count), iter->second)); ++iter; } Point currentPoint(x_, currentY); - //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << std::endl; + //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << "\n"; sort_incoming_count(counts_from_scanline, currentPoint); vertex_arbitrary_count incoming; @@ -1702,9 +1701,9 @@ namespace boost { namespace polygon{ currentIter->pt.get(HORIZONTAL) == x_); //print(incoming); sort_vertex_arbitrary_count(incoming, currentPoint); - //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << std::endl; + //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << "\n"; //print(incoming); - //std::cout << "incoming counts from input size " << incoming.size() << std::endl; + //std::cout << "incoming counts from input size " << incoming.size() << "\n"; //compact_vertex_arbitrary_count(currentPoint, incoming); vertex_arbitrary_count tmp; tmp.reserve(incoming.size()); @@ -1714,16 +1713,16 @@ namespace boost { namespace polygon{ } } incoming.swap(tmp); - //std::cout << "incoming counts from input size " << incoming.size() << std::endl; + //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 << std::endl; + //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), + (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(verticalCount.first, + currentPoint), -verticalCount.second), verticalTail)); } @@ -1737,13 +1736,13 @@ namespace boost { namespace polygon{ verticalTail = result.second; //if(verticalTail) { // std::cout << "have vertical tail\n"; - // std::cout << verticalCount.second << std::endl; + // 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 || + 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_)) { @@ -1791,15 +1790,15 @@ namespace boost { namespace polygon{ //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_ << std::endl; + //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"; @@ -1814,11 +1813,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -1838,11 +1837,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -1862,11 +1861,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -1908,16 +1907,16 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } pf2.scan(polys2, data.begin(), data.end()); - stdcout << "result size: " << polys2.size() << std::endl; + stdcout << "result size: " << polys2.size() << "\n"; for(std::size_t i = 0; i < polys2.size(); ++i) { - stdcout << polys2[i] << std::endl; + stdcout << polys2[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -1943,23 +1942,23 @@ namespace boost { namespace polygon{ 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)); - - gtlsort(data.begin(), data.end()); + + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -1985,21 +1984,21 @@ namespace boost { namespace polygon{ 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)); - - gtlsort(data.begin(), data.end()); + + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -2025,21 +2024,21 @@ namespace boost { namespace polygon{ 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)); - - gtlsort(data.begin(), data.end()); + + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -2063,11 +2062,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing polygon formation\n"; return true; @@ -2120,7 +2119,7 @@ namespace boost { namespace polygon{ return b; } - + }; template <typename Unit> @@ -2134,7 +2133,7 @@ namespace boost { namespace polygon{ 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) {} @@ -2174,7 +2173,7 @@ namespace boost { namespace polygon{ 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; @@ -2183,7 +2182,7 @@ namespace boost { namespace polygon{ 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(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; @@ -2241,7 +2240,7 @@ namespace boost { namespace polygon{ 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; @@ -2261,7 +2260,7 @@ namespace boost { namespace polygon{ 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>() {} @@ -2270,7 +2269,7 @@ namespace boost { namespace polygon{ * 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 @@ -2281,24 +2280,24 @@ namespace boost { namespace polygon{ while(inputBegin != inputEnd) { //std::cout << "2\n"; polygon_arbitrary_formation<Unit>::x_ = (*inputBegin).pt.get(HORIZONTAL); - //std::cout << "SCAN FORMATION " << x_ << std::endl; - //std::cout << "x_ = " << x_ << std::endl; - //std::cout << "scan line size: " << scanData_.size() << std::endl; + //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() << std::endl; + //std::cout << "scan line size: " << scanData_.size() << "\n"; } private: //functions - inline void getVerticalPair_(std::pair<active_tail_arbitrary*, - active_tail_arbitrary*>& verticalPair, + 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_, + 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 = + std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = active_tail_arbitrary::createActiveTailsAsPair(prevPoint, true, 0, false); verticalPair.first = iterTail; verticalPair.second = tailPair.first; @@ -2306,12 +2305,12 @@ namespace boost { namespace polygon{ } template <class cT, class cT2> - inline std::pair<std::pair<Point, int>, active_tail_arbitrary*> - processPoint_(cT& output, cT2& elements, + 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 << std::endl; + 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; @@ -2329,7 +2328,7 @@ namespace boost { namespace polygon{ incoming.back() = 0; } } - + active_tail_arbitrary* returnValue = 0; std::pair<active_tail_arbitrary*, active_tail_arbitrary*> verticalPairOut; verticalPairOut.first = 0; @@ -2346,27 +2345,27 @@ namespace boost { namespace polygon{ 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() << std::endl; + //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 << std::endl; + // } std::cout << "\n"; // print(incoming_count); { for(int i = 0; i < c_size_less_1; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << j << "\n"; if(counts[j]) { if(counts[j] == 1) { - //std::cout << "case1: " << i << " " << j << std::endl; + //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); + active_tail_arbitrary::joinChains(point, tails[i], tails[j], true, output); counts[i] = 0; counts[j] = 0; tails[i] = 0; @@ -2382,17 +2381,17 @@ namespace boost { namespace polygon{ //std::cout << "checking case2\n"; { for(int i = 0; i < i_size_less_1; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << j << "\n"; if(incoming[j]) { - //std::cout << incoming[j] << std::endl; + //std::cout << incoming[j] << "\n"; if(incoming[j] == -1) { - //std::cout << "case2: " << i << " " << j << std::endl; + //std::cout << "case2: " << i << " " << j << "\n"; //std::cout << "creating active tail pair\n"; - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = + 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(); @@ -2402,15 +2401,15 @@ namespace boost { namespace polygon{ returnCount.first = point; returnCount.second = 1; } else { - //std::cout << "new element " << j-1 << " " << -1 << std::endl; - //std::cout << point << " " << incoming_count[j].first << std::endl; - elements.push_back(std::pair<vertex_half_edge, + //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 << std::endl; - //std::cout << point << " " << incoming_count[i].first << std::endl; - elements.push_back(std::pair<vertex_half_edge, + //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; @@ -2429,14 +2428,14 @@ namespace boost { namespace polygon{ { //std::cout << "checking case 3\n"; for(int i = 0; i < c_size; ++i) { - //std::cout << i << std::endl; + //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 << std::endl; + //std::cout << "case3: " << i << " " << j << "\n"; //tails[i]->print(); //pass through solid on top tails[i]->pushPoint(point); @@ -2446,12 +2445,12 @@ namespace boost { namespace polygon{ returnCount.first = point; returnCount.second = -1; } else { - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = + 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, + 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; @@ -2470,21 +2469,21 @@ namespace boost { namespace polygon{ //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] << std::endl; + //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 << std::endl; + //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) == + 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 && + if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) { returnValue = tails[i]; returnCount.first = point; @@ -2495,13 +2494,13 @@ namespace boost { namespace polygon{ 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) == + } 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); + active_tail_arbitrary::joinChains(point, tails[i], verticalPair.first, true, output); returnValue = verticalPair.second; returnCount.first = point; returnCount.second = 1; @@ -2510,7 +2509,7 @@ namespace boost { namespace polygon{ if(verticalPair.first == 0) { getVerticalPair_(verticalPair, previter); } - active_tail_arbitrary::joinChains(point, tails[i], verticalPair.first, true, output); + 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, @@ -2536,13 +2535,13 @@ namespace boost { namespace polygon{ if(counts[i] != 0) { for(int j = i+1; j < c_size; ++j) { if(counts[j] != 0) { - //std::cout << "case5: " << i << " " << j << std::endl; + //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)) { + counts_from_scanline[j].first.first.first.get(HORIZONTAL) == + point.get(HORIZONTAL)) { verticalPairOut.second = tails[j]; } else { //need to close a trapezoid below @@ -2561,7 +2560,7 @@ namespace boost { namespace polygon{ } break; } - } + } } //find beginning of a hole { @@ -2569,7 +2568,7 @@ namespace boost { namespace polygon{ if(incoming[i] != 0) { for(int j = i+1; j < i_size; ++j) { if(incoming[j] != 0) { - //std::cout << "case6: " << i << " " << j << std::endl; + //std::cout << "case6: " << i << " " << j << "\n"; //we are beginning a empty space if(verticalPair.first == 0) { getVerticalPair_(verticalPair, previter); @@ -2581,15 +2580,15 @@ namespace boost { namespace polygon{ returnCount.first = point; returnCount.second = -1; } else { - std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair = + 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, + 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, + 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; @@ -2619,18 +2618,18 @@ namespace boost { namespace polygon{ //std::cout << count[i].first.get(HORIZONTAL) << ","; //std::cout << count[i].first.get(VERTICAL) << ":"; //std::cout << count[i].second << " "; - } //std::cout << std::endl; + } //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 << std::endl; + } //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; + //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 @@ -2645,16 +2644,16 @@ namespace boost { namespace polygon{ 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 << std::endl; - //std::cout << "scanline size " << scanData_.size() << std::endl; + //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()) << std::endl; + //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_) << std::endl; + // 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 && @@ -2668,13 +2667,13 @@ namespace boost { namespace polygon{ 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.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() << std::endl; + //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << "\n"; this->sort_incoming_count(counts_from_scanline, currentPoint); vertex_arbitrary_count incoming; @@ -2688,9 +2687,9 @@ namespace boost { namespace polygon{ 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) << std::endl; + //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << "\n"; //print(incoming); - //std::cout << "incoming counts from input size " << incoming.size() << std::endl; + //std::cout << "incoming counts from input size " << incoming.size() << "\n"; //compact_vertex_arbitrary_count(currentPoint, incoming); vertex_arbitrary_count tmp; tmp.reserve(incoming.size()); @@ -2700,16 +2699,16 @@ namespace boost { namespace polygon{ } } incoming.swap(tmp); - //std::cout << "incoming counts from input size " << incoming.size() << std::endl; + //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 << std::endl; + //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), + (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(verticalCount.first, + currentPoint), -verticalCount.second), verticalTail)); } @@ -2769,11 +2768,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing trapezoid formation\n"; return true; @@ -2792,11 +2791,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing trapezoid formation\n"; return true; @@ -2815,11 +2814,11 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } stdcout << "done testing trapezoid formation\n"; return true; @@ -2860,16 +2859,16 @@ namespace boost { namespace polygon{ 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)); - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + stdcout << polys[i] << "\n"; } //pf2.scan(polys2, data.begin(), data.end()); - //stdcout << "result size: " << polys2.size() << std::endl; + //stdcout << "result size: " << polys2.size() << "\n"; //for(std::size_t i = 0; i < polys2.size(); ++i) { - // stdcout << polys2[i] << std::endl; + // stdcout << polys2[i] << "\n"; //} stdcout << "done testing trapezoid formation\n"; return true; @@ -2895,29 +2894,29 @@ namespace boost { namespace polygon{ 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)); - - gtlsort(data.begin(), data.end()); + + polygon_sort(data.begin(), data.end()); pf.scan(polys, data.begin(), data.end()); - stdcout << "result size: " << polys.size() << std::endl; + stdcout << "result size: " << polys.size() << "\n"; for(std::size_t i = 0; i < polys.size(); ++i) { - stdcout << polys[i] << std::endl; + 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> diff --git a/boost/polygon/detail/polygon_formation.hpp b/boost/polygon/detail/polygon_formation.hpp index 012996271d..be2f54351d 100644 --- a/boost/polygon/detail/polygon_formation.hpp +++ b/boost/polygon/detail/polygon_formation.hpp @@ -5,6 +5,8 @@ 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{ @@ -72,7 +74,7 @@ namespace polygon_formation { */ PolyLine* headp_; PolyLine* tailp_; - + /* * state bitmask * bit zero is orientation, 0 H, 1 V @@ -81,7 +83,7 @@ namespace polygon_formation { * bit 3 is solid to left of PolyLine when 1, right when 0 */ int state_; - + public: /* * default constructor (for preallocation) @@ -317,8 +319,22 @@ namespace polygon_formation { 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 */ @@ -343,7 +359,10 @@ namespace polygon_formation { //now we have the right winding direction //if it is horizontal we need to skip the first element pLine_ = at->getTail(); - index_ = at->getTail()->numSegments() - 1; + + if(at->getTail()->numSegments() > 0) + index_ = at->getTail()->numSegments() - 1; + if((at->getOrient() == HORIZONTAL) ^ (orient == HORIZONTAL)) { pLineEnd_ = at->getTail(); indexEnd_ = pLineEnd_->numSegments() - 1; @@ -358,10 +377,27 @@ namespace polygon_formation { } 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_) { @@ -576,7 +612,9 @@ namespace polygon_formation { 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 0; } + inline std::size_t size() const { + return p_->getPolyLineSize(); + } inline ActiveTail<Unit>* yield() { return p_; } template<class iT> inline PolyLineHoleData& set(iT inputBegin, iT inputEnd) { @@ -689,7 +727,72 @@ namespace polygon_formation { /* 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); + 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_(); @@ -759,7 +862,7 @@ namespace polygon_formation { headp_(0), tailp_(0), state_(orient.to_int() + - (side << 3)) {} + (side << 3)){} //copy constructor template <typename Unit> @@ -884,12 +987,14 @@ namespace polygon_formation { template <typename Unit> inline PolyLine<Unit>& PolyLine<Unit>::pushPoint(const point_data<Unit>& point) { - 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(); - } + 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)); } @@ -1007,22 +1112,25 @@ namespace polygon_formation { } template <typename Unit> - inline ActiveTail<Unit>::ActiveTail() : tailp_(0), otherTailp_(0), holesList_() {} + 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_() { + 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_() {} + 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_() {} + inline ActiveTail<Unit>::ActiveTail(const ActiveTail<Unit>& that) : tailp_(that.tailp_), otherTailp_(that.otherTailp_), holesList_(), polyLineSize_(that.polyLineSize_) {} //destructor template <typename Unit> @@ -1036,6 +1144,7 @@ namespace polygon_formation { //self assignment is safe in this case tailp_ = that.tailp_; otherTailp_ = that.otherTailp_; + polyLineSize_ = that.polyLineSize_; return *this; } @@ -1083,12 +1192,17 @@ namespace polygon_formation { 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); @@ -1151,7 +1265,11 @@ namespace polygon_formation { 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); } @@ -1298,7 +1416,7 @@ namespace polygon_formation { //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 { + } else { //assert pG != 0 //the figure that was closed is a shell at1->writeOutFigure(outBufferTmp); @@ -1324,6 +1442,11 @@ namespace polygon_formation { 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); @@ -1360,6 +1483,11 @@ namespace polygon_formation { 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); @@ -1408,6 +1536,10 @@ namespace polygon_formation { (*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); @@ -1425,9 +1557,367 @@ namespace polygon_formation { 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. // @@ -1526,17 +2016,27 @@ namespace polygon_formation { 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) { + std::vector<interval_data<Unit> >& rightEdges, + size_t vertexThreshold) { clearOutput_(); - typename std::map<Unit, ActiveTail<Unit>*>::iterator nextMapItr = tailMap_.begin(); + 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)}; + 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]; @@ -1640,7 +2140,7 @@ namespace polygon_formation { currentTail = ActiveTail<Unit>::joinChains(currentTail, tail, !trailingEdge, outputPolygons_); nextMapItr = thisMapItr; //set nextMapItr to the next position after this one ++nextMapItr; - if(currentTail) { + if(currentTail) { //figure is not closed// Unit nextItrY = UnitMax; if(nextMapItr != tailMap_.end()) { nextItrY = nextMapItr->first; @@ -1718,8 +2218,10 @@ namespace polygon_formation { //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 ) { + 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; @@ -1738,7 +2240,8 @@ namespace polygon_formation { 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); + scanlineToPolygonItrsV.processEdges(itrPoly, itrPolyEnd, prevPos, + leftEdges, rightEdges, sliceThreshold); for( ; itrPoly != itrPolyEnd; ++ itrPoly) { ++countPolygons; assign(poly, *itrPoly); @@ -1746,7 +2249,8 @@ namespace polygon_formation { } } else { typename polygon_formation::ScanLineToPolygonItrs<false, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsH.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges); + scanlineToPolygonItrsH.processEdges(itrPoly, itrPolyEnd, prevPos, + leftEdges, rightEdges, sliceThreshold); for( ; itrPoly != itrPolyEnd; ++ itrPoly) { ++countPolygons; assign(poly, *itrPoly); @@ -1783,7 +2287,7 @@ namespace polygon_formation { } if(orient == VERTICAL) { typename polygon_formation::ScanLineToPolygonItrs<true, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsV.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges); + scanlineToPolygonItrsV.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges, sliceThreshold); for( ; itrPoly != itrPolyEnd; ++ itrPoly) { ++countPolygons; assign(poly, *itrPoly); @@ -1791,7 +2295,8 @@ namespace polygon_formation { } } else { typename polygon_formation::ScanLineToPolygonItrs<false, coordinate_type, polygon_concept_type>::iterator itrPoly, itrPolyEnd; - scanlineToPolygonItrsH.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges); + scanlineToPolygonItrsH.processEdges(itrPoly, itrPolyEnd, prevPos, leftEdges, rightEdges, sliceThreshold); + for( ; itrPoly != itrPolyEnd; ++ itrPoly) { ++countPolygons; assign(poly, *itrPoly); @@ -1804,4 +2309,3 @@ namespace polygon_formation { } } #endif - diff --git a/boost/polygon/detail/polygon_set_view.hpp b/boost/polygon/detail/polygon_set_view.hpp index 693acc4177..7d2709141c 100644 --- a/boost/polygon/detail/polygon_set_view.hpp +++ b/boost/polygon/detail/polygon_set_view.hpp @@ -1,6 +1,6 @@ /* 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). @@ -8,36 +8,36 @@ #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; + //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; - } + //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; + //} } } @@ -66,7 +66,7 @@ namespace boost { namespace polygon{ 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 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); @@ -92,33 +92,34 @@ namespace boost { namespace polygon{ 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 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 (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 (default: 4127) -#endif - output_.insert(o45); - } else { +// 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> @@ -172,11 +173,11 @@ namespace boost { namespace polygon{ } 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>& ) { + 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>& ) { + sort(const polygon_set_view<ltype, rtype, op_type>& ) { return true; } template <typename value_type, typename arg_type> @@ -187,7 +188,7 @@ namespace boost { namespace polygon{ 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; @@ -201,13 +202,21 @@ namespace boost { namespace polygon{ // copy constructor template <typename coordinate_type> - template <typename ltype, typename rtype, int op_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/boost/polygon/detail/polygon_simplify.hpp b/boost/polygon/detail/polygon_simplify.hpp index c9a92f3e6f..4871f507e4 100644 --- a/boost/polygon/detail/polygon_simplify.hpp +++ b/boost/polygon/detail/polygon_simplify.hpp @@ -8,19 +8,19 @@ #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, + 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 coordinate_traits<coordinate_type>::area_type ftype; typedef typename std::vector<T>::const_iterator iter; std::vector<T> out; @@ -33,7 +33,7 @@ namespace boost { namespace polygon { namespace detail { namespace simplify_deta 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 + //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) { @@ -41,7 +41,7 @@ namespace boost { namespace polygon { namespace detail { namespace simplify_deta 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); @@ -49,47 +49,47 @@ namespace boost { namespace polygon { namespace detail { namespace simplify_deta 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; } diff --git a/boost/polygon/detail/polygon_sort_adaptor.hpp b/boost/polygon/detail/polygon_sort_adaptor.hpp index 40f16a7e1b..b3561f87d0 100644 --- a/boost/polygon/detail/polygon_sort_adaptor.hpp +++ b/boost/polygon/detail/polygon_sort_adaptor.hpp @@ -1,6 +1,6 @@ /* 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). @@ -14,22 +14,22 @@ #include <algorithm> -//! @brief gtlsort_adaptor default implementation that calls std::sort +//! @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 + typedef int unit_type; // default GTL unit }; - //! @brief gtlsort_adaptor default implementation that calls std::sort + //! @brief polygon_sort_adaptor default implementation that calls std::sort template<typename T> - struct gtlsort_adaptor { + 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, + static void sort(RandomAccessIterator_Type _First, RandomAccessIterator_Type _Last) { std::sort(_First, _Last); @@ -37,31 +37,31 @@ namespace boost { //! @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, + 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 + //! @brief user level wrapper for sorting quantities template <typename iter_type> - void gtlsort(iter_type _b_, iter_type _e_) + void polygon_sort(iter_type _b_, iter_type _e_) { - gtlsort_adaptor<typename dummy_to_delay_instantiation<iter_type>::unit_type>::sort(_b_, _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 gtlsort(iter_type _b_, iter_type _e_, const pred_type& _pred_) + void polygon_sort(iter_type _b_, iter_type _e_, const pred_type& _pred_) { - gtlsort_adaptor<typename dummy_to_delay_instantiation<iter_type>::unit_type>::sort(_b_, _e_, _pred_); + polygon_sort_adaptor<typename dummy_to_delay_instantiation<iter_type>::unit_type>::sort(_b_, _e_, _pred_); } - + } // namespace polygon -} // namespace boost +} // namespace boost #endif diff --git a/boost/polygon/detail/property_merge.hpp b/boost/polygon/detail/property_merge.hpp index 77f2614753..b0c843b5de 100644 --- a/boost/polygon/detail/property_merge.hpp +++ b/boost/polygon/detail/property_merge.hpp @@ -1,6 +1,6 @@ /* 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). @@ -70,8 +70,8 @@ public: //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, + 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; @@ -112,7 +112,7 @@ public: inline void perform_merge(result_type& result, property_merge_data& data) { if(data.empty()) return; //sort - gtlsort(data.begin(), data.end(), less_vertex_data<vertex_property>()); + polygon_sort(data.begin(), data.end(), less_vertex_data<vertex_property>()); //scanline bool firstIteration = true; scanlinePosition = scanline.end(); @@ -175,7 +175,7 @@ private: //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, + 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) { @@ -286,7 +286,7 @@ private: 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 + //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 @@ -333,7 +333,7 @@ private: 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 @@ -354,7 +354,7 @@ private: std::pair<coordinate_type, property_map> elementScan; elementScan.first = currentInterval.high(); scanlinePosition = scanline.insert(scanline.end(), elementScan); - } + } } if(scanlinePosition == scanline.end() && currentY < currentInterval.high()) { @@ -423,7 +423,7 @@ private: template <typename T> inline int assertRedundant(T& t) { if(t.empty()) return 0; - int count = 0; + int count = 0; typename T::iterator itr = t.begin(); if((*itr).second.empty()) ++count; @@ -442,8 +442,8 @@ private: inline void performExtract(T& result, property_merge_data& data) { if(data.empty()) return; //sort - gtlsort(data.begin(), data.end(), less_vertex_data<vertex_property>()); - + polygon_sort(data.begin(), data.end(), less_vertex_data<vertex_property>()); + //scanline bool firstIteration = true; scanlinePosition = scanline.end(); @@ -528,7 +528,7 @@ private: insertEdges(graph, edge.second.second, previousEdge.second.first); } else { if(!firstIteration){ - //look up regions above previous edge + //look up regions above previous edge propertySetAbove(previousEdge.first.high(), ps, scanline); insertEdges(graph, ps, previousEdge.second.first); insertEdges(graph, ps, previousEdge.second.second); diff --git a/boost/polygon/detail/property_merge_45.hpp b/boost/polygon/detail/property_merge_45.hpp index b85baf7f88..c2feffc98f 100644 --- a/boost/polygon/detail/property_merge_45.hpp +++ b/boost/polygon/detail/property_merge_45.hpp @@ -1,6 +1,6 @@ /* 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). @@ -30,7 +30,7 @@ namespace boost { namespace polygon{ 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) { + 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; @@ -72,7 +72,7 @@ namespace boost { namespace polygon{ //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, + 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; @@ -98,20 +98,20 @@ namespace boost { namespace polygon{ } }; - typedef typename std::pair<Point, + 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) { - - gtlsort(tsd.begin(), tsd.end(), lessVertex45Compact()); + + 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()); @@ -149,7 +149,7 @@ namespace boost { namespace polygon{ } } } - + }; diff --git a/boost/polygon/detail/rectangle_formation.hpp b/boost/polygon/detail/rectangle_formation.hpp index d0ae180ea4..22d0f38cac 100644 --- a/boost/polygon/detail/rectangle_formation.hpp +++ b/boost/polygon/detail/rectangle_formation.hpp @@ -1,6 +1,6 @@ /* 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). @@ -10,14 +10,14 @@ namespace boost { namespace polygon{ namespace rectangle_formation { - template <class T> + 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_; @@ -26,17 +26,17 @@ namespace rectangle_formation { 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_); @@ -45,12 +45,12 @@ namespace rectangle_formation { 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) + 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; @@ -59,15 +59,15 @@ namespace rectangle_formation { //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)) && + 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 + //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)) + (*dataIter).get(orient).get(LOW) <= edge.get(HIGH)) { const rectangle_type& rect = *dataIter; //if the rectangle data intersects the edge at all @@ -111,7 +111,7 @@ namespace rectangle_formation { scanData.insert(nextIter, highRect); } //we are done with this edge - edgeProcessed = true; + edgeProcessed = true; break; } else { //it must be an opening edge @@ -145,8 +145,8 @@ namespace rectangle_formation { } } else { //extend the top of current rect - currentRect.set(orient.get_direction(HIGH), - (std::max)(edge.get(HIGH), + currentRect.set(orient.get_direction(HIGH), + (std::max)(edge.get(HIGH), tmpRect.get(orient.get_direction(HIGH)))); } } else { @@ -155,7 +155,7 @@ namespace rectangle_formation { //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), + 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)))); @@ -164,7 +164,7 @@ namespace rectangle_formation { 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), + 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)))); @@ -176,22 +176,22 @@ namespace rectangle_formation { //edgeProcessed = true; } ++dataIter; - } //end while edge intersects rectangle data + } //end while edge intersects rectangle data } if(!edgeProcessed) { if(haveCurrentRect) { - if(currentRect.get(orient.get_perpendicular().get_direction(HIGH)) + if(currentRect.get(orient.get_perpendicular().get_direction(HIGH)) == currentCoordinate && - currentRect.get(orient.get_direction(HIGH)) >= edge.get(LOW)) + 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.set(orient, + interval_data<coordinate_type>(edge.get(HIGH), currentRect.get(orient.get_direction(HIGH)))); return rectangles; } else { @@ -205,7 +205,7 @@ namespace rectangle_formation { } scanData.insert(scanData.end(), currentRect); haveCurrentRect = false; - } + } rectangle_type tmpRect(currentRect); tmpRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate, currentCoordinate)); @@ -214,13 +214,13 @@ namespace rectangle_formation { return rectangles; } return rectangles; - + } - template <class T> - template <class CT> - inline - ScanLineToRects<T>& ScanLineToRects<T>::processEdge(CT& rectangles, const interval_data<coordinate_type>& edge) + 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; @@ -264,4 +264,3 @@ namespace rectangle_formation { } } #endif - diff --git a/boost/polygon/detail/scan_arbitrary.hpp b/boost/polygon/detail/scan_arbitrary.hpp index 1933eee7ed..871522511c 100644 --- a/boost/polygon/detail/scan_arbitrary.hpp +++ b/boost/polygon/detail/scan_arbitrary.hpp @@ -1,6 +1,6 @@ /* 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). @@ -17,11 +17,11 @@ namespace boost { namespace polygon{ 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; @@ -51,7 +51,7 @@ namespace boost { namespace polygon{ // 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); @@ -76,7 +76,7 @@ namespace boost { namespace polygon{ ends.push_back(std::make_pair((*itr).first.first.y(), count)); ends.push_back(std::make_pair((*itr).first.second.y(), -count)); } - gtlsort(ends.begin(), ends.end()); + 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) { @@ -128,11 +128,11 @@ namespace boost { namespace polygon{ 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 = + 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 = + 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); @@ -161,7 +161,7 @@ namespace boost { namespace polygon{ } } typename scanline_base<Unit>::compute_intersection_pack pack_; - gtlsort(data.begin(), data.end()); + 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) { @@ -182,7 +182,7 @@ namespace boost { namespace polygon{ //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)) >= + he2.second.get(HORIZONTAL)) >= (std::max)(he1.second.get(HORIZONTAL), he1.first.get(HORIZONTAL))) break; @@ -194,11 +194,11 @@ namespace boost { namespace polygon{ pts.push_back(intersection); intersection_points[(*inner).second].insert(intersection); intersection_points[(*outer).second].insert(intersection); - } + } } } } - gtlsort(pts.begin(), pts.end()); + 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 @@ -206,7 +206,7 @@ namespace boost { namespace polygon{ outer != data.end(); ++outer) { const half_edge& he1 = (*outer).first; segment_id id1 = (*outer).second; - typedef rectangle_data<Unit> Rectangle; + //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)); @@ -217,7 +217,7 @@ namespace boost { namespace polygon{ //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; + 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); @@ -269,11 +269,11 @@ namespace boost { namespace polygon{ // 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 << std::endl; +// } 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 << std::endl; +// } std::cout << "\n"; // exit(1); // } } @@ -289,7 +289,7 @@ namespace boost { namespace polygon{ std::swap(data[i].first.first, data[i].first.second); } } - gtlsort(data.begin(), data.end()); + 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; @@ -299,7 +299,7 @@ namespace boost { namespace polygon{ const half_edge& he2 = (*inner).first; if(he1 == he2) continue; if((std::min)(he2. first.get(HORIZONTAL), - he2.second.get(HORIZONTAL)) > + he2.second.get(HORIZONTAL)) > (std::max)(he1.second.get(HORIZONTAL), he1.first.get(HORIZONTAL))) break; @@ -307,7 +307,7 @@ namespace boost { namespace polygon{ 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() << std::endl; + //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; } } @@ -359,7 +359,7 @@ namespace boost { namespace polygon{ tmpPts.reserve(pts.size()); tmpPts.insert(tmpPts.end(), pts.begin(), pts.end()); less_point_down_slope lpds; - gtlsort(tmpPts.begin(), tmpPts.end(), 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()); @@ -432,7 +432,7 @@ namespace boost { namespace polygon{ // edge_scanline_.erase(remove_iter); // } -// static inline void update_segments(std::map<segment_id, std::set<Point> >& intersection_points, +// 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); @@ -479,7 +479,7 @@ namespace boost { namespace polygon{ // 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 +// //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 @@ -491,7 +491,7 @@ namespace boost { namespace polygon{ // //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); +// 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)); @@ -499,9 +499,9 @@ namespace boost { namespace polygon{ // } // } // } - + // //merge sloping element data -// gtlsort(sloping_ends.begin(), sloping_ends.end()); +// 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(); @@ -574,7 +574,7 @@ namespace boost { namespace polygon{ // 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 +// //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; @@ -591,7 +591,7 @@ namespace boost { namespace polygon{ // lookup_and_remove(he, id); // } else { // //half edge is begin event -// insert_into_scanline(he, id); +// 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 @@ -693,7 +693,7 @@ namespace boost { namespace polygon{ } edges.clear(); validate_scan(edges, input.begin(), input.end()); - stdcout << edges.size() << std::endl; + stdcout << edges.size() << "\n"; if(!verify_scan(result, edges.begin(), edges.end())) { stdcout << "s fail5 3 " << result.first << " " << result.second << "\n"; return false; @@ -787,7 +787,7 @@ namespace boost { namespace polygon{ print(edges); return false; } - //3 3 2 2: 0; 4 2 0 6: 1; 0 3 6 3: 2; 4 1 5 5: 3; + //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)); @@ -801,7 +801,7 @@ namespace boost { namespace polygon{ print(edges); return false; } - //5 7 1 3: 0; 4 5 2 1: 1; 2 5 2 1: 2; 4 1 5 3: 3; + //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)); @@ -815,7 +815,7 @@ namespace boost { namespace polygon{ print(edges); return false; } - //1 0 -4 -1: 0; 0 0 2 -1: 1; + //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)); @@ -875,8 +875,8 @@ namespace boost { namespace polygon{ 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 << std::endl; + } + //std::cout << "\n"; } template <typename stream_type> @@ -940,14 +940,14 @@ namespace boost { namespace polygon{ }; //scanline consumes the "flattened" fully intersected line segments produced by - //a pass of line_intersection along with property and count information and performs a + //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; @@ -970,7 +970,7 @@ namespace boost { namespace polygon{ //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; @@ -987,12 +987,12 @@ namespace boost { namespace polygon{ int just_before_; typename scanline_base<Unit>::evalAtXforYPack evalAtXforYPack_; public: - inline scanline() : scan_data_(), removal_set_(), insertion_set_(), end_point_queue_(), + 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_(), + 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) { @@ -1012,7 +1012,7 @@ namespace boost { namespace polygon{ 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 << std::endl; + //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); @@ -1024,7 +1024,7 @@ namespace boost { namespace polygon{ 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; + //typedef typename high_precision_type<Unit>::type high_precision; //for each event property_map vertical_properties_above; property_map vertical_properties_below; @@ -1037,11 +1037,12 @@ namespace boost { namespace polygon{ 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( disable: 4127 ) +#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 || + 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 @@ -1062,7 +1063,7 @@ namespace boost { namespace polygon{ } 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(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; @@ -1145,8 +1146,8 @@ namespace boost { namespace polygon{ ++begin; } } -#ifdef BOOST_POLYGON_MSVC -#pragma warning( default: 4127 ) +#ifdef BOOST_POLYGON_MSVC +#pragma warning (pop) #endif } @@ -1230,7 +1231,7 @@ namespace boost { namespace polygon{ // for(std::size_t i = 0; i < mp.size(); ++i) { // std::cout << mp[i].first << ":" << mp[i].second << " "; // } std::cout << ") "; - // } std::cout << std::endl; + // } std::cout << "\n"; //} static inline void merge_property_maps(property_map& mp, const property_map& mp2) { @@ -1247,7 +1248,7 @@ namespace boost { namespace polygon{ ++j; } else { int count = mp[i].second; - count += mp2[j].second; + count += mp2[j].second; if(count) { newmp.push_back(mp[i]); newmp.back().second = count; @@ -1313,7 +1314,7 @@ namespace boost { namespace polygon{ output.push_back(vertex_half_edge(he.first, he.second, count)); output.push_back(vertex_half_edge(he.second, he.first, -count)); } - gtlsort(output.begin(), output.end()); + polygon_sort(output.begin(), output.end()); } class test_functor { @@ -1338,7 +1339,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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))); @@ -1350,7 +1351,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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))); @@ -1366,7 +1367,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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))); @@ -1382,7 +1383,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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))); @@ -1398,7 +1399,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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))); @@ -1414,7 +1415,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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))); @@ -1438,7 +1439,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } 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 @@ -1458,7 +1459,7 @@ namespace boost { namespace polygon{ stdcout << "scanned\n"; for(std::size_t i = 0; i < result.size(); ++i) { stdcout << result[i].first.first << ", " << result[i].first.second << "; "; - } stdcout << std::endl; + } stdcout << "\n"; return true; } @@ -1484,12 +1485,12 @@ namespace boost { namespace polygon{ } }; - template <typename Unit, typename property_type, typename key_type = std::set<property_type>, + 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; @@ -1531,7 +1532,7 @@ namespace boost { namespace polygon{ inline void sort_property_merge_data() { less_vertex_data<vertex_property> lvd(&evalAtXforYPack_); - gtlsort(pmd.begin(), pmd.end(), lvd); + polygon_sort(pmd.begin(), pmd.end(), lvd); } public: inline property_merge_data& get_property_merge_data() { return pmd; } @@ -1568,7 +1569,7 @@ namespace boost { namespace polygon{ } if(!line_intersection<Unit>::verify_scan(offenders, lines.begin(), lines.end())) { //stdcout << "Intersection failed!\n"; - //stdcout << offenders.first << " " << offenders.second << std::endl; + //stdcout << offenders.first << " " << offenders.second << "\n"; return false; } std::vector<Point> pts; @@ -1576,7 +1577,7 @@ namespace boost { namespace polygon{ pts.push_back(lines[i].first.first); pts.push_back(lines[i].first.second); } - gtlsort(pts.begin(), pts.end()); + 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"; @@ -1590,7 +1591,7 @@ namespace boost { namespace polygon{ protected: template <typename polygon_type> - void insert(const polygon_type& polygon_object, const property_type& property_value, bool is_hole, + 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; @@ -1638,10 +1639,10 @@ namespace boost { namespace polygon{ } 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, + void insert(const polygon_with_holes_type& polygon_with_holes_object, const property_type& property_value, bool is_hole, polygon_with_holes_concept tag) { 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 = + 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()); @@ -1649,7 +1650,7 @@ namespace boost { namespace polygon{ } template <typename rectangle_type> - void insert(const rectangle_type& rectangle_object, const property_type& property_value, bool is_hole, + 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); @@ -1658,9 +1659,9 @@ namespace boost { namespace polygon{ public: //change to private when done testing - static inline void create_vertex(property_merge_data& pmd, - const Point& current_point, - const Point& next_point, + 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; @@ -1669,7 +1670,7 @@ namespace boost { namespace polygon{ current_vertex.first.second = next_point; current_vertex.second.first = property; int multiplier = 1; - if(winding == CLOCKWISE) + if(winding == CLOCKWISE) multiplier = -1; if(is_hole) multiplier *= -1; @@ -1686,7 +1687,7 @@ namespace boost { namespace polygon{ static inline void sort_vertex_half_edges(vertex_data& vertex) { less_half_edge_pair lessF(vertex.first); - gtlsort(vertex.second.begin(), vertex.second.end(), lessF); + polygon_sort(vertex.second.begin(), vertex.second.end(), lessF); } class less_half_edge_pair { @@ -1697,12 +1698,12 @@ namespace boost { namespace polygon{ bool operator()(const half_edge& e1, const half_edge& e2) { const Point& pt1 = e1.first; const Point& pt2 = e2.first; - if(get(pt1, HORIZONTAL) == + if(get(pt1, HORIZONTAL) == get(pt_, HORIZONTAL)) { //vertical edge is always largest return false; } - if(get(pt2, HORIZONTAL) == + 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); @@ -1790,34 +1791,34 @@ namespace boost { namespace polygon{ yh(rect, 11); si.insert(rect, 333); - print(stdcout, si.pmd) << std::endl; - + 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) << std::endl; + 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) << std::endl; + 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) << std::endl; - stdcout << (si2.pmd == si4.pmd) << std::endl; + 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) << std::endl; - + stdcout << (si2.pmd == si5.pmd) << "\n"; + return true; } @@ -1833,7 +1834,7 @@ namespace boost { namespace polygon{ si.insert(rect, 333); std::map<std::set<property_type>, polygon_set_data<Unit> > result; si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; polygon_set_data<Unit> psd = (*(result.begin())).second; std::vector<polygon_data<Unit> > polys; psd.get(polys); @@ -1841,7 +1842,7 @@ namespace boost { namespace polygon{ stdcout << "fail merge 1\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; si.clear(); std::vector<Point> pts; pts.push_back(Point(0, 0)); @@ -1858,17 +1859,17 @@ namespace boost { namespace polygon{ si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; psd = (*(result.begin())).second; - stdcout << psd << std::endl; + 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 } + //Polygon { -4 -1, 3 3, -2 3 } + //Polygon { 0 -4, -4 -2, -2 1 } si.clear(); pts.clear(); pts.push_back(Point(-4, -1)); @@ -1884,9 +1885,9 @@ namespace boost { namespace polygon{ si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() != 1) { @@ -1910,16 +1911,16 @@ namespace boost { namespace polygon{ si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() != 1) { stdcout << "fail merge 4\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; stdcout << "Polygon { -4 0, -2 -3, 3 -4 } \n"; stdcout << "Polygon { -1 1, 1 -2, -4 -3 } \n"; si.clear(); @@ -1937,9 +1938,9 @@ namespace boost { namespace polygon{ si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() != 1) { @@ -1963,17 +1964,17 @@ namespace boost { namespace polygon{ si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; if(!result.empty()) { psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() != 1) { stdcout << "fail merge 6\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; } stdcout << "Polygon { 0 2, 3 -1, 4 1 } \n"; stdcout << "Polygon { -4 3, 3 3, 4 2 } \n"; @@ -1992,17 +1993,17 @@ namespace boost { namespace polygon{ si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; if(!result.empty()) { psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() == 0) { stdcout << "fail merge 7\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; } stdcout << "Polygon { 1 -2, -1 4, 3 -2 } \n"; stdcout << "Polygon { 0 -3, 3 1, -3 -4 } \n"; @@ -2021,17 +2022,17 @@ stdcout << "Polygon { 0 -3, 3 1, -3 -4 } \n"; si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; if(!result.empty()) { psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() == 0) { stdcout << "fail merge 8\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; } stdcout << "Polygon { 2 2, 3 0, -3 4 } \n"; stdcout << "Polygon { -2 -2, 0 0, -1 -1 } \n"; @@ -2050,17 +2051,17 @@ stdcout << "Polygon { -2 -2, 0 0, -1 -1 } \n"; si.insert(poly, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; if(!result.empty()) { psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() == 0) { stdcout << "fail merge 9\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; } si.clear(); pts.clear(); @@ -2069,111 +2070,111 @@ stdcout << "Polygon { -2 -2, 0 0, -1 -1 } \n"; //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(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) << std::endl; + print(stdcout, si.pmd) << "\n"; if(!result.empty()) { psd = (*(result.begin())).second; - stdcout << psd << std::endl; + 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); } - gtlsort(outpts.begin(), outpts.end()); + 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 << std::endl; - stdcout << outpts[i] << " " << outpts[i+1] << std::endl; + stdcout << i << "\n"; + stdcout << outpts[i] << " " << outpts[i+1] << "\n"; return 0; } } @@ -2183,10 +2184,10 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 stdcout << "fail merge 10\n"; return false; } - stdcout << (polys[0]) << std::endl; + stdcout << (polys[0]) << "\n"; } for(unsigned int i = 0; i < 10; ++i) { - stdcout << "random case # " << i << std::endl; + stdcout << "random case # " << i << "\n"; si.clear(); pts.clear(); pts.push_back(Point(rand()%9-4, rand()%9-4)); @@ -2194,7 +2195,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 pts.push_back(Point(rand()%9-4, rand()%9-4)); polygon_data<Unit> poly1; poly1.set(pts.begin(), pts.end()); - stdcout << poly1 << std::endl; + stdcout << poly1 << "\n"; si.insert(poly1, 444); pts.clear(); pts.push_back(Point(rand()%9-4, rand()%9-4)); @@ -2202,14 +2203,14 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 pts.push_back(Point(rand()%9-4, rand()%9-4)); polygon_data<Unit> poly2; poly2.set(pts.begin(), pts.end()); - stdcout << poly2 << std::endl; + stdcout << poly2 << "\n"; si.insert(poly2, 444); result.clear(); si.merge(result); - print(stdcout, si.pmd) << std::endl; + print(stdcout, si.pmd) << "\n"; if(!result.empty()) { psd = (*(result.begin())).second; - stdcout << psd << std::endl; + stdcout << psd << "\n"; polys.clear(); psd.get(polys); if(polys.size() == 0) { @@ -2228,13 +2229,13 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 std::vector<polygon_data<Unit> > polys2; psd.get(polys2); if(!polys1.empty() || !polys2.empty()) { - stdcout << "fail random merge " << i << std::endl; + stdcout << "fail random merge " << i << "\n"; return false; } } } if(!polys.empty()) - stdcout << polys.size() << ": " << (polys[0]) << std::endl; + stdcout << polys.size() << ": " << (polys[0]) << "\n"; } return true; } @@ -2249,13 +2250,13 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 std::vector<polygon_data<Unit> > polys90; si.insert(rect1, 111); si90.insert(rect1, 111); - stdcout << rect1 << std::endl; + stdcout << rect1 << "\n"; si.insert(rect2, 222); si90.insert(rect2, 222); - stdcout << rect2 << std::endl; + stdcout << rect2 << "\n"; si.insert(rect3, 333); si90.insert(rect3, 333); - stdcout << rect3 << std::endl; + stdcout << rect3 << "\n"; si.merge(result); si90.merge(result90); if(result.size() != result90.size()) { @@ -2277,26 +2278,27 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 psd90.get(polys90); if(polys.size() != polys90.size()) { stdcout << "merge failed with polygon count mismatch\n"; - stdcout << psd << std::endl; + stdcout << psd << "\n"; for(std::size_t j = 0; j < polys.size(); ++j) { - stdcout << polys[j] << std::endl; + stdcout << polys[j] << "\n"; } stdcout << "reference\n"; for(std::size_t j = 0; j < polys90.size(); ++j) { - stdcout << polys90[j] << std::endl; + stdcout << polys90[j] << "\n"; } return 0; } bool failed = false; for(std::size_t j = 0; j < polys.size(); ++j) { - stdcout << polys[j] << std::endl; - stdcout << polys90[j] << std::endl; + 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 (default:1572) +#pragma warning (pop) #endif stdcout << "merge failed with area mismatch\n"; failed = true; @@ -2324,7 +2326,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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 << std::endl; + 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))); @@ -2356,7 +2358,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 si.insert(rect, 555); std::map<std::set<property_type>, polygon_set_data<Unit> > result; si.merge(result); - print(stdcout, si.pmd) << std::endl; + 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 << "( "; @@ -2365,18 +2367,18 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 stdcout << (*set_itr) << " "; } stdcout << ") \n"; polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << std::endl; + 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] << std::endl; + 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 << std::endl; + stdcout << "random case # " << i << "\n"; si.clear(); pts.clear(); pts.push_back(Point(rand()%9-4, rand()%9-4)); @@ -2384,7 +2386,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 pts.push_back(Point(rand()%9-4, rand()%9-4)); polygon_data<Unit> poly1; poly1.set(pts.begin(), pts.end()); - stdcout << poly1 << std::endl; + stdcout << poly1 << "\n"; si.insert(poly1, 444); si2.insert(poly1, 333); pts.clear(); @@ -2393,7 +2395,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 pts.push_back(Point(rand()%9-4, rand()%9-4)); polygon_data<Unit> poly2; poly2.set(pts.begin(), pts.end()); - stdcout << poly2 << std::endl; + stdcout << poly2 << "\n"; si.insert(poly2, 444); si2.insert(poly2, 444); pts.clear(); @@ -2402,7 +2404,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 pts.push_back(Point(rand()%9-4, rand()%9-4)); polygon_data<Unit> poly3; poly3.set(pts.begin(), pts.end()); - stdcout << poly3 << std::endl; + stdcout << poly3 << "\n"; si.insert(poly3, 444); si2.insert(poly3, 555); result.clear(); @@ -2418,15 +2420,15 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 stdcout << (*set_itr) << " "; } stdcout << ") \n"; polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << std::endl; + 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] << std::endl; + stdcout << polys2[ii] << "\n"; } } stdcout << "intersected pmd\n"; - print(stdcout, si2.pmd) << std::endl; + 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) { @@ -2436,11 +2438,11 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 stdcout << (*set_itr) << " "; } stdcout << ") \n"; polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << std::endl; + 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] << std::endl; + stdcout << polys2[ii] << "\n"; } } si.clear(); @@ -2463,11 +2465,11 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 stdcout << (*set_itr) << " "; } stdcout << ") \n"; polygon_set_data<Unit> psd = (*itr).second; - stdcout << psd << std::endl; + 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] << std::endl; + stdcout << polys2[ii] << "\n"; } } std::vector<polygon_data<Unit> > polys2; @@ -2475,7 +2477,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 (*(result.begin())).second.get(polys); (*(result2.begin())).second.get(polys2); if(!(polys == polys2)) { - stdcout << "failed intersection check # " << i << std::endl; + stdcout << "failed intersection check # " << i << "\n"; return false; } } @@ -2486,10 +2488,10 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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; @@ -2539,6 +2541,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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 @@ -2567,9 +2570,9 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 if((*(left.begin())) == 0) { result.insert_clean(elem); } - } + } #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#pragma warning (pop) #endif if(right.size() == 1) { if((*(right.begin())) == 0) { @@ -2583,7 +2586,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 inline void sort_property_merge_data() { less_vertex_data<vertex_property> lvd(&evalAtXforYPack_); - gtlsort(pmd.begin(), pmd.end(), lvd); + polygon_sort(pmd.begin(), pmd.end(), lvd); } public: inline arbitrary_boolean_op() : pmd(), evalAtXforYPack_() {} @@ -2593,7 +2596,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 enum BOOLEAN_OP_TYPE { BOOLEAN_OR = 0, BOOLEAN_AND = 1, - BOOLEAN_XOR = 2, + BOOLEAN_XOR = 2, BOOLEAN_NOT = 3 }; template <typename result_type, typename iT1, typename iT2> @@ -2627,17 +2630,17 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 } 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(; + for(; b != e; ++b) { - pmd.push_back(vertex_property(half_edge((*b).first.first, (*b).first.second), + pmd.push_back(vertex_property(half_edge((*b).first.first, (*b).first.second), std::pair<property_type, int>(id, (*b).second))); } } @@ -2660,7 +2663,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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] << std::endl; + stdcout << pv[i] << "\n"; } pv.clear(); abo.clear(); @@ -2668,7 +2671,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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] << std::endl; + stdcout << pv[i] << "\n"; } pv.clear(); abo.clear(); @@ -2676,7 +2679,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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] << std::endl; + stdcout << pv[i] << "\n"; } pv.clear(); abo.clear(); @@ -2684,7 +2687,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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] << std::endl; + stdcout << pv[i] << "\n"; } return true; } @@ -2705,9 +2708,9 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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; @@ -2752,7 +2755,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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 = + 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); @@ -2771,7 +2774,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 } } } - + template <typename result_type, typename key_type> class connectivity_extraction_output_functor { public: @@ -2784,21 +2787,21 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 x = pt.x(); std::set<property_type>& output_set = y_prop_map[pt]; { - for(typename key_type::const_iterator itr1 = + 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 = + 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 = + 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 = + for(typename key_type::const_iterator itr2 = right.begin(); itr2 != right.end(); ++itr2) { output_set2.insert(output_set2.end(), *itr2); } @@ -2807,7 +2810,7 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 inline void sort_property_merge_data() { less_vertex_data<vertex_property> lvd(&evalAtXforYPack_); - gtlsort(pmd.begin(), pmd.end(), lvd); + polygon_sort(pmd.begin(), pmd.end(), lvd); } public: inline arbitrary_connectivity_extraction() : pmd(), evalAtXforYPack_() {} @@ -2824,13 +2827,13 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 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> > >, + 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::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*>, + 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); @@ -2839,17 +2842,16 @@ pts.push_back(Point(12344171, 6695983 )); pts.push_back(Point(12287208, 6672388 inline void clear() {*this = arbitrary_connectivity_extraction();} template <typename iT> - void populateTouchSetData(iT begin, iT end, + 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), + 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/boost/polygon/detail/transform_detail.hpp b/boost/polygon/detail/transform_detail.hpp deleted file mode 100644 index 2cd3400459..0000000000 --- a/boost/polygon/detail/transform_detail.hpp +++ /dev/null @@ -1,553 +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_TRANSFORM_DETAIL_HPP -#define BOOST_POLYGON_TRANSFORM_DETAIL_HPP - -namespace boost { namespace polygon{ - // inline std::ostream& operator<< (std::ostream& o, const axis_transformation& r) { - // o << r.atr_; - // return o; - // } - - // inline std::istream& operator>> (std::istream& i, axis_transformation& r) { - // int tmp; - // i >> tmp; - // r = axis_transformation((axis_transformation::ATR)tmp); - // return i; - // } - - // template <typename scale_factor_type> - // inline std::ostream& operator<< (std::ostream& o, const anisotropic_scale_factor<scale_factor_type>& sc) { - // o << sc.scale_[0] << BOOST_POLYGON_SEP << sc.scale_[1] << GTL_SEP << sc.scale_[2]; - // return o; - // } - - // template <typename scale_factor_type> - // inline std::istream& operator>> (std::istream& i, anisotropic_scale_factor<scale_factor_type>& sc) { - // i >> sc.scale_[0] >> sc.scale_[1] >> sc.scale_[2]; - // return i; - // } - - // template <typename coordinate_type> - // inline std::ostream& operator<< (std::ostream& o, const transformation& tr) { - // o << tr.atr_ << BOOST_POLYGON_SEP << tr.p_; - // return o; - // } - - // template <typename coordinate_type> - // inline std::istream& operator>> (std::istream& i, transformation& tr) { - // i >> tr.atr_ >> tr.p_; - // return i; - // } - - - inline axis_transformation::axis_transformation(const orientation_3d& orient) : atr_(NULL_TRANSFORM) { - const ATR tmp[3] = { - UP_EAST_NORTH, //sort by x, then z, then y - EAST_UP_NORTH, //sort by y, then z, then x - EAST_NORTH_UP //sort by z, then y, then x - }; - atr_ = tmp[orient.to_int()]; - } - - inline axis_transformation::axis_transformation(const orientation_2d& orient) : atr_(NULL_TRANSFORM) { - const ATR tmp[3] = { - NORTH_EAST_UP, //sort by z, then x, then y - EAST_NORTH_UP //sort by z, then y, then x - }; - atr_ = tmp[orient.to_int()]; - } - - inline axis_transformation::axis_transformation(const direction_3d& dir) : atr_(NULL_TRANSFORM) { - const ATR tmp[6] = { - DOWN_EAST_NORTH, //sort by -x, then z, then y - UP_EAST_NORTH, //sort by x, then z, then y - EAST_DOWN_NORTH, //sort by -y, then z, then x - EAST_UP_NORTH, //sort by y, then z, then x - EAST_NORTH_DOWN, //sort by -z, then y, then x - EAST_NORTH_UP //sort by z, then y, then x - }; - atr_ = tmp[dir.to_int()]; - } - - inline axis_transformation::axis_transformation(const direction_2d& dir) : atr_(NULL_TRANSFORM) { - const ATR tmp[4] = { - SOUTH_EAST_UP, //sort by z, then x, then y - NORTH_EAST_UP, //sort by z, then x, then y - EAST_SOUTH_UP, //sort by z, then y, then x - EAST_NORTH_UP //sort by z, then y, then x - }; - atr_ = tmp[dir.to_int()]; - } - - inline axis_transformation& axis_transformation::operator=(const axis_transformation& a) { - atr_ = a.atr_; - return *this; - } - - inline axis_transformation& axis_transformation::operator=(const ATR& atr) { - atr_ = atr; - return *this; - } - - inline bool axis_transformation::operator==(const axis_transformation& a) const { - return atr_ == a.atr_; - } - - inline bool axis_transformation::operator!=(const axis_transformation& a) const { - return !(*this == a); - } - - inline bool axis_transformation::operator<(const axis_transformation& a) const { - return atr_ < a.atr_; - } - - inline axis_transformation& axis_transformation::operator+=(const axis_transformation& a){ - bool abit5 = (a.atr_ & 32) != 0; - bool abit4 = (a.atr_ & 16) != 0; - bool abit3 = (a.atr_ & 8) != 0; - bool abit2 = (a.atr_ & 4) != 0; - bool abit1 = (a.atr_ & 2) != 0; - bool abit0 = (a.atr_ & 1) != 0; - bool bit5 = (atr_ & 32) != 0; - bool bit4 = (atr_ & 16) != 0; - bool bit3 = (atr_ & 8) != 0; - bool bit2 = (atr_ & 4) != 0; - bool bit1 = (atr_ & 2) != 0; - bool bit0 = (atr_ & 1) != 0; - int indexes[2][3] = { - { - ((int)((bit5 & bit2) | (bit4 & !bit2)) << 1) + - (int)(bit2 & !bit5), - ((int)((bit4 & bit2) | (bit5 & !bit2)) << 1) + - (int)(!bit5 & !bit2), - ((int)(!bit4 & !bit5) << 1) + - (int)(bit5) - }, - { - ((int)((abit5 & abit2) | (abit4 & !abit2)) << 1) + - (int)(abit2 & !abit5), - ((int)((abit4 & abit2) | (abit5 & !abit2)) << 1) + - (int)(!abit5 & !abit2), - ((int)(!abit4 & !abit5) << 1) + - (int)(abit5) - } - }; - int zero_bits[2][3] = { - {bit0, bit1, bit3}, - {abit0, abit1, abit3} - }; - int nbit3 = zero_bits[0][2] ^ zero_bits[1][indexes[0][2]]; - 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]]; - indexes[0][2] = indexes[1][indexes[0][2]]; - int nbit5 = (indexes[0][2] == 1); - int nbit4 = (indexes[0][2] == 0); - int nbit2 = (!(nbit5 | nbit4) & (bool)(indexes[0][0] & 1)) | //swap xy - (nbit5 & ((indexes[0][0] & 2) >> 1)) | //z->y x->z - (nbit4 & ((indexes[0][1] & 2) >> 1)); //z->x y->z - atr_ = (ATR)((nbit5 << 5) + - (nbit4 << 4) + - (nbit3 << 3) + - (nbit2 << 2) + - (nbit1 << 1) + nbit0); - return *this; - } - - inline axis_transformation 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 - inline void axis_transformation::populate_axis_array(INDIVIDUAL_AXIS axis_array[]) const { - bool bit5 = (atr_ & 32) != 0; - bool bit4 = (atr_ & 16) != 0; - bool bit3 = (atr_ & 8) != 0; - bool bit2 = (atr_ & 4) != 0; - bool bit1 = (atr_ & 2) != 0; - bool bit0 = (atr_ & 1) != 0; - axis_array[2] = - (INDIVIDUAL_AXIS)((((int)(!bit4 & !bit5)) << 2) + - ((int)(bit5) << 1) + - bit3); - axis_array[1] = - (INDIVIDUAL_AXIS)((((int)((bit4 & bit2) | (bit5 & !bit2))) << 2)+ - ((int)(!bit5 & !bit2) << 1) + - bit1); - axis_array[0] = - (INDIVIDUAL_AXIS)((((int)((bit5 & bit2) | (bit4 & !bit2))) << 2) + - ((int)(bit2 & !bit5) << 1) + - bit0); - } - - // combine_axis_arrays concatenates this_array and that_array overwriting - // the result into this_array - inline void - axis_transformation::combine_axis_arrays (INDIVIDUAL_AXIS this_array[], - const INDIVIDUAL_AXIS that_array[]){ - int indexes[3] = {this_array[0] >> 1, - this_array[1] >> 1, - this_array[2] >> 1}; - int zero_bits[2][3] = { - {this_array[0] & 1, this_array[1] & 1, this_array[2] & 1}, - {that_array[0] & 1, that_array[1] & 1, that_array[2] & 1} - }; - this_array[0] = that_array[indexes[0]]; - this_array[0] = (INDIVIDUAL_AXIS)((int)this_array[0] & (int)((int)PZ+(int)PY)); - this_array[0] = (INDIVIDUAL_AXIS)((int)this_array[0] | - ((int)zero_bits[0][0] ^ - (int)zero_bits[1][indexes[0]])); - this_array[1] = that_array[indexes[1]]; - this_array[1] = (INDIVIDUAL_AXIS)((int)this_array[1] & (int)((int)PZ+(int)PY)); - this_array[1] = (INDIVIDUAL_AXIS)((int)this_array[1] | - ((int)zero_bits[0][1] ^ - (int)zero_bits[1][indexes[1]])); - this_array[2] = that_array[indexes[2]]; - this_array[2] = (INDIVIDUAL_AXIS)((int)this_array[2] & (int)((int)PZ+(int)PY)); - this_array[2] = (INDIVIDUAL_AXIS)((int)this_array[2] | - ((int)zero_bits[0][2] ^ - (int)zero_bits[1][indexes[2]])); - } - - // write_back_axis_array converts an array of three INDIVIDUAL_AXIS values - // to the ATR enum value and sets 'this' to that value - inline void axis_transformation::write_back_axis_array(const INDIVIDUAL_AXIS this_array[]) { - int bit5 = ((int)this_array[2] & 2) != 0; - int bit4 = !((((int)this_array[2] & 4) != 0) | (((int)this_array[2] & 2) != 0)); - int bit3 = ((int)this_array[2] & 1) != 0; - //bit 2 is the tricky bit - int bit2 = ((!(bit5 | bit4)) & (((int)this_array[0] & 2) != 0)) | //swap xy - (bit5 & (((int)this_array[0] & 4) >> 2)) | //z->y x->z - (bit4 & (((int)this_array[1] & 4) >> 2)); //z->x y->z - int bit1 = ((int)this_array[1] & 1); - int bit0 = ((int)this_array[0] & 1); - atr_ = ATR((bit5 << 5) + - (bit4 << 4) + - (bit3 << 3) + - (bit2 << 2) + - (bit1 << 1) + bit0); - } - - // behavior is deterministic but undefined in the case where illegal - // combinations of directions are passed in. - inline axis_transformation& - axis_transformation::set_directions(const direction_2d& horizontalDir, - const direction_2d& verticalDir){ - int bit2 = (static_cast<orientation_2d>(horizontalDir).to_int()) != 0; - int bit1 = !(verticalDir.to_int() & 1); - int bit0 = !(horizontalDir.to_int() & 1); - atr_ = ATR((bit2 << 2) + (bit1 << 1) + bit0); - return *this; - } - - // behavior is deterministic but undefined in the case where illegal - // combinations of directions are passed in. - inline axis_transformation& axis_transformation::set_directions(const direction_3d& horizontalDir, - const direction_3d& verticalDir, - const direction_3d& proximalDir){ - int this_array[3] = {horizontalDir.to_int(), - verticalDir.to_int(), - proximalDir.to_int()}; - int bit5 = (this_array[2] & 2) != 0; - int bit4 = !(((this_array[2] & 4) != 0) | ((this_array[2] & 2) != 0)); - int bit3 = !((this_array[2] & 1) != 0); - //bit 2 is the tricky bit - int bit2 = (!(bit5 | bit4) & ((this_array[0] & 2) != 0 )) | //swap xy - (bit5 & ((this_array[0] & 4) >> 2)) | //z->y x->z - (bit4 & ((this_array[1] & 4) >> 2)); //z->x y->z - int bit1 = !(this_array[1] & 1); - int bit0 = !(this_array[0] & 1); - atr_ = ATR((bit5 << 5) + - (bit4 << 4) + - (bit3 << 3) + - (bit2 << 2) + - (bit1 << 1) + bit0); - return *this; - } - - template <typename coordinate_type_2> - inline void axis_transformation::transform(coordinate_type_2& x, coordinate_type_2& 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); - } - - template <typename coordinate_type_2> - inline void axis_transformation::transform(coordinate_type_2& x, coordinate_type_2& y, coordinate_type_2& z) const { - int bit5 = (atr_ & 32) != 0; - int bit4 = (atr_ & 16) != 0; - int bit3 = (atr_ & 8) != 0; - int bit2 = (atr_ & 4) != 0; - int bit1 = (atr_ & 2) != 0; - int bit0 = (atr_ & 1) != 0; - x *= -((bit0 << 1) - 1); - y *= -((bit1 << 1) - 1); - z *= -((bit3 << 1) - 1); - predicated_swap(bit2 != 0, x, y); - predicated_swap(bit5 != 0, y, z); - predicated_swap(bit4 != 0, x, z); - } - - inline axis_transformation& axis_transformation::invert_2d() { - 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; - } - - inline axis_transformation axis_transformation::inverse_2d() const { - axis_transformation retval(*this); - return retval.invert_2d(); - } - - inline axis_transformation& axis_transformation::invert() { - int bit5 = ((atr_ & 32) != 0); - int bit4 = ((atr_ & 16) != 0); - int bit3 = ((atr_ & 8) != 0); - int bit2 = ((atr_ & 4) != 0); - int bit1 = ((atr_ & 2) != 0); - int bit0 = ((atr_ & 1) != 0); - predicated_swap(bit2 != 0, bit4, bit5); - predicated_swap(bit4 != 0, bit0, bit3); - predicated_swap(bit5 != 0, bit1, bit3); - predicated_swap(bit2 != 0, bit0, bit1); - atr_ = (ATR)((bit5 << 5) + - (bit4 << 4) + - (bit3 << 3) + - (bit2 << 2) + - (bit1 << 1) + bit0); - return *this; - } - - inline axis_transformation axis_transformation::inverse() const { - axis_transformation retval(*this); - return retval.invert(); - } - - template <typename scale_factor_type> - inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::get(orientation_3d orient) const { - return scale_[orient.to_int()]; - } - - template <typename scale_factor_type> - inline void anisotropic_scale_factor<scale_factor_type>::set(orientation_3d orient, scale_factor_type value) { - scale_[orient.to_int()] = value; - } - - template <typename scale_factor_type> - inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::x() const { return scale_[HORIZONTAL]; } - template <typename scale_factor_type> - inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::y() const { return scale_[VERTICAL]; } - template <typename scale_factor_type> - inline scale_factor_type anisotropic_scale_factor<scale_factor_type>::z() const { return scale_[PROXIMAL]; } - template <typename scale_factor_type> - inline void anisotropic_scale_factor<scale_factor_type>::x(scale_factor_type value) { scale_[HORIZONTAL] = value; } - template <typename scale_factor_type> - inline void anisotropic_scale_factor<scale_factor_type>::y(scale_factor_type value) { scale_[VERTICAL] = value; } - template <typename scale_factor_type> - inline void anisotropic_scale_factor<scale_factor_type>::z(scale_factor_type value) { scale_[PROXIMAL] = value; } - - //concatenation operator (convolve scale factors) - template <typename scale_factor_type> - inline anisotropic_scale_factor<scale_factor_type> anisotropic_scale_factor<scale_factor_type>::operator+(const anisotropic_scale_factor<scale_factor_type>& s) const { - anisotropic_scale_factor<scale_factor_type> retval(*this); - return retval+=s; - } - - //concatenate this with that - template <typename scale_factor_type> - inline const anisotropic_scale_factor<scale_factor_type>& anisotropic_scale_factor<scale_factor_type>::operator+=(const anisotropic_scale_factor<scale_factor_type>& s){ - scale_[0] *= s.scale_[0]; - scale_[1] *= s.scale_[1]; - scale_[2] *= s.scale_[2]; - return *this; - } - - //transform - template <typename scale_factor_type> - inline anisotropic_scale_factor<scale_factor_type>& anisotropic_scale_factor<scale_factor_type>::transform(axis_transformation atr){ - direction_3d dirs[3]; - atr.get_directions(dirs[0],dirs[1],dirs[2]); - scale_factor_type tmp[3] = {scale_[0], scale_[1], scale_[2]}; - for(int i = 0; i < 3; ++i){ - scale_[orientation_3d(dirs[i]).to_int()] = tmp[i]; - } - return *this; - } - - template <typename scale_factor_type> - template <typename coordinate_type_2> - inline void anisotropic_scale_factor<scale_factor_type>::scale(coordinate_type_2& x, coordinate_type_2& y) const { - x = scaling_policy<coordinate_type_2>::round((scale_factor_type)x * get(HORIZONTAL)); - y = scaling_policy<coordinate_type_2>::round((scale_factor_type)y * get(HORIZONTAL)); - } - - template <typename scale_factor_type> - template <typename coordinate_type_2> - inline void anisotropic_scale_factor<scale_factor_type>::scale(coordinate_type_2& x, coordinate_type_2& y, coordinate_type_2& z) const { - scale(x, y); - z = scaling_policy<coordinate_type_2>::round((scale_factor_type)z * get(HORIZONTAL)); - } - - template <typename scale_factor_type> - inline anisotropic_scale_factor<scale_factor_type>& anisotropic_scale_factor<scale_factor_type>::invert() { - x(1/x()); - y(1/y()); - z(1/z()); - return *this; - } - - - template <typename coordinate_type> - inline transformation<coordinate_type>::transformation() : atr_(), p_(0, 0, 0) {;} - - template <typename coordinate_type> - inline transformation<coordinate_type>::transformation(axis_transformation atr) : atr_(atr), p_(0, 0, 0){;} - - template <typename coordinate_type> - inline transformation<coordinate_type>::transformation(axis_transformation::ATR atr) : atr_(atr), p_(0, 0, 0){;} - - template <typename coordinate_type> - template <typename point_type> - inline transformation<coordinate_type>::transformation(const point_type& p) : atr_(), p_(0, 0, 0) { - set_translation(p); - } - - template <typename coordinate_type> - template <typename point_type> - inline transformation<coordinate_type>::transformation(axis_transformation atr, const point_type& p) : - atr_(atr), p_(0, 0, 0) { - set_translation(p); - } - - template <typename coordinate_type> - template <typename point_type> - inline transformation<coordinate_type>::transformation(axis_transformation atr, const point_type& referencePt, const point_type& destinationPt) : atr_(), p_(0, 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; - } - - template <typename coordinate_type> - inline transformation<coordinate_type>::transformation(const transformation<coordinate_type>& tr) : - atr_(tr.atr_), p_(tr.p_) {;} - - template <typename coordinate_type> - inline bool transformation<coordinate_type>::operator==(const transformation<coordinate_type>& tr) const { - return atr_ == tr.atr_ && p_ == tr.p_; - } - - template <typename coordinate_type> - inline bool transformation<coordinate_type>::operator!=(const transformation<coordinate_type>& tr) const { - return !(*this == tr); - } - - template <typename coordinate_type> - inline bool transformation<coordinate_type>::operator<(const transformation<coordinate_type>& tr) const { - return atr_ < tr.atr_ || atr_ == tr.atr_ && p_ < tr.p_; - } - - template <typename coordinate_type> - inline transformation<coordinate_type> transformation<coordinate_type>::operator+(const transformation<coordinate_type>& tr) const { - transformation<coordinate_type> retval(*this); - return retval+=tr; - } - - template <typename coordinate_type> - inline const transformation<coordinate_type>& transformation<coordinate_type>::operator+=(const transformation<coordinate_type>& tr){ - //apply the inverse transformation of this to the translation point of that - //and convolve it with this translation point - coordinate_type x, y, z; - transformation<coordinate_type> inv = inverse(); - inv.transform(x, y, z); - p_.set(HORIZONTAL, p_.get(HORIZONTAL) + x); - p_.set(VERTICAL, p_.get(VERTICAL) + y); - p_.set(PROXIMAL, p_.get(PROXIMAL) + z); - //concatenate axis transforms - atr_ += tr.atr_; - return *this; - } - - template <typename coordinate_type> - inline void transformation<coordinate_type>::set_axis_transformation(const axis_transformation& atr) { - atr_ = atr; - } - - template <typename coordinate_type> - template <typename point_type> - inline void transformation<coordinate_type>::get_translation(point_type& p) const { - assign(p, p_); - } - - template <typename coordinate_type> - template <typename point_type> - inline void transformation<coordinate_type>::set_translation(const point_type& p) { - assign(p_, p); - } - - template <typename coordinate_type> - inline void transformation<coordinate_type>::transform(coordinate_type& x, coordinate_type& y) const { - //subtract each component of new origin point - y -= p_.get(VERTICAL); - x -= p_.get(HORIZONTAL); - atr_.transform(x, y); - } - - template <typename coordinate_type> - inline void transformation<coordinate_type>::transform(coordinate_type& x, coordinate_type& y, coordinate_type& z) const { - //subtract each component of new origin point - z -= p_.get(PROXIMAL); - y -= p_.get(VERTICAL); - x -= p_.get(HORIZONTAL); - atr_.transform(x,y,z); - } - - // sets the axis_transform portion to its inverse - // transforms the tranlastion portion by that inverse axis_transform - // multiplies the translation portion by -1 to reverse it - template <typename coordinate_type> - inline transformation<coordinate_type>& transformation<coordinate_type>::invert() { - coordinate_type x = p_.get(HORIZONTAL), y = p_.get(VERTICAL), z = p_.get(PROXIMAL); - atr_.transform(x, y, z); - x *= -1; - y *= -1; - z *= -1; - p_ = point_3d_data<coordinate_type>(x, y, z); - atr_.invert(); - return *this; - } - - template <typename coordinate_type> - inline transformation<coordinate_type> transformation<coordinate_type>::inverse() const { - transformation<coordinate_type> retval(*this); - return retval.invert(); - } -} -} -#endif - - diff --git a/boost/polygon/detail/voronoi_ctypes.hpp b/boost/polygon/detail/voronoi_ctypes.hpp new file mode 100644 index 0000000000..d8580dda4e --- /dev/null +++ b/boost/polygon/detail/voronoi_ctypes.hpp @@ -0,0 +1,642 @@ +// 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 = (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_ = 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_ = 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/boost/polygon/detail/voronoi_predicates.hpp b/boost/polygon/detail/voronoi_predicates.hpp new file mode 100644 index 0000000000..783987972e --- /dev/null +++ b/boost/polygon/detail/voronoi_predicates.hpp @@ -0,0 +1,1532 @@ +// 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/boost/polygon/detail/voronoi_robust_fpt.hpp b/boost/polygon/detail/voronoi_robust_fpt.hpp new file mode 100644 index 0000000000..09da1a72f9 --- /dev/null +++ b/boost/polygon/detail/voronoi_robust_fpt.hpp @@ -0,0 +1,507 @@ +// 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/boost/polygon/detail/voronoi_structures.hpp b/boost/polygon/detail/voronoi_structures.hpp new file mode 100644 index 0000000000..f37a454e84 --- /dev/null +++ b/boost/polygon/detail/voronoi_structures.hpp @@ -0,0 +1,450 @@ +// 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/boost/polygon/gmp_override.hpp b/boost/polygon/gmp_override.hpp index 16cc96fc0a..322e05d02d 100644 --- a/boost/polygon/gmp_override.hpp +++ b/boost/polygon/gmp_override.hpp @@ -1,6 +1,6 @@ /* 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). @@ -25,14 +25,14 @@ namespace boost { namespace polygon { v_ = that; return (*this); } - inline operator int() const { + 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(); + return num.get_si(); } - inline double get_d() const { + inline double get_d() const { return v_.get_d(); } inline int get_num() const { @@ -109,7 +109,7 @@ namespace boost { namespace polygon { private: mpq_class v_; }; - + template <> struct high_precision_type<int> { typedef mpq_class type; @@ -120,10 +120,9 @@ namespace boost { namespace polygon { mpz_class num = v.get_num(); mpz_class den = v.get_den(); num /= den; - return num.get_si(); + return num.get_si(); }; } } -//== #endif diff --git a/boost/polygon/gtl.hpp b/boost/polygon/gtl.hpp index cabbb63466..1fc1a574d4 100644 --- a/boost/polygon/gtl.hpp +++ b/boost/polygon/gtl.hpp @@ -1,6 +1,6 @@ /* 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). @@ -9,10 +9,12 @@ #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 @@ -21,7 +23,13 @@ #include "polygon.hpp" namespace gtl = boost::polygon; using namespace boost::polygon::operators; -#if __ICC -#pragma warning (default:1125) + +#ifdef WIN32 +#pragma warning (pop) #endif + +#ifdef __ICC +#pragma warning (pop) +#endif + #endif diff --git a/boost/polygon/interval_concept.hpp b/boost/polygon/interval_concept.hpp index 9fc5257e7f..3eeec0ffbb 100644 --- a/boost/polygon/interval_concept.hpp +++ b/boost/polygon/interval_concept.hpp @@ -1,592 +1,934 @@ -/* - 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). -*/ +// 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_data.hpp" #include "interval_traits.hpp" -namespace boost { namespace polygon{ - struct interval_concept {}; - - template <typename T> - struct is_interval_concept { typedef gtl_no type; }; - template <> - struct is_interval_concept<interval_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_mutable_interval_concept { typedef gtl_no type; }; - template <> - struct is_mutable_interval_concept<interval_concept> { typedef gtl_yes type; }; - - template <typename T, typename CT> - struct interval_coordinate_type_by_concept { typedef void type; }; - template <typename T> - struct interval_coordinate_type_by_concept<T, gtl_yes> { typedef typename interval_traits<T>::coordinate_type type; }; - - template <typename T> - struct interval_coordinate_type { - typedef typename interval_coordinate_type_by_concept< - T, typename is_interval_concept<typename geometry_concept<T>::type>::type>::type type; - }; +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); +} - template <typename T, typename CT> - struct interval_difference_type_by_concept { typedef void type; }; - template <typename T> - struct interval_difference_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename interval_traits<T>::coordinate_type>::coordinate_difference type; }; +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); +} - template <typename T> - struct interval_difference_type { - typedef typename interval_difference_type_by_concept< - T, typename is_interval_concept<typename geometry_concept<T>::type>::type>::type type; - }; +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)); +} - template <typename T> - typename interval_coordinate_type<T>::type - get(const T& interval, direction_1d dir, - typename enable_if<typename gtl_if<typename is_interval_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0 - ) { - return interval_traits<T>::get(interval, dir); - } +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; +} - template <typename T, typename coordinate_type> - void - set(T& interval, direction_1d dir, coordinate_type value, - typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type * = 0 - ) { - //this may need to be refined - interval_mutable_traits<T>::set(interval, dir, value); - if(high(interval) < low(interval)) - interval_mutable_traits<T>::set(interval, dir.backward(), value); - } - - template <typename T, typename T2, typename T3> - T - construct(T2 low_value, T3 high_value, - typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type * = 0 - ) { - if(low_value > high_value) std::swap(low_value, high_value); - return interval_mutable_traits<T>::construct(low_value, high_value); - } - - template <typename T, typename T2> - T - copy_construct(const T2& interval, - typename enable_if< typename gtl_and<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0 - ) { - return construct<T> - (get(interval, LOW ), - get(interval, HIGH)); - } +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); +} - template <typename T1, typename T2> - T1 & - assign(T1& lvalue, const T2& rvalue, - typename enable_if< typename gtl_and< typename is_mutable_interval_concept<typename geometry_concept<T1>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0) { - lvalue = copy_construct<T1>(rvalue); - return lvalue; - } +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); +} - template <typename T, typename T2> - bool - equivalence(const T& interval1, const T2& interval2, - typename enable_if< typename gtl_and< typename is_interval_concept<typename geometry_concept<T>::type>::type, - typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0 - ) { - return get(interval1, LOW) == - get(interval2, LOW) && - get(interval1, HIGH) == - get(interval2, HIGH); - } - - struct y_i_contains : gtl_yes {}; - - template <typename interval_type> - typename enable_if< typename gtl_and< y_i_contains, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type >::type, bool>::type - contains(const interval_type& interval, - typename interval_traits<interval_type>::coordinate_type value, - bool consider_touch = true ) { - if(consider_touch) { - return value <= high(interval) && value >= low(interval); - } else { - return value < high(interval) && value > low(interval); - } - } - - template <typename interval_type, typename interval_type_2> - bool - contains(const interval_type& interval, - const interval_type_2& value, bool consider_touch = true, - typename enable_if< typename gtl_and< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type>::type * = 0 - ) { - return contains(interval, get(value, LOW), consider_touch) && - contains(interval, get(value, HIGH), consider_touch); - } - - // get the low coordinate - template <typename interval_type> - typename interval_traits<interval_type>::coordinate_type - low(const interval_type& interval, - typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0 - ) { return get(interval, LOW); } - - // get the high coordinate - template <typename interval_type> - typename interval_traits<interval_type>::coordinate_type - high(const interval_type& interval, - typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0 - ) { return get(interval, HIGH); } - - // get the center coordinate - template <typename interval_type> - typename interval_traits<interval_type>::coordinate_type - center(const interval_type& interval, - typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0 - ) { return (high(interval) + low(interval))/2; } - - - struct y_i_low : gtl_yes {}; - - // set the low coordinate to v - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_low, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, void>::type - low(interval_type& interval, - typename interval_traits<interval_type>::coordinate_type v) { set(interval, LOW, v); } - - struct y_i_high : gtl_yes {}; - - // set the high coordinate to v - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_high, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, void>::type - high(interval_type& interval, - typename interval_traits<interval_type>::coordinate_type v) { set(interval, HIGH, v); } - - // get the magnitude of the interval - template <typename interval_type> - typename interval_difference_type<interval_type>::type - delta(const interval_type& interval, - typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0 - ) { - typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference diffT; - return (diffT)high(interval) - (diffT)low(interval); } - - struct y_i_flip : gtl_yes {}; - - // flip this about coordinate - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_flip, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type & - flip(interval_type& interval, - typename interval_traits<interval_type>::coordinate_type axis = 0) { - typename interval_traits<interval_type>::coordinate_type newLow, newHigh; - newLow = 2 * axis - high(interval); - newHigh = 2 * axis - low(interval); - low(interval, newLow); - high(interval, newHigh); - return interval; - } +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_scale_up : gtl_yes {}; - - // scale interval by factor - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_scale_up, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type & - scale_up(interval_type& interval, - typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newHigh = high(interval) * (Unit)factor; - low(interval, low(interval) * (Unit)factor); - high(interval, (newHigh)); - return interval; - } +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_scale_down : gtl_yes {}; - - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_scale_down, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type & - scale_down(interval_type& interval, - typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - typedef typename coordinate_traits<Unit>::coordinate_distance dt; - Unit newHigh = scaling_policy<Unit>::round((dt)(high(interval)) / (dt)factor); - low(interval, scaling_policy<Unit>::round((dt)(low(interval)) / (dt)factor)); - high(interval, (newHigh)); - return interval; - } +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_scale : gtl_yes {}; +struct y_i_contains : gtl_yes {}; - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_scale, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type & - scale(interval_type& interval, double factor) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newHigh = scaling_policy<Unit>::round((double)(high(interval)) * factor); - low(interval, scaling_policy<Unit>::round((double)low(interval)* factor)); - high(interval, (newHigh)); - return interval; - } - - // move interval by delta - template <typename interval_type> - interval_type& - move(interval_type& interval, - typename interval_difference_type<interval_type>::type displacement, - typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0 - ) { - typedef typename interval_traits<interval_type>::coordinate_type ctype; - typedef typename coordinate_traits<ctype>::coordinate_difference Unit; - Unit len = delta(interval); - low(interval, static_cast<ctype>(static_cast<Unit>(low(interval)) + displacement)); - high(interval, static_cast<ctype>(static_cast<Unit>(low(interval)) + len)); - return interval; - } - - struct y_i_convolve : gtl_yes {}; - - // convolve this with b - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_convolve, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type & - convolve(interval_type& interval, - typename interval_traits<interval_type>::coordinate_type b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newLow = low(interval) + b; - Unit newHigh = high(interval) + b; - low(interval, newLow); - high(interval, newHigh); - return interval; +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_deconvolve : gtl_yes {}; - - // deconvolve this with b - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_deconvolve, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type & - deconvolve(interval_type& interval, - typename interval_traits<interval_type>::coordinate_type b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newLow = low(interval) - b; - Unit newHigh = high(interval) - b; - low(interval, newLow); - high(interval, newHigh); - return 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_convolve2 : gtl_yes {}; - - // convolve this with b - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_convolve2, - typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - interval_type>::type & - convolve(interval_type& interval, - const interval_type_2& b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newLow = low(interval) + low(b); - Unit newHigh = high(interval) + high(b); - low(interval, newLow); - high(interval, newHigh); - return interval; - } - - struct y_i_deconvolve2 : gtl_yes {}; - - // deconvolve this with b - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3< y_i_deconvolve2, - typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - interval_type>::type & - deconvolve(interval_type& interval, - const interval_type_2& b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newLow = low(interval) - low(b); - Unit newHigh = high(interval) - high(b); - low(interval, newLow); - high(interval, newHigh); - return interval; - } - - struct y_i_reconvolve : gtl_yes {}; - - // reflected convolve this with b - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_reconvolve, - typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - interval_type>::type & - reflected_convolve(interval_type& interval, - const interval_type_2& b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newLow = low(interval) - high(b); - Unit newHigh = high(interval) - low(b); - low(interval, newLow); - high(interval, newHigh); - return interval; - } - - struct y_i_redeconvolve : gtl_yes {}; - - // reflected deconvolve this with b - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3< y_i_redeconvolve, - typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - interval_type>::type & - reflected_deconvolve(interval_type& interval, - const interval_type_2& b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit newLow = low(interval) + high(b); - Unit newHigh = high(interval) + low(b); - low(interval, newLow); - high(interval, newHigh); - return interval; - } - - struct y_i_e_dist1 : gtl_yes {}; - - // distance from a coordinate to an interval - template <typename interval_type> - typename enable_if< typename gtl_and<y_i_e_dist1, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - typename interval_difference_type<interval_type>::type>::type - euclidean_distance(const interval_type& interval, - typename interval_traits<interval_type>::coordinate_type position) { - typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference 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_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_e_dist2 : gtl_yes {}; - - // distance between two intervals - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_e_dist2, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - typename interval_difference_type<interval_type>::type>::type - euclidean_distance(const interval_type& interval, - const interval_type_2& b) { - typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference Unit; - Unit dist[3] = {0, (Unit)low(interval) - (Unit)high(b), (Unit)low(b) - (Unit)high(interval)}; - return dist[ (dist[1] > 0) + ((dist[2] > 0) << 1) ]; - } - - struct y_i_e_intersects : gtl_yes {}; - - // check if Interval b intersects `this` Interval - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_e_intersects, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - bool>::type - intersects(const interval_type& interval, const interval_type_2& b, - bool consider_touch = true) { - return consider_touch ? - (low(interval) <= high(b)) & (high(interval) >= low(b)) : - (low(interval) < high(b)) & (high(interval) > low(b)); - } +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_e_bintersect : gtl_yes {}; - - // check if Interval b partially overlaps `this` Interval - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_e_bintersect, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - bool>::type - boundaries_intersect(const interval_type& interval, const interval_type_2& b, - bool consider_touch = true) { - return (contains(interval, low(b), consider_touch) || - contains(interval, high(b), consider_touch)) && - (contains(b, low(interval), consider_touch) || - contains(b, high(interval), consider_touch)); - } +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_abuts1 : gtl_yes {}; +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; +} - // check if they are end to end - template <typename interval_type, typename interval_type_2> - typename enable_if< typename gtl_and_3<y_i_abuts1, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - bool>::type - abuts(const interval_type& interval, const interval_type_2& b, direction_1d dir) { - return dir.to_int() ? low(b) == high(interval) : low(interval) == high(b); - } +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; +} - struct y_i_abuts2 : gtl_yes {}; - - // check if they are end to end - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_abuts2, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - bool>::type - abuts(const interval_type& interval, const interval_type_2& b) { - return abuts(interval, b, HIGH) || abuts(interval, b, LOW); - } - - struct y_i_intersect : gtl_yes {}; - - // set 'this' interval to the intersection of 'this' and b - template <typename interval_type, typename interval_type_2> - typename enable_if< typename gtl_and_3<y_i_intersect, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - bool>::type - intersect(interval_type& interval, const interval_type_2& b, bool consider_touch = true) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit lowVal = (std::max)(low(interval), low(b)); - Unit highVal = (std::min)(high(interval), high(b)); - bool valid = consider_touch ? - lowVal <= highVal : - lowVal < highVal; - if(valid) { - low(interval, lowVal); - high(interval, highVal); - } - return valid; - } +// 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_g_intersect : gtl_yes {}; - - // set 'this' interval to the generalized intersection of 'this' and b - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_g_intersect, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - interval_type>::type & - generalized_intersect(interval_type& interval, const interval_type_2& b) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit coords[4] = {low(interval), high(interval), low(b), high(b)}; - //consider implementing faster sorting of small fixed length range - gtlsort(coords, coords+4); - low(interval, coords[1]); - high(interval, coords[2]); - 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_bloat : gtl_yes {}; +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; +} - // bloat the Interval - template <typename interval_type> - typename enable_if< typename gtl_and<y_i_bloat, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - interval_type>::type & - bloat(interval_type& interval, typename interval_traits<interval_type>::coordinate_type bloating) { - low(interval, low(interval)-bloating); - high(interval, high(interval)+bloating); - return interval; - } - - struct y_i_bloat2 : gtl_yes {}; - - // bloat the specified side of `this` Interval - template <typename interval_type> - typename enable_if< typename gtl_and<y_i_bloat2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - interval_type>::type & - bloat(interval_type& interval, direction_1d dir, typename interval_traits<interval_type>::coordinate_type bloating) { - set(interval, dir, get(interval, dir) + dir.get_sign() * bloating); - 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_shrink : gtl_yes {}; +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; +} - // shrink the Interval - template <typename interval_type> - typename enable_if< typename gtl_and<y_i_shrink, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - interval_type>::type & - shrink(interval_type& interval, typename interval_traits<interval_type>::coordinate_type shrinking) { - return bloat(interval, -shrinking); - } +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_shrink2 : gtl_yes {}; +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; +} - // shrink the specified side of `this` Interval - template <typename interval_type> - typename enable_if< typename gtl_and<y_i_shrink2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - interval_type>::type & - shrink(interval_type& interval, direction_1d dir, typename interval_traits<interval_type>::coordinate_type shrinking) { - return bloat(interval, dir, -shrinking); - } +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)]; +} - // Enlarge `this` Interval to encompass the specified Interval - template <typename interval_type, typename interval_type_2> +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 - encompass(interval_type& interval, const interval_type_2& b, - typename enable_if< - typename gtl_and< typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type>::type * = 0 - ) { - bool retval = !contains(interval, b, true); - low(interval, (std::min)(low(interval), low(b))); - high(interval, (std::max)(high(interval), high(b))); - return retval; - } - - struct y_i_encompass : gtl_yes {}; - - // Enlarge `this` Interval to encompass the specified Interval - template <typename interval_type> - typename enable_if< typename gtl_and<y_i_encompass, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, - bool>::type - encompass(interval_type& interval, typename interval_traits<interval_type>::coordinate_type b) { - bool retval = !contains(interval, b, true); - low(interval, (std::min)(low(interval), b)); - high(interval, (std::max)(high(interval), b)); - return retval; - } - - struct y_i_get_half : gtl_yes {}; - - // gets the half of the interval as an interval - template <typename interval_type> - typename enable_if<typename gtl_and<y_i_get_half, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type - get_half(const interval_type& interval, direction_1d d1d) { - typedef typename interval_traits<interval_type>::coordinate_type Unit; - Unit c = (get(interval, LOW) + get(interval, HIGH)) / 2; - return construct<interval_type>((d1d == LOW) ? get(interval, LOW) : c, - (d1d == LOW) ? c : get(interval, HIGH)); - } +>::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_join_with : gtl_yes {}; - - // returns true if the 2 intervals exactly touch at one value, like in l1 <= h1 == l2 <= h2 - // sets the argument to the joined interval - template <typename interval_type, typename interval_type_2> - typename enable_if< - typename gtl_and_3<y_i_join_with, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type, - typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type, - bool>::type - join_with(interval_type& interval, const interval_type_2& b) { - if(abuts(interval, b)) { - encompass(interval, b); - return true; - } - return false; - } +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)); +} - template <class T> - template <class T2> - interval_data<T>& interval_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } +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; +} - template <typename T> - struct geometry_concept<interval_data<T> > { - typedef interval_concept type; - }; +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; } -#endif + +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/boost/polygon/interval_data.hpp b/boost/polygon/interval_data.hpp index cf2aabf402..b297624dc2 100644 --- a/boost/polygon/interval_data.hpp +++ b/boost/polygon/interval_data.hpp @@ -1,67 +1,118 @@ -/* - 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). -*/ +// 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" -namespace boost { namespace polygon{ - template <typename T> - class interval_data { - public: - typedef T coordinate_type; - inline interval_data() -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - {} - inline interval_data(coordinate_type low, coordinate_type high) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { - coords_[LOW] = low; coords_[HIGH] = high; - } - inline interval_data(const interval_data& that) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { - (*this) = that; - } - inline interval_data& operator=(const interval_data& that) { - coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this; - } - template <typename T2> - inline interval_data& operator=(const T2& rvalue); - inline coordinate_type get(direction_1d dir) const { - return coords_[dir.to_int()]; - } - inline coordinate_type low() const { return coords_[0]; } - inline coordinate_type high() const { return coords_[1]; } - inline bool operator==(const interval_data& that) const { - return low() == that.low() && high() == that.high(); } - inline bool operator!=(const interval_data& that) const { - return low() != that.low() || high() != that.high(); } - inline bool operator<(const interval_data& that) const { - if(coords_[0] < that.coords_[0]) return true; - if(coords_[0] > that.coords_[0]) return false; - if(coords_[1] < that.coords_[1]) return true; - return false; +#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]; } - inline bool operator<=(const interval_data& that) const { return !(that < *this); } - inline bool operator>(const interval_data& that) const { return that < *this; } - inline bool operator>=(const interval_data& that) const { return !((*this) < that); } - inline void set(direction_1d dir, coordinate_type value) { - coords_[dir.to_int()] = value; - } -private: - coordinate_type coords_[2]; + 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]; }; -} -} -#endif +template <typename CType> +struct geometry_concept< interval_data<CType> > { + typedef interval_concept type; +}; +} // polygon +} // boost + +#endif // BOOST_POLYGON_INTERVAL_DATA_HPP diff --git a/boost/polygon/interval_traits.hpp b/boost/polygon/interval_traits.hpp index a7d74efcda..9c9062f456 100644 --- a/boost/polygon/interval_traits.hpp +++ b/boost/polygon/interval_traits.hpp @@ -1,33 +1,47 @@ -/* - 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). -*/ +// 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 -namespace boost { namespace polygon{ - template <typename T> - struct interval_traits { - typedef typename T::coordinate_type coordinate_type; - - static inline coordinate_type get(const T& interval, direction_1d dir) { - return interval.get(dir); - } - }; - - template <typename T> - struct interval_mutable_traits { - static inline void set(T& interval, direction_1d dir, typename interval_traits<T>::coordinate_type value) { - interval.set(dir, value); - } - static inline T construct(typename interval_traits<T>::coordinate_type low_value, - typename interval_traits<T>::coordinate_type high_value) { - return T(low_value, high_value); - } - }; -} -} -#endif +#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/boost/polygon/isotropy.hpp b/boost/polygon/isotropy.hpp index 055707c3e8..890595e35d 100644 --- a/boost/polygon/isotropy.hpp +++ b/boost/polygon/isotropy.hpp @@ -1,6 +1,6 @@ /* 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). @@ -26,7 +26,7 @@ #ifndef BOOST_POLYGON_NO_DEPS -#include <boost/config.hpp> +#include <boost/config.hpp> #ifdef BOOST_MSVC #define BOOST_POLYGON_MSVC #endif @@ -58,7 +58,7 @@ typedef boost::ulong_long_type polygon_ulong_long_type; typedef long long polygon_long_long_type; typedef unsigned long long polygon_ulong_long_type; - namespace boost { + namespace boost { template <bool B, class T = void> struct enable_if_c { typedef T type; @@ -67,7 +67,7 @@ typedef unsigned long long polygon_ulong_long_type; template <class T> struct enable_if_c<false, T> {}; - template <class Cond, class T = void> + template <class Cond, class T = void> struct enable_if : public enable_if_c<Cond::value, T> {}; template <bool B, class T> @@ -78,7 +78,7 @@ typedef unsigned long long polygon_ulong_long_type; template <class T> struct lazy_enable_if_c<false, T> {}; - template <class Cond, class T> + template <class Cond, class T> struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {}; @@ -90,7 +90,7 @@ typedef unsigned long long polygon_ulong_long_type; template <class T> struct disable_if_c<true, T> {}; - template <class Cond, class T = void> + template <class Cond, class T = void> struct disable_if : public disable_if_c<Cond::value, T> {}; template <bool B, class T> @@ -101,7 +101,7 @@ typedef unsigned long long polygon_ulong_long_type; template <class T> struct lazy_disable_if_c<true, T> {}; - template <class Cond, class T> + template <class Cond, class T> struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {}; } @@ -129,17 +129,18 @@ namespace boost { namespace polygon{ struct undefined_concept {}; template <typename T> - struct geometry_concept { typedef undefined_concept type; }; + 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); } + view_of<T1, T2> view_as(const T2& obj) { return view_of<T1, T2>(obj); } template <typename T> struct coordinate_traits {}; + //used to override long double with an infinite precision datatype template <typename T> struct high_precision_type { typedef long double type; @@ -150,6 +151,14 @@ namespace boost { namespace polygon{ 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; @@ -314,13 +323,13 @@ namespace boost { namespace polygon{ 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> { + 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 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 @@ -383,7 +392,7 @@ namespace boost { namespace polygon{ 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) { + 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); } @@ -426,7 +435,7 @@ namespace boost { namespace polygon{ 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) { @@ -489,7 +498,7 @@ namespace boost { namespace polygon{ 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) { + 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_); } @@ -507,7 +516,7 @@ namespace boost { namespace polygon{ 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) {} @@ -551,4 +560,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/point_3d_concept.hpp b/boost/polygon/point_3d_concept.hpp deleted file mode 100644 index ab7afeb981..0000000000 --- a/boost/polygon/point_3d_concept.hpp +++ /dev/null @@ -1,270 +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 GLT_POINT_3D_CONCEPT_HPP -#define GLT_POINT_3D_CONCEPT_HPP -#include "point_concept.hpp" -#include "point_3d_data.hpp" -#include "point_3d_traits.hpp" -namespace boost { namespace polygon{ - struct point_3d_concept {}; - - template <typename T> - struct is_point_3d_concept { typedef gtl_no type; }; - template <> - struct is_point_3d_concept<point_3d_concept> { typedef gtl_yes type; }; - //template <> - //struct is_point_concept<point_3d_concept> { typedef void type; }; - - template <typename T> - struct is_mutable_point_3d_concept { typedef gtl_no type; }; - template <> - struct is_mutable_point_3d_concept<point_3d_concept> { typedef gtl_yes type; }; - - template <typename T, typename CT> - struct point_3d_coordinate_type_by_concept { typedef void type; }; - template <typename T> - struct point_3d_coordinate_type_by_concept<T, gtl_yes> { typedef typename point_3d_traits<T>::coordinate_type type; }; - - template <typename T> - struct point_3d_coordinate_type { - typedef typename point_3d_coordinate_type_by_concept<T, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct point_3d_difference_type_by_concept { typedef void type; }; - template <typename T> - struct point_3d_difference_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename point_3d_traits<T>::coordinate_type>::coordinate_difference type; }; - - template <typename T> - struct point_3d_difference_type { - typedef typename point_3d_difference_type_by_concept< - T, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct point_3d_distance_type_by_concept { typedef void type; }; - template <typename T> - struct point_3d_distance_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename point_3d_traits<T>::coordinate_type>::coordinate_distance type; }; - - template <typename T> - struct point_3d_distance_type { - typedef typename point_3d_distance_type_by_concept< - T, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - struct y_p3d_get : gtl_yes {}; - - template <typename T> - typename enable_if< typename gtl_and<y_p3d_get, typename gtl_if<typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type>::type, - typename point_3d_coordinate_type<T>::type >::type - get(const T& point, orientation_3d orient) { return point_3d_traits<T>::get(point, orient); } - - struct y_p3d_set : gtl_yes {}; - - template <typename T, typename coordinate_type> - typename enable_if< typename gtl_and<y_p3d_set, typename is_mutable_point_3d_concept<typename geometry_concept<T>::type>::type>::type, void>::type - set(T& point, orientation_3d orient, coordinate_type value) { point_3d_mutable_traits<T>::set(point, orient, value); } - - struct y_p3d_set2 : gtl_yes {}; - - template <typename T, typename coordinate_type> - typename enable_if< typename gtl_and<y_p3d_set2, typename is_mutable_point_3d_concept<typename geometry_concept<T>::type>::type>::type, void>::type - set(T& point, orientation_2d orient, coordinate_type value) { point_3d_mutable_traits<T>::set(point, orient, value); } - - struct y_p3d_construct : gtl_yes {}; - - template <typename T, typename coordinate_type1, typename coordinate_type2, typename coordinate_type3> - typename enable_if< typename gtl_and<y_p3d_construct, typename is_mutable_point_3d_concept<typename geometry_concept<T>::type>::type>::type, T>::type - construct(coordinate_type1 x_value, coordinate_type2 y_value, coordinate_type3 z_value) { - return point_3d_mutable_traits<T>::construct(x_value, y_value, z_value); } - - struct y_p3d_assign : gtl_yes {}; - - template <typename point_3d_type_1, typename point_3d_type_2> - typename enable_if< - typename gtl_and_3<y_p3d_assign, typename is_mutable_point_3d_concept<typename geometry_concept<point_3d_type_1>::type>::type, - typename is_point_3d_concept<typename geometry_concept<point_3d_type_2>::type>::type>::type, - point_3d_type_1>::type & - assign(point_3d_type_1& lvalue, const point_3d_type_2& rvalue) { - set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); - set(lvalue, VERTICAL, get(rvalue, VERTICAL)); - set(lvalue, PROXIMAL, get(rvalue, PROXIMAL)); - return lvalue; - } - - struct y_p3d_z : gtl_yes {}; - - template <typename point_type> - typename enable_if< typename gtl_and<y_p3d_z, typename is_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, - typename point_3d_traits<point_type>::coordinate_type >::type - z(const point_type& point) { return get(point, PROXIMAL); } - - struct y_p3d_x : gtl_yes {}; - - template <typename point_type, typename coordinate_type> - typename enable_if< typename gtl_and<y_p3d_x, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type - x(point_type& point, coordinate_type value) { set(point, HORIZONTAL, value); } - - struct y_p3d_y : gtl_yes {}; - - template <typename point_type, typename coordinate_type> - typename enable_if< typename gtl_and<y_p3d_y, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type - y(point_type& point, coordinate_type value) { set(point, VERTICAL, value); } - - struct y_p3d_z2 : gtl_yes {}; - - template <typename point_type, typename coordinate_type> - typename enable_if< typename gtl_and<y_p3d_z2, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type - z(point_type& point, coordinate_type value) { set(point, PROXIMAL, value); } - - struct y_p3d_equiv : gtl_yes {}; - - template <typename T, typename T2> - typename enable_if< - typename gtl_and_3<y_p3d_equiv, typename gtl_same_type<point_3d_concept, typename geometry_concept<T>::type>::type, - typename gtl_same_type<point_3d_concept, typename geometry_concept<T2>::type>::type>::type, - bool>::type - equivalence(const T& point1, const T2& point2) { - return x(point1) == x(point2) && y(point1) == y(point2) && z(point1) == z(point2); - } - - struct y_p3d_dist : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_3<y_p3d_dist, typename is_point_3d_concept<typename geometry_concept<point_type_1>::type>::type, - typename is_point_3d_concept<typename geometry_concept<point_type_2>::type>::type>::type, - typename point_3d_difference_type<point_type_1>::type>::type - euclidean_distance(const point_type_1& point1, const point_type_2& point2, orientation_3d orient) { - typedef typename coordinate_traits<typename point_3d_traits<point_type_1>::coordinate_type>::coordinate_difference return_type; - return_type return_value = - (return_type)get(point1, orient) - (return_type)get(point2, orient); - return return_value < 0 ? -return_value : return_value; - } - - struct y_p3d_man_dist : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_3<y_p3d_man_dist, typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_1>::type>::type, - typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type, - typename point_3d_difference_type<point_type_1>::type>::type - manhattan_distance(const point_type_1& point1, const point_type_2& point2) { - return euclidean_distance(point1, point2, HORIZONTAL) + euclidean_distance(point1, point2, VERTICAL) - + euclidean_distance(point1, point2, PROXIMAL); - } - - struct y_p3d_dist2 : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_3< y_p3d_dist2, - typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_1>::type>::type, - typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type, - typename point_3d_distance_type<point_type_1>::type>::type - euclidean_distance(const point_type_1& point1, const point_type_2& point2) { - typedef typename coordinate_traits<typename point_3d_traits<point_type_1>::coordinate_type>::coordinate_distance return_value; - return_value pdist = (return_value)euclidean_distance(point1, point2, PROXIMAL); - pdist *= pdist; - return sqrt((double)(distance_squared(point1, point2) + pdist)); - } - - struct y_p3d_convolve : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_3< y_p3d_convolve, - typename is_mutable_point_3d_concept<typename geometry_concept<point_type_1>::type>::type, - typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type, - point_type_1>::type & - convolve(point_type_1& lvalue, const point_type_2& rvalue) { - x(lvalue, x(lvalue) + x(rvalue)); - y(lvalue, y(lvalue) + y(rvalue)); - z(lvalue, z(lvalue) + z(rvalue)); - return lvalue; - } - - struct y_p3d_deconvolve : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< - typename gtl_and_3<y_p3d_deconvolve, typename is_mutable_point_3d_concept<typename geometry_concept<point_type_1>::type>::type, - typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type, - point_type_1>::type & - deconvolve(point_type_1& lvalue, const point_type_2& rvalue) { - x(lvalue, x(lvalue) - x(rvalue)); - y(lvalue, y(lvalue) - y(rvalue)); - z(lvalue, z(lvalue) - z(rvalue)); - return lvalue; - } - - struct y_p3d_scale_up : gtl_yes {}; - - template <typename point_type> - typename enable_if< typename gtl_and<y_p3d_scale_up, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, - point_type>::type & - scale_up(point_type& point, - typename coordinate_traits<typename point_3d_traits<point_type>::coordinate_type>::unsigned_area_type factor) { - x(point, x(point) * (typename point_3d_traits<point_type>::coordinate_type)factor); - y(point, y(point) * (typename point_3d_traits<point_type>::coordinate_type)factor); - z(point, z(point) * (typename point_3d_traits<point_type>::coordinate_type)factor); - return point; - } - - struct y_p3d_scale_down : gtl_yes {}; - - template <typename point_type> - typename enable_if< typename gtl_and<y_p3d_scale_down, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, - point_type>::type & - scale_down(point_type& point, - typename coordinate_traits<typename point_3d_traits<point_type>::coordinate_type>::unsigned_area_type factor) { - typedef typename point_3d_traits<point_type>::coordinate_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)); - z(point, scaling_policy<Unit>::round((dt)(z(point)) / (dt)factor)); - return point; - } - - struct y_p3d_scale : gtl_yes {}; - - template <typename point_type, typename scaling_type> - typename enable_if< typename gtl_and<y_p3d_scale, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, - point_type>::type & - scale(point_type& point, - const scaling_type& scaling) { - typedef typename point_3d_traits<point_type>::coordinate_type Unit; - Unit x_(x(point)), y_(y(point)), z_(z(point)); - scaling.scale(x_, y_, z_); - x(point, x_); - y(point, y_); - z(point, z_); - return point; - } - - struct y_p3d_transform : gtl_yes {}; - - template <typename point_type, typename transformation_type> - typename enable_if< typename gtl_and<y_p3d_transform, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, - point_type>::type & - transform(point_type& point, const transformation_type& transformation) { - typedef typename point_3d_traits<point_type>::coordinate_type Unit; - Unit x_(x(point)), y_(y(point)), z_(z(point)); - transformation.transform(x_, y_, z_); - x(point, x_); - y(point, y_); - z(point, z_); - return point; - } - - template <typename T> - struct geometry_concept<point_3d_data<T> > { - typedef point_3d_concept type; - }; -} -} -#endif - diff --git a/boost/polygon/point_3d_data.hpp b/boost/polygon/point_3d_data.hpp deleted file mode 100644 index c57097cea2..0000000000 --- a/boost/polygon/point_3d_data.hpp +++ /dev/null @@ -1,51 +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_POINT_3D_DATA_HPP -#define BOOST_POLYGON_POINT_3D_DATA_HPP -namespace boost { namespace polygon{ - template <typename T> - class point_3d_data { - public: - typedef T coordinate_type; - inline point_3d_data():coords_(){} - inline point_3d_data(coordinate_type x, coordinate_type y):coords_() { - coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; coords_[PROXIMAL] = 0; } - inline point_3d_data(coordinate_type x, coordinate_type y, coordinate_type z) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { - coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; coords_[PROXIMAL] = z; } - inline point_3d_data(const point_3d_data& that):coords_() { (*this) = that; } - inline point_3d_data& operator=(const point_3d_data& that) { - coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; - coords_[2] = that.coords_[2]; return *this; } - template <typename T2> - inline point_3d_data& operator=(const T2& rvalue); - inline bool operator==(const point_3d_data& that) const { - return coords_[0] == that.coords_[0] && coords_[1] == that.coords_[1] && coords_[2] == that.coords_[2]; - } - inline bool operator!=(const point_3d_data& that) const { - return !((*this) == that); - } - inline coordinate_type get(orientation_2d orient) const { - return coords_[orient.to_int()]; } - inline coordinate_type get(orientation_3d orient) const { - return coords_[orient.to_int()]; } - inline void set(orientation_2d orient, coordinate_type value) { - coords_[orient.to_int()] = value; } - inline void set(orientation_3d orient, coordinate_type value) { - coords_[orient.to_int()] = value; } - private: - coordinate_type coords_[3]; - }; -} -} -#endif - - diff --git a/boost/polygon/point_3d_traits.hpp b/boost/polygon/point_3d_traits.hpp deleted file mode 100644 index 9f6eb9a3c2..0000000000 --- a/boost/polygon/point_3d_traits.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 BOOST_POLYGON_POINT_3D_TRAITS_HPP -#define BOOST_POLYGON_POINT_3D_TRAITS_HPP - -#include "isotropy.hpp" - -namespace boost { namespace polygon{ - template <typename T> - struct point_3d_traits { - typedef typename T::coordinate_type coordinate_type; - - static inline coordinate_type get(const T& point, orientation_3d orient) { - return point.get(orient); } - }; - - template <typename T> - struct point_3d_mutable_traits { - static inline void set(T& point, orientation_3d orient, typename point_3d_traits<T>::coordinate_type value) { - point.set(orient, value); } - - static inline T construct(typename point_3d_traits<T>::coordinate_type x_value, - typename point_3d_traits<T>::coordinate_type y_value, - typename point_3d_traits<T>::coordinate_type z_value) { - return T(x_value, y_value, z_value); } - }; -} -} -#endif - diff --git a/boost/polygon/point_concept.hpp b/boost/polygon/point_concept.hpp index 6e2ce0a520..4d4c1dd207 100644 --- a/boost/polygon/point_concept.hpp +++ b/boost/polygon/point_concept.hpp @@ -1,298 +1,469 @@ -/* - 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). -*/ +// 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_data.hpp" #include "point_traits.hpp" -namespace boost { namespace polygon{ - struct point_concept {}; - - template <typename T> - struct is_point_concept { typedef gtl_no type; }; - template <> - struct is_point_concept<point_concept> { typedef gtl_yes type; }; - - struct point_3d_concept; - template <> - struct is_point_concept<point_3d_concept> { typedef gtl_yes type; }; - - template <typename T> - struct is_mutable_point_concept { typedef gtl_no type; }; - template <> - struct is_mutable_point_concept<point_concept> { typedef gtl_yes type; }; - - template <typename T, typename CT> - struct point_coordinate_type_by_concept { typedef void type; }; - template <typename T> - struct point_coordinate_type_by_concept<T, gtl_yes> { typedef typename point_traits<T>::coordinate_type type; }; - - template <typename T> - struct point_coordinate_type { - typedef typename point_coordinate_type_by_concept<T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct point_difference_type_by_concept { typedef void type; }; - template <typename T> - struct point_difference_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename point_traits<T>::coordinate_type>::coordinate_difference type; }; - - template <typename T> - struct point_difference_type { - typedef typename point_difference_type_by_concept< - T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T, typename CT> - struct point_distance_type_by_concept { typedef void type; }; - template <typename T> - struct point_distance_type_by_concept<T, gtl_yes> { - typedef typename coordinate_traits<typename point_traits<T>::coordinate_type>::coordinate_distance type; }; - - template <typename T> - struct point_distance_type { - typedef typename point_distance_type_by_concept< - T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type; - }; - - template <typename T> - typename point_coordinate_type<T>::type - get(const T& point, orientation_2d orient, - typename enable_if< typename gtl_if<typename is_point_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0 - ) { - return point_traits<T>::get(point, orient); - } - - template <typename T, typename coordinate_type> - void - set(T& point, orientation_2d orient, coordinate_type value, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type * = 0 - ) { - point_mutable_traits<T>::set(point, orient, value); - } - - template <typename T, typename coordinate_type1, typename coordinate_type2> - T - construct(coordinate_type1 x_value, coordinate_type2 y_value, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type * = 0 - ) { - return point_mutable_traits<T>::construct(x_value, y_value); - } - - template <typename T1, typename T2> - T1& - assign(T1& lvalue, const T2& rvalue, - typename enable_if< typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type, - typename is_point_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0 - ) { - set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); - set(lvalue, VERTICAL, get(rvalue, VERTICAL)); - return lvalue; - } - - struct y_p_x : gtl_yes {}; - - template <typename point_type> - typename enable_if< typename gtl_and<y_p_x, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - typename point_traits<point_type>::coordinate_type >::type - x(const point_type& point) { - return get(point, HORIZONTAL); - } - - struct y_p_y : gtl_yes {}; - - template <typename point_type> - typename enable_if< typename gtl_and<y_p_y, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, - typename point_traits<point_type>::coordinate_type >::type - y(const point_type& point) { - return get(point, VERTICAL); - } - - struct y_p_sx : gtl_yes {}; - - template <typename point_type, typename coordinate_type> - typename enable_if<typename gtl_and<y_p_sx, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, - void>::type - x(point_type& point, coordinate_type value) { - set(point, HORIZONTAL, value); - } - - struct y_p_sy : gtl_yes {}; - - template <typename point_type, typename coordinate_type> - typename enable_if<typename gtl_and<y_p_sy, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, - void>::type - y(point_type& point, coordinate_type value) { - set(point, VERTICAL, value); - } - - template <typename T, typename T2> - bool - equivalence(const T& point1, const T2& point2, - typename enable_if< typename gtl_and<typename gtl_same_type<point_concept, typename geometry_concept<T>::type>::type, - typename is_point_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0 - ) { - typename point_traits<T>::coordinate_type x1 = x(point1); - typename point_traits<T2>::coordinate_type x2 = get(point2, HORIZONTAL); - typename point_traits<T>::coordinate_type y1 = get(point1, VERTICAL); - typename point_traits<T2>::coordinate_type y2 = y(point2); - return x1 == x2 && y1 == y2; - } - - template <typename point_type_1, typename point_type_2> - typename point_difference_type<point_type_1>::type - manhattan_distance(const point_type_1& point1, const point_type_2& point2, - typename enable_if< typename gtl_and<typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type, - typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0) { - return euclidean_distance(point1, point2, HORIZONTAL) + euclidean_distance(point1, point2, VERTICAL); - } - - struct y_i_ed1 : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_3<y_i_ed1, 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, - typename point_difference_type<point_type_1>::type>::type - euclidean_distance(const point_type_1& point1, const point_type_2& point2, orientation_2d orient) { - typename coordinate_traits<typename point_traits<point_type_1>::coordinate_type>::coordinate_difference return_value = +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 return_value < 0 ? (typename coordinate_traits<typename point_traits<point_type_1>::coordinate_type>::coordinate_difference)-return_value : return_value; - } - - struct y_i_ed2 : gtl_yes {}; - - template <typename point_type_1, typename point_type_2> - typename enable_if< typename gtl_and_3<y_i_ed2, typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type, - typename gtl_same_type<point_concept, typename geometry_concept<point_type_2>::type>::type>::type, - typename point_distance_type<point_type_1>::type>::type - euclidean_distance(const point_type_1& point1, const point_type_2& point2) { - typedef typename point_traits<point_type_1>::coordinate_type Unit; - return sqrt((double)(distance_squared(point1, point2))); - } - - template <typename point_type_1, typename point_type_2> - typename point_difference_type<point_type_1>::type - distance_squared(const point_type_1& point1, const point_type_2& point2, - typename enable_if< typename gtl_and<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>::type * = 0 - ) { - typedef typename point_traits<point_type_1>::coordinate_type Unit; - typename coordinate_traits<Unit>::coordinate_difference dx = euclidean_distance(point1, point2, HORIZONTAL); - typename coordinate_traits<Unit>::coordinate_difference dy = euclidean_distance(point1, point2, VERTICAL); - dx *= dx; - dy *= dy; - return dx + dy; - } - - template <typename point_type_1, typename point_type_2> - point_type_1 & - convolve(point_type_1& lvalue, const point_type_2& rvalue, - typename enable_if< typename gtl_and<typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type, - typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0 - ) { - x(lvalue, x(lvalue) + x(rvalue)); - y(lvalue, y(lvalue) + y(rvalue)); - return lvalue; - } - - template <typename point_type_1, typename point_type_2> - point_type_1 & - deconvolve(point_type_1& lvalue, const point_type_2& rvalue, - typename enable_if< typename gtl_and<typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type, - typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0 - ) { - x(lvalue, x(lvalue) - x(rvalue)); - y(lvalue, y(lvalue) - y(rvalue)); - return lvalue; - } - - template <typename point_type, typename coord_type> - point_type & - scale_up(point_type& point, coord_type factor, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0 - ) { - typedef typename point_traits<point_type>::coordinate_type Unit; - x(point, x(point) * (Unit)factor); - y(point, y(point) * (Unit)factor); - return point; - } - - template <typename point_type, typename coord_type> - point_type & - scale_down(point_type& point, coord_type factor, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0 - ) { - typedef typename point_traits<point_type>::coordinate_type Unit; - typedef typename coordinate_traits<Unit>::coordinate_distance dt; - x(point, scaling_policy<Unit>::round((dt)((dt)(x(point)) / (dt)factor))); - y(point, scaling_policy<Unit>::round((dt)((dt)(y(point)) / (dt)factor))); - return point; - } - - template <typename point_type, typename scaling_type> - point_type & - scale(point_type& point, - const scaling_type& scaling, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0 - ) { - typedef typename point_traits<point_type>::coordinate_type Unit; - Unit x_(x(point)), y_(y(point)); - scaling.scale(x_, y_); - x(point, x_); - y(point, y_); - return point; - } - - template <typename point_type, typename transformation_type> - point_type & - transform(point_type& point, const transformation_type& transformation, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0 - ) { - typedef typename point_traits<point_type>::coordinate_type Unit; - Unit x_(x(point)), y_(y(point)); - transformation.transform(x_, y_); - x(point, x_); - y(point, y_); - return point; - } - - struct y_pt_move : gtl_yes {}; - - template <typename point_type> - typename enable_if< - typename gtl_and< y_pt_move, - typename is_mutable_point_concept< - typename geometry_concept<point_type>::type>::type>::type, - point_type>::type & - move(point_type& point, orientation_2d orient, - typename point_traits<point_type>::coordinate_type displacement, - typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0 - ) { - typedef typename point_traits<point_type>::coordinate_type Unit; - Unit v(get(point, orient)); - set(point, orient, v + displacement); - return point; - } - - template <class T> - template <class T2> - point_data<T>& point_data<T>::operator=(const T2& rvalue) { - assign(*this, rvalue); - return *this; - } - - template <typename T> - struct geometry_concept<point_data<T> > { - typedef point_concept type; - }; + 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; } -#endif +} // polygon +} // boost +#endif // BOOST_POLYGON_POINT_CONCEPT_HPP diff --git a/boost/polygon/point_data.hpp b/boost/polygon/point_data.hpp index d181b035d5..23c23ed2b0 100644 --- a/boost/polygon/point_data.hpp +++ b/boost/polygon/point_data.hpp @@ -1,105 +1,130 @@ -/* - 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 GTLPOINT_DATA_HPP -#define GTLPOINT_DATA_HPP +// 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{ +namespace boost { +namespace polygon { - template <typename T> - class point_data { - public: - typedef T coordinate_type; - inline point_data() -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - {} - inline point_data(coordinate_type x, coordinate_type y) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { - coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; - } - inline point_data(const point_data& that) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { (*this) = that; } - template <typename other> - point_data(const other& that) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { (*this) = that; } - inline point_data& operator=(const point_data& that) { - coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this; - } - template<typename T1, typename T2> - inline point_data(const T1& x, const T2& y) -#ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { - coords_[HORIZONTAL] = (coordinate_type)x; - coords_[VERTICAL] = (coordinate_type)y; - } - template <typename T2> - inline point_data(const point_data<T2>& rvalue) +template <typename T> +class point_data { + public: + typedef T coordinate_type; + + point_data() #ifndef BOOST_POLYGON_MSVC - :coords_() -#endif - { - coords_[HORIZONTAL] = (coordinate_type)(rvalue.x()); - coords_[VERTICAL] = (coordinate_type)(rvalue.y()); - } - template <typename T2> - inline point_data& operator=(const T2& rvalue); - inline bool operator==(const point_data& that) const { - return coords_[0] == that.coords_[0] && coords_[1] == that.coords_[1]; - } - inline bool operator!=(const point_data& that) const { - return !((*this) == that); - } - inline bool operator<(const point_data& that) const { - return coords_[0] < that.coords_[0] || - (coords_[0] == that.coords_[0] && coords_[1] < that.coords_[1]); - } - inline bool operator<=(const point_data& that) const { return !(that < *this); } - inline bool operator>(const point_data& that) const { return that < *this; } - inline bool operator>=(const point_data& that) const { return !((*this) < that); } - inline coordinate_type get(orientation_2d orient) const { - return coords_[orient.to_int()]; - } - inline void set(orientation_2d orient, coordinate_type value) { - coords_[orient.to_int()] = value; - } - inline coordinate_type x() const { - return coords_[HORIZONTAL]; - } - inline coordinate_type y() const { - return coords_[VERTICAL]; - } - inline point_data& x(coordinate_type value) { - coords_[HORIZONTAL] = value; - return *this; - } - inline point_data& y(coordinate_type value) { - coords_[VERTICAL] = value; - return *this; - } - private: - coordinate_type coords_[2]; - }; - -} -} + : 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; + } + + template <typename PointType> + point_data(const PointType& that) { + *this = that; + } + + 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/boost/polygon/point_traits.hpp b/boost/polygon/point_traits.hpp index 504fa355f5..5bc43d1514 100644 --- a/boost/polygon/point_traits.hpp +++ b/boost/polygon/point_traits.hpp @@ -1,35 +1,48 @@ -/* - 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). -*/ +// 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 T> - struct point_traits { - typedef typename T::coordinate_type coordinate_type; - - static inline coordinate_type get(const T& point, orientation_2d orient) { - return point.get(orient); - } - }; - - template <typename T> - struct point_mutable_traits { - static inline void set(T& point, orientation_2d orient, typename point_traits<T>::coordinate_type value) { - point.set(orient, value); - } - static inline T construct(typename point_traits<T>::coordinate_type x_value, typename point_traits<T>::coordinate_type y_value) { - return T(x_value, y_value); - } - }; -} -} -#endif +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/boost/polygon/polygon.hpp b/boost/polygon/polygon.hpp index 4c3e43a5eb..90a7c1f81a 100644 --- a/boost/polygon/polygon.hpp +++ b/boost/polygon/polygon.hpp @@ -1,6 +1,6 @@ /* 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). @@ -16,13 +16,7 @@ #include "point_traits.hpp" #include "point_concept.hpp" -//point 3d -#include "point_3d_data.hpp" -#include "point_3d_traits.hpp" -#include "point_3d_concept.hpp" - #include "transform.hpp" -#include "detail/transform_detail.hpp" //interval #include "interval_data.hpp" @@ -34,6 +28,11 @@ #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" @@ -88,4 +87,6 @@ #include "polygon_set_concept.hpp" +#include "segment_utils.hpp" + #endif diff --git a/boost/polygon/polygon_45_data.hpp b/boost/polygon/polygon_45_data.hpp index 86753ec13e..cdd5c2498b 100644 --- a/boost/polygon/polygon_45_data.hpp +++ b/boost/polygon/polygon_45_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -34,7 +34,7 @@ public: // 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_; @@ -63,11 +63,10 @@ public: inline std::size_t size() const { return coords_.size(); } public: - std::vector<point_data<coordinate_type> > coords_; + std::vector<point_data<coordinate_type> > coords_; }; } } #endif - diff --git a/boost/polygon/polygon_45_set_concept.hpp b/boost/polygon/polygon_45_set_concept.hpp index f22910cb90..623415fb59 100644 --- a/boost/polygon/polygon_45_set_concept.hpp +++ b/boost/polygon/polygon_45_set_concept.hpp @@ -1,6 +1,6 @@ /* 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). @@ -28,14 +28,14 @@ namespace boost { namespace polygon{ 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 @@ -79,9 +79,9 @@ namespace boost { namespace polygon{ 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, + typename gtl_if<typename is_either_polygon_45_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type>::type, - bool>::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; @@ -111,14 +111,14 @@ namespace boost { namespace polygon{ 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, + 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; @@ -181,7 +181,7 @@ namespace boost { namespace polygon{ 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, + 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); @@ -195,7 +195,7 @@ namespace boost { namespace polygon{ 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, + 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)); } @@ -203,7 +203,7 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -211,7 +211,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -233,7 +233,7 @@ namespace boost { namespace polygon{ 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, + 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); @@ -247,7 +247,7 @@ namespace boost { namespace polygon{ 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, + 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); @@ -316,7 +316,7 @@ namespace boost { namespace polygon{ 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, + 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, @@ -408,13 +408,13 @@ namespace boost { namespace polygon{ return polygon_set.end(); } - static inline orientation_2d orient(const view_of<polygon_90_set_concept, T>& polygon_set) { + 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) { + 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) { + static inline bool sorted(const view_of<polygon_90_set_concept, T>& polygon_set) { return polygon_set.sorted(); } }; diff --git a/boost/polygon/polygon_45_set_data.hpp b/boost/polygon/polygon_45_set_data.hpp index e541ee5cbf..4438d74ef8 100644 --- a/boost/polygon/polygon_45_set_data.hpp +++ b/boost/polygon/polygon_45_set_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -19,7 +19,7 @@ namespace boost { namespace polygon{ template <typename ltype, typename rtype, int op_type> class polygon_45_set_view; - + struct polygon_45_set_concept {}; template <typename Unit> @@ -43,8 +43,8 @@ namespace boost { namespace polygon{ } // copy constructor - inline polygon_45_set_data(const polygon_45_set_data& that) : - error_data_(that.error_data_), data_(that.data_), dirty_(that.dirty_), + 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> @@ -123,7 +123,7 @@ namespace boost { namespace polygon{ 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) { @@ -158,14 +158,14 @@ namespace boost { namespace polygon{ p.data_.insert(p.data_.end(), error_data_.begin(), error_data_.end()); } - // equivalence operator + // equivalence operator inline bool operator==(const polygon_45_set_data& p) const { clean(); p.clean(); return data_ == p.data_; } - // inequivalence operator + // inequivalence operator inline bool operator!=(const polygon_45_set_data& p) const { return !((*this) == p); } @@ -212,7 +212,7 @@ namespace boost { namespace polygon{ void sort() const{ if(unsorted_) { - gtlsort(data_.begin(), data_.end()); + polygon_sort(data_.begin(), data_.end()); unsorted_ = false; } } @@ -220,6 +220,7 @@ namespace boost { namespace polygon{ 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; @@ -232,7 +233,7 @@ namespace boost { namespace polygon{ } void set(const value_type& value) { - data_ = value; + data_ = value; dirty_ = true; unsorted_ = true; } @@ -242,13 +243,13 @@ namespace boost { namespace polygon{ 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> @@ -288,7 +289,7 @@ namespace boost { namespace polygon{ // 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); @@ -300,7 +301,7 @@ namespace boost { namespace polygon{ // 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); @@ -338,14 +339,14 @@ namespace boost { namespace polygon{ 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> @@ -377,7 +378,7 @@ namespace boost { namespace polygon{ 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); + 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); @@ -417,20 +418,20 @@ namespace boost { namespace polygon{ insert(pl.begin(), pl.end(), is_hole); } - void insert_vertex_half_edge_45_pair(const point_data<Unit>& pt1, point_data<Unit>& pt2, + 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); - + CornerOption corner, bool hole, polygon_45_with_holes_concept tag); + static void snap_vertex_45(Vertex45Compact& vertex); public: @@ -446,7 +447,7 @@ namespace boost { namespace polygon{ 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) { @@ -490,17 +491,17 @@ namespace boost { namespace polygon{ template <typename cT, typename pT> bool insert_vertex_half_edge_45_pair_into_vector(cT& output, - const pT& pt1, pT& pt2, - const pT& pt3, + 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); + 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); + 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); @@ -508,8 +509,8 @@ namespace boost { namespace polygon{ } 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, + 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; } @@ -611,7 +612,7 @@ namespace boost { namespace polygon{ 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> + 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; @@ -623,7 +624,7 @@ namespace boost { namespace polygon{ template <typename Unit> template <typename geometry_type> - inline void polygon_45_set_data<Unit>::insert_dispatch(const geometry_type& geometry_object, + inline void polygon_45_set_data<Unit>::insert_dispatch(const geometry_type& geometry_object, bool is_hole, rectangle_concept ) { dirty_ = true; unsorted_ = true; @@ -640,7 +641,7 @@ namespace boost { namespace polygon{ } Unit low = (std::numeric_limits<Unit>::max)(); Unit high = (std::numeric_limits<Unit>::min)(); - interval_data<Unit> xivl(low, high); + 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) { @@ -714,7 +715,7 @@ namespace boost { namespace polygon{ 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); + applyAdaptiveBoolean_<2>(b); dirty_ = false; unsorted_ = false; return *this; @@ -723,7 +724,7 @@ namespace boost { namespace polygon{ 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); + applyAdaptiveBoolean_<3>(b); dirty_ = false; unsorted_ = false; return *this; @@ -739,7 +740,7 @@ namespace boost { namespace polygon{ } template <typename Unit> - inline polygon_45_set_data<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; @@ -852,7 +853,7 @@ namespace boost { namespace polygon{ Unit y = 0; if(run1 == 0) { x = pt1.x(); - y = (Unit)(((x1 - x2) * rise2) / run2) + pt2.y(); + y = (Unit)(((x1 - x2) * rise2) / run2) + pt2.y(); } else if(run2 == 0) { x = pt2.x(); y = (Unit)(((x2 - x1) * rise1) / run1) + pt1.y(); @@ -863,7 +864,7 @@ namespace boost { namespace polygon{ // (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)) * + x = (Unit)((y2 - y1 + ((rise1 * x1) / run1) - ((rise2 * x2) / run2)) * (run1 * run2) / (rise1 * run2 - rise2 * run1)); if(rise1 == 0) { y = pt1.y(); @@ -873,7 +874,7 @@ namespace boost { namespace polygon{ // 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)) * + y = (Unit)((x2 - x1 + ((run1 * y1) / rise1) - ((run2 * y2) / rise2)) * (rise1 * rise2) / (run1 * rise2 - run2 * rise1)); } } @@ -882,7 +883,7 @@ namespace boost { namespace polygon{ template <typename Unit> inline - void handleResizingEdge45_SQRT1OVER2(polygon_45_set_data<Unit>& sizingSet, point_data<Unit> first, + 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())); @@ -932,7 +933,7 @@ namespace boost { namespace polygon{ template <typename Unit> inline - void handleResizingEdge45(polygon_45_set_data<Unit>& sizingSet, point_data<Unit> first, + 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())); @@ -998,14 +999,14 @@ namespace boost { namespace polygon{ 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, + 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) + if(multiplier < 0) diffAngle = (edge2 + 8 - edge1) % 8; else diffAngle = (edge1 + 8 - edge2) % 8; @@ -1015,7 +1016,7 @@ namespace boost { namespace polygon{ } Unit bloating = abs(resizing); if(rounding == SQRT1OVER2) { - if(edge1 % 2 && edge2 % 2) return; + 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); @@ -1074,7 +1075,7 @@ namespace boost { namespace polygon{ sizingSet.insert(insertion_rect); return; } - } + } std::vector<point_data<Unit> > pts; pts.push_back(edgePoint1); pts.push_back(second); @@ -1086,15 +1087,15 @@ namespace boost { namespace polygon{ template <typename Unit> template <typename geometry_type> - inline polygon_45_set_data<Unit>& + inline polygon_45_set_data<Unit>& polygon_45_set_data<Unit>::insert_with_resize_dispatch(const geometry_type& poly, - coordinate_type resizing, + 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; + 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); @@ -1113,8 +1114,8 @@ namespace boost { namespace polygon{ handleResizingEdge45(sizingSet, *first, *second, resizing, rounding); } else { handleResizingEdge45_SQRT1OVER2(sizingSet, *first, *second, resizing, corner); - } - if(corner != UNFILLED) + } + if(corner != UNFILLED) handleResizingVertex45(sizingSet, *first, *second, *third, resizing, rounding, corner, multiplier); first = second; second = third; @@ -1144,9 +1145,9 @@ namespace boost { namespace polygon{ 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, + coordinate_type resizing, RoundingOption rounding, - CornerOption corner, + 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 = @@ -1170,11 +1171,11 @@ namespace boost { namespace polygon{ } clear(); insert(polys.begin(), polys.end()); - dirty_ = true; + 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); @@ -1192,7 +1193,7 @@ namespace boost { namespace polygon{ } clear(); insert(polys.begin(), polys.end()); - dirty_ = true; + dirty_ = true; unsorted_ = true; return *this; } @@ -1208,7 +1209,7 @@ namespace boost { namespace polygon{ } clear(); insert(polys.begin(), polys.end()); - dirty_ = true; + dirty_ = true; unsorted_ = true; return *this; } @@ -1244,7 +1245,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -1262,7 +1263,7 @@ namespace boost { namespace polygon{ //std::cout << "SCAN " << currentX << "\n"; //scan event scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - gtlsort(eventOut.begin(), eventOut.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() && @@ -1270,7 +1271,7 @@ namespace boost { namespace polygon{ result_data.back().count += eventOut[i]; ++ptCount; } else { - if(!result_data.empty()) { + if(!result_data.empty()) { if(result_data.back().count.is_45()) { result_is_manhattan_ = false; } @@ -1290,24 +1291,24 @@ namespace boost { namespace polygon{ x = currentX; } //std::cout << "get next\n"; - if(iter2 != end2 && (iter1 == end1 || iter2->pt.x() < iter1->pt.x() || + 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, + (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() || + } 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, + (iter1->pt, typename polygon_45_formation<Unit2>:: Scan45Count( typename polygon_45_formation<Unit2>::Count2(iter1->count[0], 0), @@ -1318,22 +1319,22 @@ namespace boost { namespace polygon{ } else { //std::cout << "case3 next\n"; eventIn.push_back(Scan45Vertex - (iter2->pt, + (iter2->pt, typename polygon_45_formation<Unit2>:: - Scan45Count(typename polygon_45_formation<Unit2>::Count2(iter1->count[0], + Scan45Count(typename polygon_45_formation<Unit2>::Count2(iter1->count[0], iter2->count[0]), - typename polygon_45_formation<Unit2>::Count2(iter1->count[1], + typename polygon_45_formation<Unit2>::Count2(iter1->count[1], iter2->count[1]), - typename polygon_45_formation<Unit2>::Count2(iter1->count[2], + typename polygon_45_formation<Unit2>::Count2(iter1->count[2], iter2->count[2]), - typename polygon_45_formation<Unit2>::Count2(iter1->count[3], + typename polygon_45_formation<Unit2>::Count2(iter1->count[3], iter2->count[3])))); ++iter1; ++iter2; } } scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - gtlsort(eventOut.begin(), eventOut.end()); + polygon_sort(eventOut.begin(), eventOut.end()); std::size_t ptCount = 0; for(std::size_t i = 0; i < eventOut.size(); ++i) { @@ -1342,7 +1343,7 @@ namespace boost { namespace polygon{ result_data.back().count += eventOut[i]; ++ptCount; } else { - if(!result_data.empty()) { + if(!result_data.empty()) { if(result_data.back().count.is_45()) { result_is_manhattan_ = false; } @@ -1385,7 +1386,7 @@ namespace boost { namespace polygon{ //std::cout << "SCAN " << currentX << "\n"; //scan event scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - gtlsort(eventOut.begin(), eventOut.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() && @@ -1393,7 +1394,7 @@ namespace boost { namespace polygon{ result_data.back().count += eventOut[i]; ++ptCount; } else { - if(!result_data.empty()) { + if(!result_data.empty()) { if(result_data.back().count.is_45()) { result_is_manhattan_ = false; } @@ -1414,7 +1415,7 @@ namespace boost { namespace polygon{ } //std::cout << "get next\n"; eventIn.push_back(Scan45Vertex - (iter1->pt, + (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]), @@ -1422,7 +1423,7 @@ namespace boost { namespace polygon{ ++iter1; } scan45.scan(eventOut, eventIn.begin(), eventIn.end()); - gtlsort(eventOut.begin(), eventOut.end()); + polygon_sort(eventOut.begin(), eventOut.end()); std::size_t ptCount = 0; for(std::size_t i = 0; i < eventOut.size(); ++i) { @@ -1431,7 +1432,7 @@ namespace boost { namespace polygon{ result_data.back().count += eventOut[i]; ++ptCount; } else { - if(!result_data.empty()) { + if(!result_data.empty()) { if(result_data.back().count.is_45()) { result_is_manhattan_ = false; } @@ -1453,9 +1454,9 @@ namespace boost { namespace polygon{ return result_is_manhattan_; } - template <typename cT, typename iT> + template <typename cT, typename iT> void get_error_rects_shell(cT& posE, cT& negE, iT beginr, iT endr) { - typedef typename iT::value_type Point; + 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; @@ -1493,7 +1494,7 @@ namespace boost { namespace polygon{ const Point& pt = *beginr; pt3 = pt; ++beginr; - if(beginr == endr) { + if(beginr == endr) { next_to_last = true; //skip last point equal to first continue; @@ -1508,7 +1509,7 @@ namespace boost { namespace polygon{ 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)); @@ -1518,8 +1519,8 @@ namespace boost { namespace polygon{ pt2 = pt3; } } - - template <typename cT, typename pT> + + 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(); @@ -1550,23 +1551,24 @@ namespace boost { namespace polygon{ 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>()); + 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>()); + 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>()); + 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>()); + r90sd.begin(), r90sd.end(), boolean_op::BinaryCount<boolean_op::BinaryXor>()); } #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#pragma warning (pop) #endif result.data_.clear(); result.insert(output); @@ -1590,7 +1592,7 @@ namespace boost { namespace polygon{ lvalue_data.reserve(data_.size()); for(std::size_t i = 0 ; i < data_.size(); ++i) { const Vertex45Compact& vi = data_[i]; - Vertex45Compact2 ci; + 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]); @@ -1639,7 +1641,7 @@ namespace boost { namespace polygon{ result.error_data_.push_back(ci); } Data2 new_result_data; - gtlsort(result_data.begin(), result_data.end()); + polygon_sort(result_data.begin(), result_data.end()); applyUnary45OpOnVectors<Unit2, 0>(new_result_data, result_data); //OR operation result_data.swap(new_result_data); } @@ -1677,6 +1679,7 @@ namespace boost { namespace polygon{ } l90sd.sort(); #ifdef BOOST_POLYGON_MSVC +#pragma warning (push) #pragma warning (disable: 4127) #endif if(op == 0) { @@ -1687,7 +1690,7 @@ namespace boost { namespace polygon{ l90sd.self_xor(); } #ifdef BOOST_POLYGON_MSVC -#pragma warning (default: 4127) +#pragma warning (pop) #endif result.data_.clear(); result.insert(l90sd); @@ -1709,7 +1712,7 @@ namespace boost { namespace polygon{ lvalue_data.reserve(data_.size()); for(std::size_t i = 0 ; i < data_.size(); ++i) { const Vertex45Compact& vi = data_[i]; - Vertex45Compact2 ci; + 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 @@ -1749,7 +1752,7 @@ namespace boost { namespace polygon{ result.error_data_.push_back(ci); } Data2 new_result_data; - gtlsort(result_data.begin(), result_data.end()); + polygon_sort(result_data.begin(), result_data.end()); applyUnary45OpOnVectors<Unit2, 0>(new_result_data, result_data); //OR operation result_data.swap(new_result_data); } @@ -1787,11 +1790,11 @@ namespace boost { namespace polygon{ 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_; + 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); @@ -1844,12 +1847,12 @@ namespace boost { namespace polygon{ 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_; + 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(); @@ -1862,7 +1865,7 @@ namespace boost { namespace polygon{ 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 diff --git a/boost/polygon/polygon_45_set_traits.hpp b/boost/polygon/polygon_45_set_traits.hpp index cfc0f98a24..f52f57f17e 100644 --- a/boost/polygon/polygon_45_set_traits.hpp +++ b/boost/polygon/polygon_45_set_traits.hpp @@ -1,6 +1,6 @@ /* 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). @@ -43,13 +43,13 @@ namespace boost { namespace polygon{ 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> > { + 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> > { + 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; @@ -60,13 +60,13 @@ namespace boost { namespace polygon{ 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> > { + 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> > { + 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; @@ -94,6 +94,7 @@ namespace boost { namespace polygon{ 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(); @@ -105,7 +106,10 @@ namespace boost { namespace polygon{ 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(); @@ -116,7 +120,7 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -140,7 +144,6 @@ namespace boost { namespace polygon{ static inline bool sorted(const polygon_45_set_data<T>& polygon_set) { polygon_set.sort(); return true; } }; -} +} } #endif - diff --git a/boost/polygon/polygon_45_with_holes_data.hpp b/boost/polygon/polygon_45_with_holes_data.hpp index 717bbd3a0a..0601bdc406 100644 --- a/boost/polygon/polygon_45_with_holes_data.hpp +++ b/boost/polygon/polygon_45_with_holes_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -18,7 +18,7 @@ public: 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 polygon_45_data<coordinate_type> hole_type; typedef typename coordinate_traits<T>::coordinate_distance area_type; typedef point_data<T> point_type; @@ -55,9 +55,9 @@ public: } // copy constructor (since we have dynamic memory) - inline polygon_45_with_holes_data(const polygon_45_with_holes_data& that) : self_(that.self_), + 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_; @@ -80,7 +80,7 @@ public: 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 { @@ -98,11 +98,10 @@ public: public: polygon_45_data<coordinate_type> self_; - std::list<hole_type> holes_; + std::list<hole_type> holes_; }; } } #endif - diff --git a/boost/polygon/polygon_90_data.hpp b/boost/polygon/polygon_90_data.hpp index 7e1d9695b9..1f14ed72a6 100644 --- a/boost/polygon/polygon_90_data.hpp +++ b/boost/polygon/polygon_90_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -40,7 +40,7 @@ public: // 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_; @@ -63,18 +63,17 @@ public: // 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_; + std::vector<coordinate_type> coords_; }; } } #endif - diff --git a/boost/polygon/polygon_90_set_concept.hpp b/boost/polygon/polygon_90_set_concept.hpp index 09d5eee80d..5259a079c9 100644 --- a/boost/polygon/polygon_90_set_concept.hpp +++ b/boost/polygon/polygon_90_set_concept.hpp @@ -1,6 +1,6 @@ /* 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). @@ -17,14 +17,14 @@ namespace boost { namespace polygon{ 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 @@ -47,7 +47,7 @@ namespace boost { namespace polygon{ 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), + 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; } @@ -59,12 +59,12 @@ namespace boost { namespace polygon{ //equivalence template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3< + 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 + 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; @@ -99,7 +99,7 @@ namespace boost { namespace polygon{ //get: min_rectangles max_rectangles template <typename output_container_type, typename polygon_set_type> - typename enable_if <typename gtl_and< + 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 @@ -111,7 +111,7 @@ namespace boost { namespace polygon{ 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, @@ -120,7 +120,7 @@ namespace boost { namespace polygon{ 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, @@ -132,13 +132,13 @@ namespace boost { namespace polygon{ 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, + 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; @@ -177,7 +177,7 @@ namespace boost { namespace polygon{ 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, @@ -207,7 +207,7 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -250,7 +250,7 @@ namespace boost { namespace polygon{ 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, + 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, @@ -267,7 +267,7 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -310,7 +310,7 @@ namespace boost { namespace polygon{ 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, + 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, @@ -328,7 +328,6 @@ namespace boost { namespace polygon{ 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) { - typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; if(resizing > 0) { return bloat(polygon_set, resizing); } @@ -354,7 +353,7 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -397,7 +396,7 @@ namespace boost { namespace polygon{ 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, + 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, @@ -422,7 +421,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -436,7 +435,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -450,7 +449,7 @@ namespace boost { namespace polygon{ 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, + 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; @@ -460,24 +459,27 @@ namespace boost { namespace polygon{ return polygon_set; } + struct y_p_s_move : gtl_yes {}; + //move template <typename polygon_set_type> - 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, - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type * = 0) { + orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement) { if(orient == HORIZONTAL) return move(polygon_set, displacement, 0); - else + else return move(polygon_set, 0, displacement); } + struct y_p_s_move2 : gtl_yes {}; + template <typename polygon_set_type> - polygon_set_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, - typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type * = 0 - ) { + 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); @@ -507,7 +509,7 @@ namespace boost { namespace polygon{ 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, + 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, diff --git a/boost/polygon/polygon_90_set_data.hpp b/boost/polygon/polygon_90_set_data.hpp index 151cb9d259..305aa3e113 100644 --- a/boost/polygon/polygon_90_set_data.hpp +++ b/boost/polygon/polygon_90_set_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -9,10 +9,10 @@ #define BOOST_POLYGON_POLYGON_90_SET_DATA_HPP #include "isotropy.hpp" #include "point_concept.hpp" -#include "point_3d_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" @@ -46,7 +46,7 @@ namespace boost { namespace polygon{ // constructor from an iterator pair over vertex data template <typename iT> - inline polygon_90_set_data(orientation_2d orient, iT input_begin, iT input_end) : + inline polygon_90_set_data(orientation_2d orient, iT input_begin, iT input_end) : orient_(HORIZONTAL), data_(), dirty_(false), unsorted_(false) { dirty_ = true; unsorted_ = true; @@ -54,14 +54,14 @@ namespace boost { namespace polygon{ } // copy constructor - inline polygon_90_set_data(const polygon_90_set_data& that) : + 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) : + 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_); } @@ -138,7 +138,7 @@ namespace boost { namespace polygon{ insert(begin_input, end_input, orient_); } - inline void insert(const std::pair<coordinate_type, std::pair<coordinate_type, int> >& vertex, bool is_hole = false, + 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); @@ -164,6 +164,12 @@ namespace boost { namespace polygon{ } 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()); } @@ -190,7 +196,7 @@ namespace boost { namespace polygon{ } } - // equivalence operator + // equivalence operator inline bool operator==(const polygon_90_set_data& p) const { if(orient_ == p.orient()) { clean(); @@ -201,7 +207,7 @@ namespace boost { namespace polygon{ } } - // inequivalence operator + // inequivalence operator inline bool operator!=(const polygon_90_set_data& p) const { return !((*this) == p); } @@ -260,7 +266,7 @@ namespace boost { namespace polygon{ // value_type data; // std::swap(data, data_); // applyBooleanBinaryOp(data.begin(), data.end(), - // that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryNot>()); + // 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) { @@ -269,7 +275,7 @@ namespace boost { namespace polygon{ // value_type data; // std::swap(data, data_); // applyBooleanBinaryOp(data.begin(), data.end(), - // that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryXor>()); + // 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) { @@ -278,7 +284,7 @@ namespace boost { namespace polygon{ // value_type data; // std::swap(data, data_); // applyBooleanBinaryOp(data.begin(), data.end(), - // that.begin(), that.end(), boolean_op::BinaryCount<boolean_op::BinaryAnd>()); + // 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) { @@ -296,7 +302,7 @@ namespace boost { namespace polygon{ void sort() const{ if(unsorted_) { - gtlsort(data_.begin(), data_.end()); + polygon_sort(data_.begin(), data_.end()); unsorted_ = false; } } @@ -304,6 +310,7 @@ namespace boost { namespace polygon{ 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; @@ -311,7 +318,7 @@ namespace boost { namespace polygon{ } void set(const value_type& value, orientation_2d orient) { - data_ = value; + data_ = value; orient_ = orient; dirty_ = true; unsorted_ = true; @@ -345,11 +352,11 @@ namespace boost { namespace polygon{ typename coordinate_traits<coordinate_type>::unsigned_area_type north_bloating) { std::vector<rectangle_data<coordinate_type> > rects; clean(); - rects.reserve(data_.size() / 2); + rects.reserve(data_.size() / 2); get(rects); - rectangle_data<coordinate_type> convolutionRectangle(interval_data<coordinate_type>(-((coordinate_type)west_bloating), + 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), + 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) { @@ -392,7 +399,7 @@ namespace boost { namespace polygon{ if(nyg) pt.x(current_pt.x() + east_bloating); } - static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly, + static void resize_poly_up(std::vector<point_data<coordinate_type> >& poly, coordinate_type west_bloating, coordinate_type east_bloating, coordinate_type south_bloating, @@ -415,7 +422,7 @@ namespace boost { namespace polygon{ 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, + static bool resize_poly_down(std::vector<point_data<coordinate_type> >& poly, coordinate_type west_shrinking, coordinate_type east_shrinking, coordinate_type south_shrinking, @@ -427,7 +434,7 @@ namespace boost { namespace polygon{ point_data<coordinate_type> prev_pt = poly[0]; point_data<coordinate_type> current_pt = poly[1]; encompass(extents_rectangle, current_pt); - for(int i = 2; i < poly.size(); ++i) { + 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); @@ -451,7 +458,7 @@ namespace boost { namespace polygon{ bool found_colinear = true; while(found_colinear && poly.size() >= 4) { found_colinear = false; - typename std::vector<point_data<coordinate_type> >::iterator itr = poly.begin(); + 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; @@ -477,7 +484,7 @@ namespace boost { namespace polygon{ 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, @@ -493,9 +500,10 @@ namespace boost { namespace polygon{ //psref.insert(view_as<polygon_90_concept>((*itr).self_)); //rectangle_data<coordinate_type> prerect; //psref.extents(prerect); - resize_poly_up((*itr).self_.coords_, west_bloating, east_bloating, south_bloating, north_bloating); + 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), + 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; @@ -512,15 +520,16 @@ namespace boost { namespace polygon{ //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_, west_bloating, east_bloating, south_bloating, north_bloating)) { + 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), + 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); + // 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)) { @@ -556,13 +565,14 @@ namespace boost { namespace polygon{ //rectangle_data<coordinate_type> prerect; //psref.extents(prerect); //polygon_45_data<coordinate_type> testpoly((*itr).self_); - if(resize_poly_down((*itr).self_.coords_, -west_shrinking, -east_shrinking, -south_shrinking, -north_shrinking)) { + 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), + 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); + // 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); @@ -577,15 +587,16 @@ namespace boost { namespace polygon{ //psrefhole.insert(prerect); //psrefhole.insert(view_as<polygon_90_concept>(*itrh), true); //polygon_45_data<coordinate_type> testpoly(*itrh); - resize_poly_up((*itrh).coords_, -west_shrinking, -east_shrinking, -south_shrinking, -north_shrinking); + 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), + 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); + // 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)) { @@ -618,13 +629,13 @@ namespace boost { namespace polygon{ 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); + 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), + 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), + 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) { @@ -663,10 +674,10 @@ namespace boost { namespace polygon{ } polygon_90_set_data& - resize(coordinate_type west, coordinate_type east, coordinate_type south, coordinate_type north); + 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 + 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; @@ -701,7 +712,7 @@ namespace boost { namespace polygon{ // 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 + 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; @@ -710,7 +721,7 @@ namespace boost { namespace polygon{ } 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 + 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); @@ -720,7 +731,7 @@ namespace boost { namespace polygon{ } 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 + 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); @@ -733,7 +744,7 @@ namespace boost { namespace polygon{ } 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 + 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); @@ -746,7 +757,7 @@ namespace boost { namespace polygon{ } 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 + 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); @@ -812,7 +823,7 @@ namespace boost { namespace polygon{ mutable value_type data_; mutable bool dirty_; mutable bool unsorted_; - + private: //functions template <typename output_container> @@ -824,10 +835,25 @@ namespace boost { namespace polygon{ 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); @@ -849,6 +875,13 @@ namespace boost { namespace polygon{ 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> @@ -882,7 +915,7 @@ namespace boost { namespace polygon{ return bloat(0, e_total, 0, n_total); } } - + template <typename coordinate_type, typename property_type> class property_merge_90 { private: @@ -905,7 +938,7 @@ namespace boost { namespace polygon{ //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> + 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_); @@ -924,12 +957,12 @@ namespace boost { namespace polygon{ 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_; + 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(); @@ -942,7 +975,7 @@ namespace boost { namespace polygon{ 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 @@ -954,4 +987,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/polygon_90_set_traits.hpp b/boost/polygon/polygon_90_set_traits.hpp index 18e632973c..c1312e8856 100644 --- a/boost/polygon/polygon_90_set_traits.hpp +++ b/boost/polygon/polygon_90_set_traits.hpp @@ -1,6 +1,6 @@ /* 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). @@ -20,10 +20,10 @@ namespace boost { namespace polygon{ template <typename T> struct traits_by_concept<T, point_concept> { typedef point_traits<T> type; }; template <typename T> - struct traits_by_concept<T, point_3d_concept> { typedef point_3d_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; }; @@ -63,7 +63,7 @@ namespace boost { namespace polygon{ typedef typename traits_type::coordinate_type type; }; template <typename T> - struct get_coordinate_type<T, undefined_concept> { + 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 @@ -71,7 +71,7 @@ namespace boost { namespace polygon{ template <typename T, typename T2> struct get_iterator_type_2 { - typedef const T* type; + 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; } }; @@ -88,7 +88,7 @@ namespace boost { namespace polygon{ 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 {}; @@ -109,25 +109,25 @@ namespace boost { namespace polygon{ // struct get_iterator_type_45 {}; // template <typename T> // struct get_iterator_type_45<T, void> { -// typedef typename T::const_iterator type; +// 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; +// 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; +// 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; +// 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; } // }; @@ -170,13 +170,13 @@ namespace boost { namespace polygon{ 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> > { + 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> > { + 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; @@ -187,15 +187,15 @@ namespace boost { namespace polygon{ 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> > { + 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 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> > { + 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 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; }; @@ -278,6 +278,7 @@ namespace boost { namespace polygon{ 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()); @@ -289,7 +290,10 @@ namespace boost { namespace polygon{ 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()); @@ -300,10 +304,11 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -341,15 +346,15 @@ namespace boost { namespace polygon{ 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"; } @@ -359,4 +364,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/polygon_90_with_holes_data.hpp b/boost/polygon/polygon_90_with_holes_data.hpp index 2fb6cdb9f2..be43b6582e 100644 --- a/boost/polygon/polygon_90_with_holes_data.hpp +++ b/boost/polygon/polygon_90_with_holes_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -19,7 +19,7 @@ public: 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 polygon_90_data<coordinate_type> hole_type; typedef typename coordinate_traits<T>::area_type area_type; typedef point_data<T> point_type; @@ -55,9 +55,9 @@ public: } // copy constructor (since we have dynamic memory) - inline polygon_90_with_holes_data(const polygon_90_with_holes_data& that) : self_(that.self_), + 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_; @@ -90,7 +90,7 @@ public: 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 { @@ -108,9 +108,8 @@ public: private: polygon_90_data<coordinate_type> self_; - std::list<hole_type> holes_; + std::list<hole_type> holes_; }; } } #endif - diff --git a/boost/polygon/polygon_data.hpp b/boost/polygon/polygon_data.hpp index cd3b672299..9784466f1d 100644 --- a/boost/polygon/polygon_data.hpp +++ b/boost/polygon/polygon_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -32,7 +32,7 @@ public: // 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_; @@ -61,10 +61,9 @@ public: inline std::size_t size() const { return coords_.size(); } public: - std::vector<point_data<coordinate_type> > coords_; + std::vector<point_data<coordinate_type> > coords_; }; } } #endif - diff --git a/boost/polygon/polygon_set_concept.hpp b/boost/polygon/polygon_set_concept.hpp index ecd2c70209..e3d37b8216 100644 --- a/boost/polygon/polygon_set_concept.hpp +++ b/boost/polygon/polygon_set_concept.hpp @@ -1,6 +1,6 @@ /* 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). @@ -27,14 +27,14 @@ namespace boost { namespace polygon{ 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 @@ -83,11 +83,11 @@ namespace boost { namespace polygon{ //equivalence template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3 < + 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 + 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; @@ -117,14 +117,14 @@ namespace boost { namespace polygon{ ps.clean(); return ps.empty(); } - + //extents template <typename polygon_set_type, typename rectangle_type> - typename enable_if< typename gtl_and< + 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, + 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; @@ -161,11 +161,11 @@ namespace boost { namespace polygon{ 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_, + retval += detail::simplify_detail::simplify(polys[i].self_.coords_, polys[i].self_.coords_, threshold); - for(typename std::list<polygon_data<Unit> >::iterator itrh = + 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_, + retval += detail::simplify_detail::simplify((*itrh).coords_, (*itrh).coords_, threshold); } } @@ -204,7 +204,7 @@ namespace boost { namespace polygon{ //interact template <typename polygon_set_type_1, typename polygon_set_type_2> - typename enable_if< typename gtl_and_3 < + 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, @@ -222,7 +222,7 @@ namespace boost { namespace polygon{ 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, + 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); @@ -236,7 +236,7 @@ namespace boost { namespace polygon{ 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, + 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); @@ -266,7 +266,7 @@ namespace boost { namespace polygon{ 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, + 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, @@ -307,7 +307,7 @@ namespace boost { namespace polygon{ 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 + 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); @@ -317,23 +317,23 @@ namespace boost { namespace polygon{ 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_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 + ::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 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 + 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); @@ -346,7 +346,7 @@ namespace boost { namespace polygon{ 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 + 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); @@ -359,30 +359,30 @@ namespace boost { namespace polygon{ 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 + 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_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 + ::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, + 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); @@ -391,8 +391,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -401,8 +401,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -412,8 +412,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -422,8 +422,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -432,9 +432,9 @@ namespace boost { namespace polygon{ 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, + 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); @@ -550,13 +550,13 @@ namespace boost { namespace polygon{ return polygon_set.end(); } - static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) { + 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) { + 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) { + static inline bool sorted(const view_of<polygon_45_set_concept, T>& polygon_set) { return polygon_set.sorted(); } }; diff --git a/boost/polygon/polygon_set_data.hpp b/boost/polygon/polygon_set_data.hpp index bbddacf241..3c761d34f8 100644 --- a/boost/polygon/polygon_set_data.hpp +++ b/boost/polygon/polygon_set_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -11,7 +11,6 @@ #include "polygon_45_set_concept.hpp" #include "polygon_traits.hpp" #include "detail/polygon_arbitrary_formation.hpp" -#include <iostream> namespace boost { namespace polygon { @@ -22,7 +21,7 @@ namespace boost { namespace polygon { template <typename T> static inline T round_down(double val) { T rounded_val = (T)(val); - if(val < (double)rounded_val) + if(val < (double)rounded_val) --rounded_val; return rounded_val; } @@ -57,11 +56,11 @@ namespace boost { namespace polygon { } // copy constructor - inline polygon_set_data(const polygon_set_data& that) : + 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> + template <typename ltype, typename rtype, int op_type> inline polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that); // destructor @@ -150,10 +149,10 @@ namespace boost { namespace polygon { 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, + 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 = + 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()); @@ -161,12 +160,12 @@ namespace boost { namespace polygon { } template <typename polygon_with_holes_type> - inline void insert(const polygon_with_holes_type& polygon_with_holes_object, bool is_hole, + 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, + 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()); } @@ -198,36 +197,34 @@ namespace boost { namespace polygon { template <class iT> inline void insert_vertex_sequence(iT begin_vertex, iT end_vertex, direction_1d winding, bool is_hole) { - bool first_iteration = true; - point_type first_point; - point_type previous_point; - point_type current_point; - direction_1d winding_dir = winding; - int multiplier = winding_dir == COUNTERCLOCKWISE ? 1 : -1; - if(is_hole) multiplier *= -1; - for( ; begin_vertex != end_vertex; ++begin_vertex) { - assign(current_point, *begin_vertex); - if(first_iteration) { - first_iteration = false; - first_point = previous_point = current_point; - } else { - if(previous_point != current_point) { - element_type elem(edge_type(previous_point, current_point), - ( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier); - insert_clean(elem); - } - } - previous_point = current_point; + if (begin_vertex == end_vertex) { + // No edges to insert. + return; } - current_point = first_point; - if(!first_iteration) { - if(previous_point != current_point) { - element_type elem(edge_type(previous_point, current_point), - ( previous_point.get(HORIZONTAL) == current_point.get(HORIZONTAL) ? -1 : 1) * multiplier); + // 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; + 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); } - dirty_ = true; - unsorted_ = true; + ++vertex0; + ++vertex1; + if (vertex1 == end_vertex) { + vertex1 = begin_vertex; + } } } @@ -248,7 +245,7 @@ namespace boost { namespace polygon { 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)); } - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(container, data.begin(), data.end()); //std::cout << "DONE FORMING POLYGONS\n"; } @@ -270,14 +267,10 @@ namespace boost { namespace polygon { } } - // equivalence operator - inline bool operator==(const polygon_set_data& p) const { - clean(); - p.clean(); - return data_ == p.data_; - } + // equivalence operator + inline bool operator==(const polygon_set_data& p) const; - // inequivalence operator + // inequivalence operator inline bool operator!=(const polygon_set_data& p) const { return !((*this) == p); } @@ -321,7 +314,7 @@ namespace boost { namespace polygon { void sort() const{ if(unsorted_) { - gtlsort(data_.begin(), data_.end()); + polygon_sort(data_.begin(), data_.end()); unsorted_ = false; } } @@ -329,13 +322,14 @@ namespace boost { namespace polygon { 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; + data_ = value; dirty_ = true; unsorted_ = true; } @@ -362,7 +356,7 @@ namespace boost { namespace polygon { resize(coordinate_type resizing, bool corner_fill_arc = false, unsigned int num_circle_segments=0); template <typename transform_type> - inline polygon_set_data& + inline polygon_set_data& transform(const transform_type& tr) { std::vector<polygon_with_holes_data<T> > polys; get(polys); @@ -376,7 +370,7 @@ namespace boost { namespace polygon { return *this; } - inline polygon_set_data& + 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); @@ -384,31 +378,41 @@ namespace boost { namespace polygon { } return *this; } - - inline polygon_set_data& + + 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& polygon_set, + inline polygon_set_data& scale(polygon_set_data& polygon_set, 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, + 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) { @@ -439,17 +443,17 @@ namespace boost { namespace polygon { 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); - typename scanline_base<long double>::compute_intersection_pack pack; + 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)) { + 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)) { + 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 } } @@ -565,8 +569,8 @@ namespace boost { namespace polygon { } 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, + 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 tag) { 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 = @@ -578,14 +582,14 @@ namespace boost { namespace polygon { } 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, + 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 tag) { if (resizing==0) return *this; - + // one dimensional used to store CCW/CW flag //direction_1d wdir = winding(poly); // LOW==CLOCKWISE just faster to type @@ -630,25 +634,25 @@ namespace boost { namespace polygon { 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 = sqrt(s2)/resizing; + 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 + 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) { + if ( treat_as_concave) { std::vector<point_data<T> > pts; pts.push_back(point_data<T>(second->x()+v.x(),second->y()+v.y())); @@ -669,13 +673,13 @@ namespace boost { namespace polygon { 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)) + , 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; @@ -684,7 +688,7 @@ namespace boost { namespace polygon { } } prev_point = curr_prev; - + } else { treat_as_concave = true; } @@ -707,7 +711,7 @@ namespace boost { namespace polygon { 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 @@ -721,7 +725,7 @@ namespace boost { namespace polygon { inline polygon_set_data& - interact(const polygon_set_data& that); + interact(const polygon_set_data& that); inline bool downcast(polygon_45_set_data<coordinate_type>& result) const { if(!is_45_) return false; @@ -790,7 +794,7 @@ namespace boost { namespace polygon { 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)); } - gtlsort(data.begin(), data.end()); + polygon_sort(data.begin(), data.end()); pf.scan(container, data.begin(), data.end()); } }; @@ -810,17 +814,17 @@ namespace boost { namespace polygon { // } template <typename T> - inline int make_resizing_vertex_list(std::vector<std::vector<point_data< T> > >& return_points, + 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/sqrt( dn1.x()*dn1.x()+dn1.y()*dn1.y()); + 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/sqrt( dn2.x()*dn2.x()+dn2.y()*dn2.y()); + 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())); @@ -843,7 +847,7 @@ namespace boost { namespace polygon { 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); @@ -881,21 +885,21 @@ namespace boost { namespace polygon { // 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, + 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 + // 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) + if (ps < 0.0) ps += 2.0 * our_pi; - if (pe <= 0.0) + if (pe <= 0.0) pe += 2.0 * our_pi; - if (ps >= 2.0 * our_pi) + if (ps >= 2.0 * our_pi) ps -= 2.0 * our_pi; - while (pe <= ps) + while (pe <= ps) pe += 2.0 * our_pi; double delta_angle = (2.0 * our_pi) / (double)num_circle_segments; if ( start==end) // full circle? @@ -941,12 +945,12 @@ namespace boost { namespace polygon { 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_; + 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(); @@ -959,7 +963,7 @@ namespace boost { namespace polygon { 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 @@ -997,4 +1001,3 @@ namespace boost { namespace polygon { #include "polygon_set_concept.hpp" #include "detail/minkowski.hpp" #endif - diff --git a/boost/polygon/polygon_set_traits.hpp b/boost/polygon/polygon_set_traits.hpp index 93604c4931..b68bbc1390 100644 --- a/boost/polygon/polygon_set_traits.hpp +++ b/boost/polygon/polygon_set_traits.hpp @@ -1,6 +1,6 @@ /* 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). @@ -45,13 +45,13 @@ namespace boost { namespace polygon{ typedef typename is_polygonal_concept<typename geometry_concept<T>::type>::type type; }; template <typename T> - struct is_polygon_set_type<std::list<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> > { + 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; @@ -62,13 +62,13 @@ namespace boost { namespace polygon{ 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> > { + 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 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> > { + 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; @@ -82,6 +82,7 @@ namespace boost { namespace polygon{ 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); } @@ -91,7 +92,10 @@ namespace boost { namespace polygon{ 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); } @@ -100,7 +104,7 @@ namespace boost { namespace polygon{ 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, + 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); } @@ -124,7 +128,6 @@ namespace boost { namespace polygon{ static inline bool sorted(const polygon_set_data<T>& polygon_set) { polygon_set.sort(); return true; } }; -} +} } #endif - diff --git a/boost/polygon/polygon_traits.hpp b/boost/polygon/polygon_traits.hpp index 041321d22b..dddbf34d5d 100644 --- a/boost/polygon/polygon_traits.hpp +++ b/boost/polygon/polygon_traits.hpp @@ -1,6 +1,6 @@ /* 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). @@ -18,17 +18,17 @@ namespace boost { namespace polygon{ 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; @@ -45,17 +45,17 @@ namespace boost { namespace polygon{ 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; @@ -73,18 +73,18 @@ namespace boost { namespace polygon{ 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); @@ -97,7 +97,7 @@ namespace boost { namespace polygon{ struct polygon_traits {}; template <typename T> - struct polygon_traits<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, @@ -106,7 +106,7 @@ namespace boost { namespace polygon{ >::type> : public polygon_traits_general<T> {}; template <typename T> - struct polygon_traits< 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 @@ -161,7 +161,7 @@ namespace boost { namespace polygon{ return t.end_holes(); } - // Get the number of holes + // Get the number of holes static inline std::size_t size_holes(const T& t) { return t.size_holes(); } @@ -169,14 +169,14 @@ namespace boost { namespace polygon{ 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> @@ -199,7 +199,7 @@ namespace boost { namespace polygon{ t.set(input_begin, input_end); return t; } - + }; template <typename T, typename enable = void> @@ -251,7 +251,7 @@ namespace boost { namespace polygon{ struct polygon_45_with_holes_concept {}; struct polygon_90_concept {}; struct polygon_90_with_holes_concept {}; - + template <typename T> struct is_polygon_90_type { @@ -272,7 +272,7 @@ namespace boost { namespace polygon{ 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; @@ -284,7 +284,7 @@ namespace boost { namespace polygon{ 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 is_polygon_45_type<T>::type, typename gtl_same_type<polygon_45_with_holes_concept, GC>::type>::type type; }; @@ -292,7 +292,7 @@ namespace boost { namespace polygon{ 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 is_polygon_type<T>::type, typename gtl_same_type<polygon_with_holes_concept, GC>::type>::type type; }; @@ -301,7 +301,7 @@ namespace boost { namespace polygon{ 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; @@ -313,7 +313,7 @@ namespace boost { namespace polygon{ 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; @@ -341,10 +341,10 @@ namespace boost { namespace polygon{ 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_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, @@ -372,7 +372,7 @@ namespace boost { namespace polygon{ 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> { + 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 @@ -399,9 +399,9 @@ namespace boost { namespace polygon{ /// \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 & + 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; @@ -411,7 +411,7 @@ namespace boost { namespace polygon{ 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, + 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) { @@ -434,29 +434,29 @@ namespace boost { namespace polygon{ 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_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 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 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); @@ -465,7 +465,7 @@ namespace boost { namespace polygon{ /// \relatesalso polygon_concept template <typename T> typename enable_if < typename gtl_if< - typename is_polygon_with_holes_type<T>::type>::type, + 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); @@ -473,7 +473,7 @@ namespace boost { namespace polygon{ /// \relatesalso polygon_concept template <typename T> - typename enable_if <typename is_polygon_with_holes_type<T>::type, + 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); @@ -482,7 +482,7 @@ namespace boost { namespace 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 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); @@ -491,7 +491,7 @@ namespace boost { namespace 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 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); @@ -499,7 +499,7 @@ namespace boost { namespace polygon{ /// \relatesalso polygon_with_holes_concept template <typename T> - typename enable_if <typename is_polygon_with_holes_type<T>::type, + 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); @@ -550,7 +550,7 @@ namespace boost { namespace polygon{ polygon_with_holes_traits<T2>::end_holes(rvalue)); return lvalue; } - + // \relatesalso polygon_90_concept template <typename T1, typename T2> typename enable_if< @@ -561,7 +561,7 @@ namespace boost { namespace polygon{ polygon_90_traits<T2>::end_compact(rvalue)); return lvalue; } - + // \relatesalso polygon_90_with_holes_concept template <typename T1, typename T2> typename enable_if< @@ -589,14 +589,14 @@ namespace boost { namespace 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 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); + 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; @@ -607,15 +607,15 @@ namespace boost { namespace 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 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); + 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); @@ -623,11 +623,11 @@ namespace boost { namespace polygon{ 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 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) { @@ -654,7 +654,7 @@ namespace boost { namespace polygon{ 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. @@ -667,7 +667,7 @@ namespace boost { namespace polygon{ 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); + 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); @@ -701,7 +701,7 @@ namespace boost { namespace polygon{ 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); + 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); @@ -732,15 +732,15 @@ namespace boost { namespace 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_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, typename gtl_not<typename gtl_same_type - < forty_five_domain, + < 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); + 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); @@ -756,8 +756,6 @@ namespace boost { namespace polygon{ void snap_point_vector_to_45(std::vector<point_data<Unit> >& pts) { typedef point_data<Unit> Point; if(pts.size() < 3) { pts.clear(); return; } - Point firstPt = pts.front(); - Point prevPt = firstPt; typename std::vector<point_data<Unit> >::iterator endLocation = std::unique(pts.begin(), pts.end()); if(endLocation != pts.end()){ pts.resize(endLocation - pts.begin()); @@ -838,7 +836,7 @@ namespace boost { namespace polygon{ 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); + for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon); iter != end_points(polygon); ++iter) { points.push_back(*iter); } @@ -869,15 +867,15 @@ namespace boost { namespace 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_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, typename gtl_same_type - < forty_five_domain, + < 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); + 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); @@ -906,18 +904,18 @@ namespace boost { namespace polygon{ return polygon; } - //scale non-45 + //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_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, typename gtl_not<typename gtl_same_type - < forty_five_domain, + < 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); + 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)); @@ -926,19 +924,19 @@ namespace boost { namespace polygon{ return polygon; } - //scale specifically 45 + //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_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, typename gtl_same_type - < forty_five_domain, + < 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); + 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)); @@ -973,7 +971,6 @@ namespace boost { namespace polygon{ 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; - typedef typename point_traits<point_type>::coordinate_type Unit; if(begin_range == end_range) return area_type(0); point_type first = *begin_range; point_type previous = first; @@ -987,11 +984,12 @@ namespace boost { namespace polygon{ 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 (default:1572) +#pragma warning (pop) #endif // do trapezoid area accumulation area += (x2 - x1) * (((area_type)y(*begin_range) - y_base) + @@ -1012,7 +1010,7 @@ namespace boost { namespace polygon{ } template <typename T> - typename enable_if< + 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 @@ -1036,7 +1034,7 @@ namespace boost { namespace polygon{ template <typename iT> bool point_sequence_is_45(iT itr, iT itr_end) { - typedef typename iT::value_type Point; + 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; @@ -1097,7 +1095,7 @@ namespace boost { namespace polygon{ 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 enable_if< typename is_polygon_with_holes_type<T>::type>::type * = 0 ) { typedef typename distance_type_by_domain @@ -1115,7 +1113,7 @@ namespace boost { namespace polygon{ } template <typename T> - typename enable_if <typename is_polygon_with_holes_type<T>::type, + 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); @@ -1129,51 +1127,65 @@ namespace boost { namespace polygon{ } 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) { + 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; - iterator iter, iter_end; - iter_end = end_points(polygon); - iter = begin_points(polygon); - point_type prev_pt = *iter; - std::size_t num = size(polygon); - std::size_t counts[2] = {0, 0}; - for(std::size_t i = 0; i < num; ++i) { - if(i == num-1) iter = begin_points(polygon); - else ++iter; - point_type current_pt = *iter; - if(x(current_pt) == - x(prev_pt)) { - unsigned int index = x(current_pt) > - x(point); - std::size_t increment = 0; - interval_data<coordinate_type> ivl(y(current_pt), - y(prev_pt)); - if(contains(ivl, y(point), true)) { - if(x(current_pt) == - x(point)) return consider_touch; - ++increment; - if(y(current_pt) != - y(point) && - y(prev_pt) != - y(point)) { - ++increment; - } - counts[index] += increment; + 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; + } } } - prev_pt = current_pt; } - //odd count implies boundary condition - if(counts[0] % 2 || counts[1] % 2) return consider_touch; - //an odd number of edges to the left implies interior pt - return counts[winding(polygon) == COUNTERCLOCKWISE ? 0 : 1] % 4 != 0; + int total_intersections = num_full_intersections + (num_half_intersections >> 1); + return total_intersections & 1; } //TODO: refactor to expose as user APIs @@ -1200,7 +1212,7 @@ namespace boost { namespace polygon{ 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; @@ -1240,7 +1252,7 @@ namespace boost { namespace polygon{ 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 + //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; @@ -1285,8 +1297,8 @@ namespace boost { namespace polygon{ }; template <typename T, typename input_point_type> - typename enable_if< - typename gtl_and< typename is_any_mutable_polygon_with_holes_type<T>::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) { @@ -1306,10 +1318,10 @@ namespace boost { namespace polygon{ } 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 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) { @@ -1367,16 +1379,16 @@ namespace boost { namespace polygon{ } } 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 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) { @@ -1420,28 +1432,16 @@ namespace boost { namespace polygon{ } } 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_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 <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 + bool>::type extents(T1& bounding_box, const T2& polygon) { typedef typename polygon_traits<T2>::iterator_type iterator; bool first_iteration = true; @@ -1458,6 +1458,18 @@ namespace boost { namespace polygon{ 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) { @@ -1548,7 +1560,7 @@ namespace boost { namespace polygon{ // }; 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; @@ -1565,7 +1577,7 @@ namespace boost { namespace polygon{ rectangle_data<coordinate_type> rect; view_of(const T& obj) : rect() { point_data<coordinate_type> pts[2]; - typename polygon_traits<T>::iterator_type itr = + typename polygon_traits<T>::iterator_type itr = begin_points(obj), itre = end_points(obj); if(itr == itre) return; assign(pts[0], *itr); @@ -1584,7 +1596,7 @@ namespace boost { namespace polygon{ 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; @@ -1597,17 +1609,17 @@ namespace boost { namespace polygon{ 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); @@ -1618,7 +1630,7 @@ namespace boost { namespace polygon{ 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; @@ -1633,18 +1645,18 @@ namespace boost { namespace polygon{ 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); @@ -1689,26 +1701,26 @@ namespace boost { namespace polygon{ inline bool operator!=(const iterator_holes_type& that) const { return (internal_itr != that.internal_itr); } - inline value_type operator*() const { + 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); @@ -1718,24 +1730,24 @@ namespace boost { namespace polygon{ 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; @@ -1770,28 +1782,28 @@ namespace boost { namespace polygon{ inline bool operator!=(const iterator_holes_type& that) const { return (internal_itr != that.internal_itr); } - inline value_type operator*() const { + 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); @@ -1801,17 +1813,17 @@ namespace boost { namespace polygon{ 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> @@ -1831,17 +1843,17 @@ namespace boost { namespace polygon{ 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); @@ -1856,4 +1868,3 @@ namespace boost { namespace polygon{ } #endif - diff --git a/boost/polygon/polygon_with_holes_data.hpp b/boost/polygon/polygon_with_holes_data.hpp index e5a975bbdf..a1a0e1dd2a 100644 --- a/boost/polygon/polygon_with_holes_data.hpp +++ b/boost/polygon/polygon_with_holes_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -18,7 +18,7 @@ public: 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 polygon_data<coordinate_type> hole_type; typedef typename coordinate_traits<T>::coordinate_distance area_type; typedef point_data<T> point_type; @@ -55,9 +55,9 @@ public: } // copy constructor (since we have dynamic memory) - inline polygon_with_holes_data(const polygon_with_holes_data& that) : self_(that.self_), + 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_; @@ -80,7 +80,7 @@ public: 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 { @@ -98,11 +98,10 @@ public: public: polygon_data<coordinate_type> self_; - std::list<hole_type> holes_; + std::list<hole_type> holes_; }; - + } } #endif - diff --git a/boost/polygon/rectangle_concept.hpp b/boost/polygon/rectangle_concept.hpp index e302b99c90..e82431907b 100644 --- a/boost/polygon/rectangle_concept.hpp +++ b/boost/polygon/rectangle_concept.hpp @@ -1,6 +1,6 @@ /* 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). @@ -25,7 +25,7 @@ namespace boost { namespace polygon{ struct rectangle_concept {}; - + template <typename T> struct is_rectangle_concept { typedef gtl_no type; }; template <> @@ -62,8 +62,8 @@ namespace boost { namespace polygon{ 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; }; + 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 { @@ -74,8 +74,8 @@ namespace boost { namespace polygon{ 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_traits<T>::coordinate_type>::coordinate_distance type; }; + 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 { @@ -83,91 +83,92 @@ namespace boost { namespace polygon{ T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type; }; + struct y_r_get_interval : gtl_yes {}; + template <typename T> - typename rectangle_interval_type<T>::type - get(const T& rectangle, orientation_2d orient, - typename enable_if< typename gtl_if<typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0 - ) { - return rectangle_traits<T>::get(rectangle, orient); + 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 gtl_if<typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type>::type, - typename rectangle_traits<T>::interval_type>::type + 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); + 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 gtl_if<typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type>::type, - typename rectangle_traits<T>::interval_type>::type + 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); + 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 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 + void>::type set(T& rectangle, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, orient, 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 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 + void>::type set(T& rectangle, orientation_2d orient, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, orient, 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 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 + void>::type horizontal(T& rectangle, const T2& interval) { - rectangle_mutable_traits<T>::set(rectangle, HORIZONTAL, 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 + 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); + 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 + 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 + 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)); + 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> @@ -179,11 +180,11 @@ namespace boost { namespace polygon{ 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 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, @@ -193,36 +194,36 @@ namespace boost { namespace polygon{ set(lvalue, VERTICAL, get(rvalue, VERTICAL)); return lvalue; } - + struct y_r_equiv : gtl_yes {}; template <typename T, typename T2> - typename enable_if< + 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 + 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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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); + 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_traits<rectangle_type>::coordinate_type value) { - typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient); + 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); } @@ -230,7 +231,7 @@ namespace boost { namespace polygon{ struct y_r_xl : gtl_yes {}; template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_xl, typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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); @@ -239,15 +240,15 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type>::coordinate_type value) { + 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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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); @@ -256,32 +257,32 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type>::coordinate_type value) { + 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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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_traits<rectangle_type>::coordinate_type value) { + 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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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); @@ -290,45 +291,45 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type>::coordinate_type value) { + 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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type, - point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::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_traits<rectangle_type>::coordinate_type> (xl(rectangle), yl(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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type, - point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::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_traits<rectangle_type>::coordinate_type> (xh(rectangle), yl(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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type, - point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::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_traits<rectangle_type>::coordinate_type> (xl(rectangle), yh(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 gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type, - point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::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_traits<rectangle_type>::coordinate_type> (xh(rectangle), yh(rectangle)); + return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yh(rectangle)); } struct y_r_contains : gtl_yes {}; @@ -336,8 +337,8 @@ namespace boost { namespace polygon{ 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>::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); @@ -347,8 +348,8 @@ namespace boost { namespace polygon{ 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, + 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); @@ -359,30 +360,31 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type Unit; + 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_traits<rectangle_type>::interval_type>(x1, x2)); - vertical(rectangle, construct<typename rectangle_traits<rectangle_type>::interval_type>(y1, y2)); + 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> - rectangle_type& - move(rectangle_type& rectangle, orientation_2d orient, - typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::coordinate_difference delta, - typename enable_if<typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type * = 0 - ) { - typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient); + 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; @@ -394,18 +396,18 @@ namespace boost { namespace polygon{ 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, + 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_traits<rectangle_type_1>::interval_type ivl = horizontal(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 @@ -415,13 +417,13 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type_1>::interval_type ivl = horizontal(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 @@ -431,13 +433,13 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type_1>::interval_type ivl = horizontal(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 @@ -448,13 +450,13 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type_1>::interval_type ivl = horizontal(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 @@ -463,7 +465,7 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type>::interval_type ivl = horizontal(rectangle); + 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))); @@ -474,11 +476,11 @@ namespace boost { namespace polygon{ // deconvolve with point template <typename rectangle_type, typename point_type> - typename enable_if< + 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_traits<rectangle_type>::interval_type ivl = horizontal(rectangle); + 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))); @@ -489,7 +491,7 @@ namespace boost { namespace polygon{ // get the magnitude of the interval range depending on orient template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_delta, typename gtl_if<typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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)); @@ -500,9 +502,9 @@ namespace boost { namespace polygon{ // 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_traits<rectangle_type>::coordinate_type>::manhattan_area_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_traits<rectangle_type>::coordinate_type>::manhattan_area_type area_type; + 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); } @@ -510,8 +512,8 @@ namespace boost { namespace polygon{ // 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 + 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; @@ -521,18 +523,19 @@ namespace boost { namespace polygon{ // get the half perimeter of the rectangle template <typename rectangle_type> - typename enable_if< typename gtl_and<y_r_half_p, typename gtl_if<typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::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 rectangle_difference_type<rectangle_type>::type - perimeter(const rectangle_type& rectangle, - typename enable_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type * = 0 - ) { + 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); } @@ -543,10 +546,10 @@ namespace boost { namespace polygon{ // [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 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 + 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); @@ -559,44 +562,44 @@ namespace boost { namespace polygon{ // [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 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 + 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 + bool>::type abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, direction_2d dir) { - return + 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 + bool>::type abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, orientation_2d orient) { - return + return abuts(get(rectangle, orient), get(b, orient)) && intersects(get(rectangle, orient.get_perpendicular()), get(b, orient.get_perpendicular()), true); @@ -608,7 +611,7 @@ namespace boost { namespace polygon{ 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 + bool>::type abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b) { return abuts(rectangle, b, HORIZONTAL) || abuts(rectangle, b, VERTICAL); } @@ -617,13 +620,13 @@ namespace boost { namespace polygon{ // intersect rectangle with interval on orient template <typename rectangle_type, typename interval_type> - typename enable_if< + 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 + bool>::type intersect(rectangle_type& rectangle, const interval_type& b, orientation_2d orient, bool consider_touch = true) { - typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient); + typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient); if(intersect(ivl, b, consider_touch)) { set(rectangle, orient, ivl); return true; @@ -637,7 +640,7 @@ namespace boost { namespace polygon{ 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 + 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); @@ -656,7 +659,7 @@ namespace boost { namespace polygon{ 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_traits<rectangle_type_1>::interval_type ivl = get(rectangle, HORIZONTAL); + typename rectangle_interval_type<rectangle_type_1>::type ivl = get(rectangle, HORIZONTAL); generalized_intersect(ivl, horizontal(b)); horizontal(rectangle, ivl); ivl = vertical(rectangle); @@ -669,11 +672,11 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type bloating) { - typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient); + 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; @@ -683,10 +686,10 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type bloating) { + typename rectangle_coordinate_type<rectangle_type>::type bloating) { bloat(rectangle, HORIZONTAL, bloating); return bloat(rectangle, VERTICAL, bloating); } @@ -695,11 +698,11 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type bloating) { - typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orientation_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; @@ -709,10 +712,10 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type shrinking) { + shrink(rectangle_type& rectangle, orientation_2d orient, + typename rectangle_coordinate_type<rectangle_type>::type shrinking) { return bloat(rectangle, orient, -shrinking); } @@ -720,10 +723,10 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type shrinking) { + shrink(rectangle_type& rectangle, + typename rectangle_coordinate_type<rectangle_type>::type shrinking) { return bloat(rectangle, -shrinking); } @@ -731,10 +734,10 @@ namespace boost { namespace polygon{ // 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, + 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_traits<rectangle_type>::coordinate_type shrinking) { + typename rectangle_coordinate_type<rectangle_type>::type shrinking) { return bloat(rectangle, dir, -shrinking); } @@ -742,13 +745,13 @@ namespace boost { namespace polygon{ // 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_traits<rectangle_type>::interval_type ivl = get(rectangle, orient); + 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; @@ -760,12 +763,12 @@ namespace boost { namespace polygon{ // enlarge rectangle to encompass the Rectangle b template <typename rectangle_type_1, typename rectangle_type_2> - bool - encompass(rectangle_type_1& rectangle, const rectangle_type_2& b, - 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>::type * = 0 - ) { + 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); @@ -775,16 +778,13 @@ namespace boost { namespace polygon{ // 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 enable_if< - typename gtl_and< 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>::type * = 0 - ) { - typename rectangle_traits<rectangle_type_1>::interval_type hivl, vivl; + 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 @@ -803,7 +803,7 @@ namespace boost { namespace polygon{ 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 + bool>::type center(point_type& center_point, const rectangle_type& rectangle) { center_point = construct<point_type>(center(horizontal(rectangle)), center(vertical(rectangle))); @@ -816,9 +816,9 @@ namespace boost { namespace polygon{ 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 + bool>::type get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) { - typedef typename rectangle_traits<rectangle_type>::coordinate_type Unit; + 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); @@ -829,8 +829,8 @@ namespace boost { namespace polygon{ 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 + 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))); @@ -842,10 +842,10 @@ namespace boost { namespace polygon{ 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 + bool>::type join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) { - typedef typename rectangle_traits<rectangle_type_1>::interval_type Interval1; - typedef typename rectangle_traits<rectangle_type_2>::interval_type Interval2; + 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); @@ -860,7 +860,7 @@ namespace boost { namespace polygon{ } return false; } - + struct y_r_eda2 : gtl_yes {}; template <typename rectangle_type, typename point_type> @@ -875,8 +875,8 @@ namespace boost { namespace polygon{ 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 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 @@ -887,12 +887,12 @@ namespace boost { namespace polygon{ struct y_r_sed : gtl_yes {}; template <typename rectangle_type, typename point_type> - typename enable_if< typename gtl_if< typename gtl_and_3<y_r_sed, + 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>::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_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist; + 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); @@ -901,12 +901,12 @@ namespace boost { namespace polygon{ 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 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_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist; + 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); @@ -917,10 +917,9 @@ namespace boost { namespace polygon{ 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 + typename rectangle_distance_type<rectangle_type>::type>::type euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { - return sqrt((double) - (square_euclidean_distance(lvalue, rvalue))); + return std::sqrt((double)(square_euclidean_distance(lvalue, rvalue))); } struct y_r_edist2 : gtl_yes {}; @@ -928,21 +927,21 @@ namespace boost { namespace polygon{ 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 + 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 sqrt(val); + return std::sqrt(val); } struct y_r_mdist : gtl_yes {}; template <typename rectangle_type, typename point_type> - typename enable_if< + 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_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist; + 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; @@ -951,12 +950,12 @@ namespace boost { namespace polygon{ struct y_r_mdist2 : gtl_yes {}; template <typename rectangle_type, typename rectangle_type_2> - typename enable_if< + 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_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist; + 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; @@ -965,55 +964,59 @@ namespace boost { namespace polygon{ 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, + 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_traits<rectangle_type>::coordinate_type>::unsigned_area_type factor) { - horizontal(rectangle, scale_up(horizontal(rectangle), factor)); - vertical(rectangle, scale_up(vertical(rectangle), factor)); + 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, + 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_traits<rectangle_type>::coordinate_type>::unsigned_area_type factor) { - horizontal(rectangle, scale_down(horizontal(rectangle), factor)); - vertical(rectangle, scale_down(vertical(rectangle), factor)); + 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, + 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_traits<rectangle_type>::coordinate_type> llp(xl(rectangle), yl(rectangle)); - point_data<typename rectangle_traits<rectangle_type>::coordinate_type> urp(xl(rectangle), yl(rectangle)); + 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, + 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_traits<rectangle_type>::coordinate_type> llp(xl(rectangle), yl(rectangle)); - point_data<typename rectangle_traits<rectangle_type>::coordinate_type> urp(xh(rectangle), yh(rectangle)); + 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: @@ -1023,12 +1026,12 @@ namespace boost { namespace polygon{ 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 + bool>::type operator () (const rectangle_type_1& a, const rectangle_type_2& b) const { - typedef typename rectangle_traits<rectangle_type_1>::coordinate_type Unit; - Unit vl1 = get(get(a, orient_), LOW); - Unit vl2 = get(get(b, orient_), LOW); + 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(); @@ -1036,8 +1039,8 @@ namespace boost { namespace polygon{ 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); + 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); @@ -1048,7 +1051,7 @@ namespace boost { namespace polygon{ } return true; } - + }; template <typename T> @@ -1063,7 +1066,7 @@ namespace boost { namespace polygon{ assign(*this, rvalue); return *this; } - + template <class T> template <class T2> bool rectangle_data<T>::operator==(const T2& rvalue) const { @@ -1077,4 +1080,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/rectangle_data.hpp b/boost/polygon/rectangle_data.hpp index 2bcbb461d8..5a1f99e611 100644 --- a/boost/polygon/rectangle_data.hpp +++ b/boost/polygon/rectangle_data.hpp @@ -1,6 +1,6 @@ /* 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). @@ -52,13 +52,12 @@ public: 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); + inline void set(orientation_2d orient, const interval_type_1& interval); private: - interval_data<coordinate_type> ranges_[2]; + interval_data<coordinate_type> ranges_[2]; }; } } #endif - diff --git a/boost/polygon/rectangle_traits.hpp b/boost/polygon/rectangle_traits.hpp index fe777a4fe1..bd494744af 100644 --- a/boost/polygon/rectangle_traits.hpp +++ b/boost/polygon/rectangle_traits.hpp @@ -1,12 +1,15 @@ /* 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> @@ -35,4 +38,3 @@ namespace boost { namespace polygon{ } } #endif - diff --git a/boost/polygon/segment_concept.hpp b/boost/polygon/segment_concept.hpp new file mode 100644 index 0000000000..2f41c1be99 --- /dev/null +++ b/boost/polygon/segment_concept.hpp @@ -0,0 +1,696 @@ +// 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/boost/polygon/segment_data.hpp b/boost/polygon/segment_data.hpp new file mode 100644 index 0000000000..dd317fc4aa --- /dev/null +++ b/boost/polygon/segment_data.hpp @@ -0,0 +1,121 @@ +// 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]) { + 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/boost/polygon/segment_traits.hpp b/boost/polygon/segment_traits.hpp new file mode 100644 index 0000000000..cb092bd408 --- /dev/null +++ b/boost/polygon/segment_traits.hpp @@ -0,0 +1,50 @@ +// 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/boost/polygon/segment_utils.hpp b/boost/polygon/segment_utils.hpp new file mode 100644 index 0000000000..075f7c32d2 --- /dev/null +++ b/boost/polygon/segment_utils.hpp @@ -0,0 +1,164 @@ +/* + 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/boost/polygon/transform.hpp b/boost/polygon/transform.hpp index 16b566d36a..2601cff95a 100644 --- a/boost/polygon/transform.hpp +++ b/boost/polygon/transform.hpp @@ -1,197 +1,60 @@ -/* - 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). -*/ +// 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" -#include "point_3d_concept.hpp" -namespace boost { namespace polygon{ -// Transformation of Coordinate Systems + +namespace boost { +namespace polygon { +// Transformation of Coordinate System. // Enum meaning: -// Select which direction_3d to change the positive direction of each +// 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_3d listed for each enum is the direction to map the +// The first direction_2d listed for each enum is the direction to map the // positive horizontal direction to. -// The second direction_3d listed for each enum is the direction to map the +// The second direction_2d listed for each enum is the direction to map the // positive vertical direction to. -// The third direction_3d listed for each enum is the direction to map the -// positive proximal 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 +// 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. -// Note that the first eight values are the complete set of 2D transforms. -// The 3rd position bit indicates whether the proximal axis flips when -// transformed. -// The 4th position bit indicates whether the proximal and horizontal axis are -// swapped when transformed. It changes the meaning of the 2nd position bit -// to mean that the horizontal and vertical axis are swapped in their new -// positions, naturally. -// The 5th position bit (MSB) indicates whether the proximal and vertical axis -// are swapped when transformed. It is mutually exclusive with the 4th postion -// bit, making the maximum legal value 48 (decimal). It similarly changes the -// meaning of the 2nd position bit to mean that the horizontal and vertical are -// swapped in their new positions. // Enum Values: -// 000000 EAST NORTH UP -// 000001 WEST NORTH UP -// 000010 EAST SOUTH UP -// 000011 WEST SOUTH UP -// 000100 NORTH EAST UP -// 000101 SOUTH EAST UP -// 000110 NORTH WEST UP -// 000111 SOUTH WEST UP -// 001000 EAST NORTH DOWN -// 001001 WEST NORTH DOWN -// 001010 EAST SOUTH DOWN -// 001011 WEST SOUTH DOWN -// 001100 NORTH EAST DOWN -// 001101 SOUTH EAST DOWN -// 001110 NORTH WEST DOWN -// 001111 SOUTH WEST DOWN -// 010000 UP NORTH EAST -// 010001 DOWN NORTH EAST -// 010010 UP SOUTH EAST -// 010011 DOWN SOUTH EAST -// 010100 NORTH UP EAST -// 010101 SOUTH UP EAST -// 010110 NORTH DOWN EAST -// 010111 SOUTH DOWN EAST -// 011000 UP NORTH WEST -// 011001 DOWN NORTH WEST -// 011010 UP SOUTH WEST -// 011011 DOWN SOUTH WEST -// 011100 NORTH UP WEST -// 011101 SOUTH UP WEST -// 011110 NORTH DOWN WEST -// 011111 SOUTH DOWN WEST -// 100000 EAST UP NORTH -// 100001 WEST UP NORTH -// 100010 EAST DOWN NORTH -// 100011 WEST DOWN NORTH -// 100100 UP EAST NORTH -// 100101 DOWN EAST NORTH -// 100110 UP WEST NORTH -// 100111 DOWN WEST NORTH -// 101000 EAST UP SOUTH -// 101001 WEST UP SOUTH -// 101010 EAST DOWN SOUTH -// 101011 WEST DOWN SOUTH -// 101100 UP EAST SOUTH -// 101101 DOWN EAST SOUTH -// 101110 UP WEST SOUTH -// 101111 DOWN WEST SOUTH +// 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 Names and values - // NULL_TRANSFORM = 0, BEGIN_TRANSFORM = 0, - // ENU = 0, EAST_NORTH_UP = 0, EN = 0, EAST_NORTH = 0, - // WNU = 1, WEST_NORTH_UP = 1, WN = 1, WEST_NORTH = 1, FLIP_X = 1, - // ESU = 2, EAST_SOUTH_UP = 2, ES = 2, EAST_SOUTH = 2, FLIP_Y = 2, - // WSU = 3, WEST_SOUTH_UP = 3, WS = 3, WEST_SOUTH = 3, - // NEU = 4, NORTH_EAST_UP = 4, NE = 4, NORTH_EAST = 4, SWAP_XY = 4, - // SEU = 5, SOUTH_EAST_UP = 5, SE = 5, SOUTH_EAST = 5, - // NWU = 6, NORTH_WEST_UP = 6, NW = 6, NORTH_WEST = 6, - // SWU = 7, SOUTH_WEST_UP = 7, SW = 7, SOUTH_WEST = 7, - // END_2D_TRANSFORM = 7, - // END = 8, EAST_NORTH_DOWN = 8, - // WND = 9, WEST_NORTH_DOWN = 9, - // ESD = 10, EAST_SOUTH_DOWN = 10, - // WSD = 11, WEST_SOUTH_DOWN = 11, - // NED = 12, NORTH_EAST_DOWN = 12, - // SED = 13, SOUTH_EAST_DOWN = 13, - // NWD = 14, NORTH_WEST_DOWN = 14, - // SWD = 15, SOUTH_WEST_DOWN = 15, - // UNE = 16, UP_NORTH_EAST = 16, - // DNE = 17, DOWN_NORTH_EAST = 17, - // USE = 18, UP_SOUTH_EAST = 18, - // DSE = 19, DOWN_SOUTH_EAST = 19, - // NUE = 20, NORTH_UP_EAST = 20, - // SUE = 21, SOUTH_UP_EAST = 21, - // NDE = 22, NORTH_DOWN_EAST = 22, - // SDE = 23, SOUTH_DOWN_EAST = 23, - // UNW = 24, UP_NORTH_WEST = 24, - // DNW = 25, DOWN_NORTH_WEST = 25, - // USW = 26, UP_SOUTH_WEST = 26, - // DSW = 27, DOWN_SOUTH_WEST = 27, - // NUW = 28, NORTH_UP_WEST = 28, - // SUW = 29, SOUTH_UP_WEST = 29, - // NDW = 30, NORTH_DOWN_WEST = 30, - // SDW = 31, SOUTH_DOWN_WEST = 31, - // EUN = 32, EAST_UP_NORTH = 32, - // WUN = 33, WEST_UP_NORTH = 33, - // EDN = 34, EAST_DOWN_NORTH = 34, - // WDN = 35, WEST_DOWN_NORTH = 35, - // UEN = 36, UP_EAST_NORTH = 36, - // DEN = 37, DOWN_EAST_NORTH = 37, - // UWN = 38, UP_WEST_NORTH = 38, - // DWN = 39, DOWN_WEST_NORTH = 39, - // EUS = 40, EAST_UP_SOUTH = 40, - // WUS = 41, WEST_UP_SOUTH = 41, - // EDS = 42, EAST_DOWN_SOUTH = 42, - // WDS = 43, WEST_DOWN_SOUTH = 43, - // UES = 44, UP_EAST_SOUTH = 44, - // DES = 45, DOWN_EAST_SOUTH = 45, - // UWS = 46, UP_WEST_SOUTH = 46, - // DWS = 47, DOWN_WEST_SOUTH = 47, END_TRANSFORM = 47 + public: enum ATR { - NULL_TRANSFORM = 0, BEGIN_TRANSFORM = 0, - ENU = 0, EAST_NORTH_UP = 0, EN = 0, EAST_NORTH = 0, - WNU = 1, WEST_NORTH_UP = 1, WN = 1, WEST_NORTH = 1, FLIP_X = 1, - ESU = 2, EAST_SOUTH_UP = 2, ES = 2, EAST_SOUTH = 2, FLIP_Y = 2, - WSU = 3, WEST_SOUTH_UP = 3, WS = 3, WEST_SOUTH = 3, FLIP_XY = 3, - NEU = 4, NORTH_EAST_UP = 4, NE = 4, NORTH_EAST = 4, SWAP_XY = 4, - SEU = 5, SOUTH_EAST_UP = 5, SE = 5, SOUTH_EAST = 5, ROTATE_LEFT = 5, - NWU = 6, NORTH_WEST_UP = 6, NW = 6, NORTH_WEST = 6, ROTATE_RIGHT = 6, - SWU = 7, SOUTH_WEST_UP = 7, SW = 7, SOUTH_WEST = 7, FLIP_SWAP_XY = 7, END_2D_TRANSFORM = 7, - END = 8, EAST_NORTH_DOWN = 8, FLIP_Z = 8, - WND = 9, WEST_NORTH_DOWN = 9, - ESD = 10, EAST_SOUTH_DOWN = 10, - WSD = 11, WEST_SOUTH_DOWN = 11, - NED = 12, NORTH_EAST_DOWN = 12, - SED = 13, SOUTH_EAST_DOWN = 13, - NWD = 14, NORTH_WEST_DOWN = 14, - SWD = 15, SOUTH_WEST_DOWN = 15, - UNE = 16, UP_NORTH_EAST = 16, - DNE = 17, DOWN_NORTH_EAST = 17, - USE = 18, UP_SOUTH_EAST = 18, - DSE = 19, DOWN_SOUTH_EAST = 19, - NUE = 20, NORTH_UP_EAST = 20, - SUE = 21, SOUTH_UP_EAST = 21, - NDE = 22, NORTH_DOWN_EAST = 22, - SDE = 23, SOUTH_DOWN_EAST = 23, - UNW = 24, UP_NORTH_WEST = 24, - DNW = 25, DOWN_NORTH_WEST = 25, - USW = 26, UP_SOUTH_WEST = 26, - DSW = 27, DOWN_SOUTH_WEST = 27, - NUW = 28, NORTH_UP_WEST = 28, - SUW = 29, SOUTH_UP_WEST = 29, - NDW = 30, NORTH_DOWN_WEST = 30, - SDW = 31, SOUTH_DOWN_WEST = 31, - EUN = 32, EAST_UP_NORTH = 32, - WUN = 33, WEST_UP_NORTH = 33, - EDN = 34, EAST_DOWN_NORTH = 34, - WDN = 35, WEST_DOWN_NORTH = 35, - UEN = 36, UP_EAST_NORTH = 36, - DEN = 37, DOWN_EAST_NORTH = 37, - UWN = 38, UP_WEST_NORTH = 38, - DWN = 39, DOWN_WEST_NORTH = 39, - EUS = 40, EAST_UP_SOUTH = 40, - WUS = 41, WEST_UP_SOUTH = 41, - EDS = 42, EAST_DOWN_SOUTH = 42, - WDS = 43, WEST_DOWN_SOUTH = 43, - UES = 44, UP_EAST_SOUTH = 44, - DES = 45, DOWN_EAST_SOUTH = 45, - UWS = 46, UP_WEST_SOUTH = 46, - DWS = 47, DOWN_WEST_SOUTH = 47, END_TRANSFORM = 47 + NULL_TRANSFORM = 0, + BEGIN_TRANSFORM = 0, + EN = 0, EAST_NORTH = 0, + WN = 1, WEST_NORTH = 1, FLIP_X = 1, + ES = 2, EAST_SOUTH = 2, FLIP_Y = 2, + WS = 3, WEST_SOUTH = 3, FLIP_XY = 3, + NE = 4, NORTH_EAST = 4, SWAP_XY = 4, + SE = 5, SOUTH_EAST = 5, ROTATE_LEFT = 5, + NW = 6, NORTH_WEST = 6, ROTATE_RIGHT = 6, + SW = 7, 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 @@ -205,297 +68,399 @@ public: // NX: map to negative x axis // PY: map to positive y axis // NY: map to negative y axis - // PZ: map to positive z axis - // NZ: map to negative z axis enum INDIVIDUAL_AXIS { PX = 0, NX = 1, PY = 2, - NY = 3, - PZ = 4, - NZ = 5 + NY = 3 }; - inline axis_transformation() : atr_(NULL_TRANSFORM) {} - inline axis_transformation(ATR atr) : atr_(atr) {} - inline axis_transformation(const axis_transformation& atr) : atr_(atr.atr_) {} - explicit axis_transformation(const orientation_3d& orient); - explicit axis_transformation(const direction_3d& dir); - explicit axis_transformation(const orientation_2d& orient); - explicit axis_transformation(const direction_2d& dir); + axis_transformation() : atr_(NULL_TRANSFORM) {} + explicit axis_transformation(ATR atr) : atr_(atr) {} + axis_transformation(const axis_transformation& atr) : atr_(atr.atr_) {} - // assignment operator - axis_transformation& operator=(const axis_transformation& a); + 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 ATR& atr); + // 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; + bool operator==(const axis_transformation& a) const { + return atr_ == a.atr_; + } // inequivalence operator - bool operator!=(const axis_transformation& a) const; + bool operator!=(const axis_transformation& a) const { + return !(*this == a); + } // ordering - bool operator<(const axis_transformation& a) const; - - // concatenation operator - axis_transformation operator+(const axis_transformation& a) const; + bool operator<(const axis_transformation& a) const { + return atr_ < a.atr_; + } // concatenate this with that - axis_transformation& operator+=(const axis_transformation& a); + 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; + 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 - inline void get_directions(direction_2d& horizontal_dir, - direction_2d& vertical_dir) const { + 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; + 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)); } - // it is recommended that the directions stored in an array - // in the caller code for easier isotropic access by orientation value - inline void get_directions(direction_3d& horizontal_dir, - direction_3d& vertical_dir, - direction_3d& proximal_dir) const { - bool bit5 = (atr_ & 32) != 0; - bool bit4 = (atr_ & 16) != 0; - bool bit3 = (atr_ & 8) != 0; - bool bit2 = (atr_ & 4) != 0; - bool bit1 = (atr_ & 2) != 0; - bool bit0 = (atr_ & 1) != 0; - proximal_dir = direction_3d((direction_2d_enum)((((int)(!bit4 & !bit5)) << 2) + - ((int)(bit5) << 1) + - !bit3)); - vertical_dir = direction_3d((direction_2d_enum)((((int)((bit4 & bit2) | (bit5 & !bit2))) << 2)+ - ((int)(!bit5 & !bit2) << 1) + - !bit1)); - horizontal_dir = direction_3d((direction_2d_enum)((((int)((bit5 & bit2) | - (bit4 & !bit2))) << 2) + - ((int)(bit2 & !bit5) << 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[]); + 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[]); + 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); - // behavior is deterministic but undefined in the case where illegal // combinations of directions are passed in. - axis_transformation& set_directions(const direction_3d& horizontal_dir, - const direction_3d& vertical_dir, - const direction_3d& proximal_dir); - - // transform the two coordinates by reference using the 2D portion of this - template <typename coordinate_type> - void transform(coordinate_type& x, coordinate_type& y) const; + 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, coordinate_type& z) const; - - // invert the 2D portion of this - axis_transformation& invert_2d(); - - // get the inverse of the 2D portion of this - axis_transformation inverse_2d() const; + 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(); + 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; - - //friend std::ostream& operator<< (std::ostream& o, const axis_transformation& r); - //friend std::istream& operator>> (std::istream& i, axis_transformation& r); + axis_transformation inverse() const { + axis_transformation retval(*this); + return retval.invert(); + } -private: + private: ATR atr_; }; - -// Scaling object to be used to store the scale factor for each axis - +// 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. -// If the horizontal value of the Scale is 10 that means the horizontal -// axis of the input is multiplied by 10 when the transformation is applied. template <typename scale_factor_type> class anisotropic_scale_factor { -public: - inline anisotropic_scale_factor() -#ifndef BOOST_POLYGON_MSVC - : scale_() -#endif - { + public: + anisotropic_scale_factor() { scale_[0] = 1; scale_[1] = 1; - scale_[2] = 1; - } - inline anisotropic_scale_factor(scale_factor_type xscale, scale_factor_type yscale) -#ifndef BOOST_POLYGON_MSVC - : scale_() -#endif - { - scale_[0] = xscale; - scale_[1] = yscale; - scale_[2] = 1; - } - inline anisotropic_scale_factor(scale_factor_type xscale, scale_factor_type yscale, scale_factor_type zscale) -#ifndef BOOST_POLYGON_MSVC - : scale_() -#endif - { + } + anisotropic_scale_factor(scale_factor_type xscale, + scale_factor_type yscale) { scale_[0] = xscale; scale_[1] = yscale; - scale_[2] = zscale; - } + } // get a component of the anisotropic_scale_factor by orientation - scale_factor_type get(orientation_3d orient) const; - scale_factor_type get(orientation_2d orient) const { return get(orientation_3d(orient)); } + 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_3d orient, scale_factor_type value); - void set(orientation_2d orient, scale_factor_type value) { set(orientation_3d(orient), value); } + 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]; + } - scale_factor_type x() const; - scale_factor_type y() const; - scale_factor_type z() const; - void x(scale_factor_type value); - void y(scale_factor_type value); - void z(scale_factor_type value); + 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 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); + 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); + 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; - - // scale the three coordinates - template <typename coordinate_type> - void scale(coordinate_type& x, coordinate_type& y, coordinate_type& z) const; + 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(); - -private: - scale_factor_type scale_[3]; + anisotropic_scale_factor& invert() { + x(1/x()); + y(1/y()); + return *this; + } - //friend std::ostream& operator<< (std::ostream& o, const Scale& r); - //friend std::istream& operator>> (std::istream& i, Scale& r); + private: + scale_factor_type scale_[2]; }; -// Transformation object, stores and provides services for transformations - -// Transformation object stores an axistransformation, a scale factor and a translation. -// The tranlation is the position of the origin of the new system of coordinates in the old system. -// The scale scales the coordinates before they are transformed. +// 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(); - transformation(axis_transformation atr); - transformation(axis_transformation::ATR atr); + 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> - transformation(const point_type& p); + 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); + 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); - transformation(const transformation& tr); + 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; + // equivalence operator + bool operator==(const transformation& tr) const { + return (atr_ == tr.atr_) && (p_ == tr.p_); + } - // inequivalence operator - bool operator!=(const transformation& tr) const; + // inequivalence operator + bool operator!=(const transformation& tr) const { + return !(*this == tr); + } // ordering - bool operator<(const transformation& tr) const; + bool operator<(const transformation& tr) const { + return (atr_ < tr.atr_) || ((atr_ == tr.atr_) && (p_ < tr.p_)); + } - // concatenation operator - transformation operator+(const transformation& tr) const; + // 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); + 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 - inline axis_transformation get_axis_transformation() const {return atr_;} + axis_transformation get_axis_transformation() const { + return atr_; + } // set the axis_transformation portion of this - void set_axis_transformation(const axis_transformation& atr); + void set_axis_transformation(const axis_transformation& atr) { + atr_ = atr; + } - // get the translation portion of this as a point3d + // get the translation template <typename point_type> - void get_translation(point_type& translation) const; + void get_translation(point_type& p) const { + assign(p, p_); + } - // set the translation portion of this with a point3d + // set the translation template <typename point_type> - void set_translation(const point_type& p); + 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; - - // apply this transformation to the three coordinates given - void transform(coordinate_type& x, coordinate_type& y, coordinate_type& z) const; + 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(); - - // get the inverse of this transformation - transformation inverse() const; + 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; + } - inline void get_directions(direction_2d& horizontal_dir, - direction_2d& vertical_dir) const { - return atr_.get_directions(horizontal_dir, vertical_dir); } + // get the inverse of this transformation + transformation inverse() const { + transformation<coordinate_type> ret_val(*this); + return ret_val.invert(); + } - inline void get_directions(direction_3d& horizontal_dir, - direction_3d& vertical_dir, - direction_3d& proximal_dir) const { - return atr_.get_directions(horizontal_dir, vertical_dir, proximal_dir); } + void get_directions(direction_2d& horizontal_dir, + direction_2d& vertical_dir) const { + return atr_.get_directions(horizontal_dir, vertical_dir); + } -private: + private: axis_transformation atr_; - point_3d_data<coordinate_type> p_; - - template <typename point_type> - void construct_dispatch(axis_transformation atr, point_type p, point_concept tag); - template <typename point_type> - void construct_dispatch(axis_transformation atr, point_type p, point_3d_concept tag); - template <typename point_type> - void construct_dispatch(axis_transformation atr, point_type rp, point_type dp, point_concept tag); - template <typename point_type> - void construct_dispatch(axis_transformation atr, point_type rp, point_type dp, point_3d_concept tag); - - //friend std::ostream& operator<< (std::ostream& o, const transformation& tr); - //friend std::istream& operator>> (std::istream& i, transformation& tr); + point_data<coordinate_type> p_; }; -} -} -#include "detail/transform_detail.hpp" -#endif +} // polygon +} // boost +#endif // BOOST_POLYGON_TRANSFORM_HPP diff --git a/boost/polygon/voronoi.hpp b/boost/polygon/voronoi.hpp new file mode 100644 index 0000000000..bca6add873 --- /dev/null +++ b/boost/polygon/voronoi.hpp @@ -0,0 +1,157 @@ +// 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/boost/polygon/voronoi_builder.hpp b/boost/polygon/voronoi_builder.hpp new file mode 100644 index 0000000000..48a06a36e1 --- /dev/null +++ b/boost/polygon/voronoi_builder.hpp @@ -0,0 +1,517 @@ +// 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 (except endpoints). +// Complexity - O(N*logN), memory usage - O(N), where N is the total number +// of input geometries. Input geometries should have integer coordinate type. +// +// IMPLEMENTATION DETAILS: +// Each input point creates one site event. Each input segment creates three +// site events: two for its endpoints and one for the segment itself (this is +// made to simplify output construction). All the site events 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/boost/polygon/voronoi_diagram.hpp b/boost/polygon/voronoi_diagram.hpp new file mode 100644 index 0000000000..7df26ec4e1 --- /dev/null +++ b/boost/polygon/voronoi_diagram.hpp @@ -0,0 +1,620 @@ +// 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. + int site_index1 = site1.sorted_index(); + int 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/boost/polygon/voronoi_geometry_type.hpp b/boost/polygon/voronoi_geometry_type.hpp new file mode 100644 index 0000000000..1de80e59ef --- /dev/null +++ b/boost/polygon/voronoi_geometry_type.hpp @@ -0,0 +1,48 @@ +// 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 |