Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:28:40

0001 /*
0002   Copyright 2008 Intel Corporation
0003 
0004   Use, modification and distribution are subject to the Boost Software License,
0005   Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006   http://www.boost.org/LICENSE_1_0.txt).
0007 */
0008 #ifndef BOOST_POLYGON_BOOLEAN_OP_45_HPP
0009 #define BOOST_POLYGON_BOOLEAN_OP_45_HPP
0010 namespace boost { namespace polygon{
0011 
0012   template <typename Unit>
0013   struct boolean_op_45 {
0014     typedef point_data<Unit> Point;
0015     typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit;
0016 
0017     class Count2 {
0018     public:
0019       inline Count2()
0020 #ifndef BOOST_POLYGON_MSVC
0021       : counts()
0022 #endif
0023       { counts[0] = counts[1] = 0; }
0024       //inline Count2(int count) { counts[0] = counts[1] = count; }
0025       inline Count2(int count1, int count2)
0026 #ifndef BOOST_POLYGON_MSVC
0027       : counts()
0028 #endif
0029       { counts[0] = count1; counts[1] = count2; }
0030       inline Count2(const Count2& count)
0031 #ifndef BOOST_POLYGON_MSVC
0032       : counts()
0033 #endif
0034       { counts[0] = count.counts[0]; counts[1] = count.counts[1]; }
0035       inline bool operator==(const Count2& count) const { return counts[0] == count.counts[0] && counts[1] == count.counts[1]; }
0036       inline bool operator!=(const Count2& count) const { return !((*this) == count); }
0037       inline Count2& operator=(int count) { counts[0] = counts[1] = count; return *this; }
0038       inline Count2& operator=(const Count2& count) { counts[0] = count.counts[0]; counts[1] = count.counts[1]; return *this; }
0039       inline int& operator[](bool index) { return counts[index]; }
0040       inline int operator[](bool index) const {return counts[index]; }
0041       inline Count2& operator+=(const Count2& count){
0042         counts[0] += count[0];
0043         counts[1] += count[1];
0044         return *this;
0045       }
0046       inline Count2& operator-=(const Count2& count){
0047         counts[0] -= count[0];
0048         counts[1] -= count[1];
0049         return *this;
0050       }
0051       inline Count2 operator+(const Count2& count) const {
0052         return Count2(*this)+=count;
0053       }
0054       inline Count2 operator-(const Count2& count) const {
0055         return Count2(*this)-=count;
0056       }
0057       inline Count2 invert() const {
0058         return Count2(-counts[0], -counts[1]);
0059       }
0060     private:
0061       int counts[2];
0062     };
0063 
0064     class Count1 {
0065     public:
0066       inline Count1() : count_(0) { }
0067       inline Count1(int count) : count_(count) { }
0068       inline Count1(const Count1& count) : count_(count.count_) { }
0069       inline bool operator==(const Count1& count) const { return count_ == count.count_; }
0070       inline bool operator!=(const Count1& count) const { return !((*this) == count); }
0071       inline Count1& operator=(int count) { count_ = count; return *this; }
0072       inline Count1& operator=(const Count1& count) { count_ = count.count_; return *this; }
0073       inline Count1& operator+=(const Count1& count){
0074         count_ += count.count_;
0075         return *this;
0076       }
0077       inline Count1& operator-=(const Count1& count){
0078         count_ -= count.count_;
0079         return *this;
0080       }
0081       inline Count1 operator+(const Count1& count) const {
0082         return Count1(*this)+=count;
0083       }
0084       inline Count1 operator-(const Count1& count) const {
0085         return Count1(*this)-=count;
0086       }
0087       inline Count1 invert() const {
0088         return Count1(-count_);
0089       }
0090       int count_;
0091     };
0092 
0093     //     inline std::ostream& operator<< (std::ostream& o, const Count2& c) {
0094     //       o << c[0] << " " << c[1];
0095     //       return o;
0096     //     }
0097 
0098     template <typename CountType>
0099     class Scan45ElementT {
0100     public:
0101       Unit x;
0102       Unit y;
0103       int rise; //-1, 0, +1
0104       mutable CountType count;
0105       inline Scan45ElementT() : x(), y(), rise(), count() {}
0106       inline Scan45ElementT(Unit xIn, Unit yIn, int riseIn, CountType countIn = CountType()) :
0107         x(xIn), y(yIn), rise(riseIn), count(countIn) {}
0108       inline Scan45ElementT(const Scan45ElementT& that) :
0109         x(that.x), y(that.y), rise(that.rise), count(that.count) {}
0110       inline Scan45ElementT& operator=(const Scan45ElementT& that) {
0111         x = that.x; y = that.y; rise = that.rise; count = that.count;
0112         return *this;
0113       }
0114       inline Unit evalAtX(Unit xIn) const {
0115         return y + rise * (xIn - x);
0116       }
0117 
0118       inline bool cross(Point& crossPoint, const Scan45ElementT& edge, Unit currentX) const {
0119         Unit y1 = evalAtX(currentX);
0120         Unit y2 = edge.evalAtX(currentX);
0121         int rise1 = rise;
0122         int rise2 = edge.rise;
0123         if(rise > edge.rise){
0124           if(y1 > y2) return false;
0125         } else if(rise < edge.rise){
0126           if(y2 > y1) return false;
0127           std::swap(y1, y2);
0128           std::swap(rise1, rise2);
0129         } else { return false; }
0130         if(rise1 == 1) {
0131           if(rise2 == 0) {
0132             crossPoint = Point(currentX + y2 - y1, y2);
0133           } else {
0134             //rise2 == -1
0135             Unit delta = (y2 - y1)/2;
0136             crossPoint = Point(currentX + delta, y1 + delta);
0137           }
0138         } else {
0139           //rise1 == 0 and rise2 == -1
0140           crossPoint = Point(currentX + y2 - y1, y1);
0141         }
0142         return true;
0143       }
0144     };
0145 
0146     typedef Scan45ElementT<Count2> Scan45Element;
0147 
0148     //     inline std::ostream& operator<< (std::ostream& o, const Scan45Element& c) {
0149     //       o << c.x << " " << c.y << " " << c.rise << " " << c.count;
0150     //       return o;
0151     //     }
0152 
0153     class lessScan45ElementRise {
0154     public:
0155       typedef Scan45Element first_argument_type;
0156       typedef Scan45Element second_argument_type;
0157       typedef bool result_type;
0158       inline lessScan45ElementRise() {} //default constructor is only constructor
0159       inline bool operator () (Scan45Element elm1, Scan45Element elm2) const {
0160         return elm1.rise < elm2.rise;
0161       }
0162     };
0163 
0164     template <typename CountType>
0165     class lessScan45Element {
0166     private:
0167       Unit *x_; //x value at which to apply comparison
0168       int *justBefore_;
0169     public:
0170       inline lessScan45Element() : x_(0), justBefore_(0) {}
0171       inline lessScan45Element(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {}
0172       inline lessScan45Element(const lessScan45Element& that) : x_(that.x_), justBefore_(that.justBefore_) {}
0173       inline lessScan45Element& operator=(const lessScan45Element& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; }
0174       inline bool operator () (const Scan45ElementT<CountType>& elm1,
0175                                const Scan45ElementT<CountType>& elm2) const {
0176         Unit y1 = elm1.evalAtX(*x_);
0177         Unit y2 = elm2.evalAtX(*x_);
0178         if(y1 < y2) return true;
0179         if(y1 == y2) {
0180           //if justBefore is true we invert the result of the comparison of slopes
0181           if(*justBefore_) {
0182             return elm1.rise > elm2.rise;
0183           } else {
0184             return elm1.rise < elm2.rise;
0185           }
0186         }
0187         return false;
0188       }
0189     };
0190 
0191     template <typename CountType>
0192     class Scan45CountT {
0193     public:
0194       inline Scan45CountT() : counts() {} //counts[0] = counts[1] = counts[2] = counts[3] = 0; }
0195       inline Scan45CountT(CountType count) : counts() { counts[0] = counts[1] = counts[2] = counts[3] = count; }
0196       inline Scan45CountT(const CountType& count1, const CountType& count2, const CountType& count3,
0197                           const CountType& count4) : counts() {
0198         counts[0] = count1;
0199         counts[1] = count2;
0200         counts[2] = count3;
0201         counts[3] = count4;
0202       }
0203       inline Scan45CountT(const Scan45CountT& count) : counts() {
0204         (*this) = count;
0205       }
0206       inline bool operator==(const Scan45CountT& count) const {
0207         for(unsigned int i = 0; i < 4; ++i) {
0208           if(counts[i] != count.counts[i]) return false;
0209         }
0210         return true;
0211       }
0212       inline bool operator!=(const Scan45CountT& count) const { return !((*this) == count); }
0213       inline Scan45CountT& operator=(CountType count) {
0214         counts[0] = counts[1] = counts[2] = counts[3] = count; return *this; }
0215       inline Scan45CountT& operator=(const Scan45CountT& count) {
0216         for(unsigned int i = 0; i < 4; ++i) {
0217           counts[i] = count.counts[i];
0218         }
0219         return *this;
0220       }
0221       inline CountType& operator[](int index) { return counts[index]; }
0222       inline CountType operator[](int index) const {return counts[index]; }
0223       inline Scan45CountT& operator+=(const Scan45CountT& count){
0224         for(unsigned int i = 0; i < 4; ++i) {
0225           counts[i] += count.counts[i];
0226         }
0227         return *this;
0228       }
0229       inline Scan45CountT& operator-=(const Scan45CountT& count){
0230         for(unsigned int i = 0; i < 4; ++i) {
0231           counts[i] -= count.counts[i];
0232         }
0233         return *this;
0234       }
0235       inline Scan45CountT operator+(const Scan45CountT& count) const {
0236         return Scan45CountT(*this)+=count;
0237       }
0238       inline Scan45CountT operator-(const Scan45CountT& count) const {
0239         return Scan45CountT(*this)-=count;
0240       }
0241       inline Scan45CountT invert() const {
0242         return Scan45CountT(CountType())-=(*this);
0243       }
0244       inline Scan45CountT& operator+=(const Scan45ElementT<CountType>& element){
0245         counts[element.rise+1] += element.count; return *this;
0246       }
0247     private:
0248       CountType counts[4];
0249     };
0250 
0251     typedef Scan45CountT<Count2> Scan45Count;
0252 
0253     //     inline std::ostream& operator<< (std::ostream& o, const Scan45Count& c) {
0254     //       o << c[0] << ", " << c[1] << ", ";
0255     //       o << c[2] << ", " << c[3];
0256     //       return o;
0257     //     }
0258 
0259 
0260     //     inline std::ostream& operator<< (std::ostream& o, const Scan45Vertex& c) {
0261     //       o << c.first << ": " << c.second;
0262     //       return o;
0263     //     }
0264 
0265 
0266     //vetex45 is sortable
0267     template <typename ct>
0268     class Vertex45T {
0269     public:
0270       Point pt;
0271       int rise; // 1, 0 or -1
0272       ct count; //dxdydTheta
0273       inline Vertex45T() : pt(), rise(), count() {}
0274       inline Vertex45T(const Point& point, int riseIn, ct countIn) : pt(point), rise(riseIn), count(countIn) {}
0275       inline Vertex45T(const Vertex45T& vertex) : pt(vertex.pt), rise(vertex.rise), count(vertex.count) {}
0276       inline Vertex45T& operator=(const Vertex45T& vertex){
0277         pt = vertex.pt; rise = vertex.rise; count = vertex.count; return *this; }
0278       inline bool operator==(const Vertex45T& vertex) const {
0279         return pt == vertex.pt && rise == vertex.rise && count == vertex.count; }
0280       inline bool operator!=(const Vertex45T& vertex) const { return !((*this) == vertex); }
0281       inline bool operator<(const Vertex45T& vertex) const {
0282         if(pt.x() < vertex.pt.x()) return true;
0283         if(pt.x() == vertex.pt.x()) {
0284           if(pt.y() < vertex.pt.y()) return true;
0285           if(pt.y() == vertex.pt.y()) { return rise < vertex.rise; }
0286         }
0287         return false;
0288       }
0289       inline bool operator>(const Vertex45T& vertex) const { return vertex < (*this); }
0290       inline bool operator<=(const Vertex45T& vertex) const { return !((*this) > vertex); }
0291       inline bool operator>=(const Vertex45T& vertex) const { return !((*this) < vertex); }
0292       inline Unit evalAtX(Unit xIn) const { return pt.y() + rise * (xIn - pt.x()); }
0293     };
0294 
0295     typedef Vertex45T<int> Vertex45;
0296 
0297     //     inline std::ostream& operator<< (std::ostream& o, const Vertex45& c) {
0298     //       o << c.pt << " " << c.rise << " " << c.count;
0299     //       return o;
0300     //     }
0301 
0302     //when scanning Vertex45 for polygon formation we need a scanline comparator functor
0303     class lessVertex45 {
0304     private:
0305       Unit *x_; //x value at which to apply comparison
0306       int *justBefore_;
0307     public:
0308       inline lessVertex45() : x_(0), justBefore_() {}
0309 
0310       inline lessVertex45(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {}
0311 
0312       inline lessVertex45(const lessVertex45& that) : x_(that.x_), justBefore_(that.justBefore_) {}
0313 
0314       inline lessVertex45& operator=(const lessVertex45& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; }
0315 
0316       template <typename ct>
0317       inline bool operator () (const Vertex45T<ct>& elm1, const Vertex45T<ct>& elm2) const {
0318         Unit y1 = elm1.evalAtX(*x_);
0319         Unit y2 = elm2.evalAtX(*x_);
0320         if(y1 < y2) return true;
0321         if(y1 == y2) {
0322           //if justBefore is true we invert the result of the comparison of slopes
0323           if(*justBefore_) {
0324             return elm1.rise > elm2.rise;
0325           } else {
0326             return elm1.rise < elm2.rise;
0327           }
0328         }
0329         return false;
0330       }
0331     };
0332 
0333     // 0 right to left
0334     // 1 upper right to lower left
0335     // 2 high to low
0336     // 3 upper left to lower right
0337     // 4 left to right
0338     // 5 lower left to upper right
0339     // 6 low to high
0340     // 7 lower right to upper left
0341     static inline int classifyEdge45(const Point& prevPt, const Point& nextPt) {
0342       if(prevPt.x() == nextPt.x()) {
0343         //2 or 6
0344         return predicated_value(prevPt.y() < nextPt.y(), 6, 2);
0345       }
0346       if(prevPt.y() == nextPt.y()) {
0347         //0 or 4
0348         return predicated_value(prevPt.x() < nextPt.x(), 4, 0);
0349       }
0350       if(prevPt.x() < nextPt.x()) {
0351         //3 or 5
0352         return predicated_value(prevPt.y() < nextPt.y(), 5, 3);
0353       }
0354       //prevPt.x() > nextPt.y()
0355       //1 or 7
0356       return predicated_value(prevPt.y() < nextPt.y(), 7, 1);
0357     }
0358 
0359     template <int op, typename CountType>
0360     static int applyLogic(CountType count1, CountType count2){
0361       bool l1 = applyLogic<op>(count1);
0362       bool l2 = applyLogic<op>(count2);
0363       if(l1 && !l2)
0364         return -1; //was true before and became false like a trailing edge
0365       if(!l1 && l2)
0366         return 1; //was false before and became true like a leading edge
0367       return 0; //no change in logic between the two counts
0368     }
0369     template <int op>
0370     static bool applyLogic(Count2 count) {
0371 #ifdef BOOST_POLYGON_MSVC
0372 #pragma warning (push)
0373 #pragma warning (disable: 4127)
0374 #endif
0375       if(op == 0) { //apply or
0376         return count[0] > 0 || count[1] > 0;
0377       } else if(op == 1) { //apply and
0378         return count[0] > 0 && count[1] > 0;
0379       } else if(op == 2) { //apply not
0380         return count[0] > 0 && !(count[1] > 0);
0381       } else if(op == 3) { //apply xor
0382         return (count[0] > 0) ^ (count[1] > 0);
0383       } else
0384         return false;
0385 #ifdef BOOST_POLYGON_MSVC
0386 #pragma warning (pop)
0387 #endif
0388     }
0389 
0390     template <int op>
0391     struct boolean_op_45_output_functor {
0392       template <typename cT>
0393       void operator()(cT& output, const Count2& count1, const Count2& count2,
0394                       const Point& pt, int rise, direction_1d end) {
0395         int edgeType = applyLogic<op>(count1, count2);
0396         if(edgeType) {
0397           int multiplier = end == LOW ? -1 : 1;
0398           //std::cout << "cross logic: " << edgeType << "\n";
0399           output.insert(output.end(), Vertex45(pt, rise, edgeType * multiplier));
0400           //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n";
0401         }
0402       }
0403     };
0404 
0405     template <int op>
0406     static bool applyLogic(Count1 count) {
0407 #ifdef BOOST_POLYGON_MSVC
0408 #pragma warning (push)
0409 #pragma warning (disable: 4127)
0410 #endif
0411       if(op == 0) { //apply or
0412         return count.count_ > 0;
0413       } else if(op == 1) { //apply and
0414         return count.count_ > 1;
0415       } else if(op == 3) { //apply xor
0416         return (count.count_ % 2) != 0;
0417       } else
0418         return false;
0419 #ifdef BOOST_POLYGON_MSVC
0420 #pragma warning (pop)
0421 #endif
0422     }
0423 
0424     template <int op>
0425     struct unary_op_45_output_functor {
0426       template <typename cT>
0427       void operator()(cT& output, const Count1& count1, const Count1& count2,
0428                       const Point& pt, int rise, direction_1d end) {
0429         int edgeType = applyLogic<op>(count1, count2);
0430         if(edgeType) {
0431           int multiplier = end == LOW ? -1 : 1;
0432           //std::cout << "cross logic: " << edgeType << "\n";
0433           output.insert(output.end(), Vertex45(pt, rise, edgeType * multiplier));
0434           //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n";
0435         }
0436       }
0437     };
0438 
0439     class lessScan45Vertex {
0440     public:
0441       inline lessScan45Vertex() {} //default constructor is only constructor
0442       template <typename Scan45Vertex>
0443       inline bool operator () (const Scan45Vertex& v1, const Scan45Vertex& v2) const {
0444         return (v1.first.x() < v2.first.x()) || (v1.first.x() == v2.first.x() && v1.first.y() < v2.first.y());
0445       }
0446     };
0447     template <typename S45V>
0448     static inline void sortScan45Vector(S45V& vec) {
0449       polygon_sort(vec.begin(), vec.end(), lessScan45Vertex());
0450     }
0451 
0452     template <typename CountType, typename output_functor>
0453     class Scan45 {
0454     public:
0455       typedef Scan45CountT<CountType> Scan45Count;
0456       typedef std::pair<Point, Scan45Count> Scan45Vertex;
0457 
0458       //index is the index into the vertex
0459       static inline Scan45Element getElement(const Scan45Vertex& vertex, int index) {
0460         return Scan45Element(vertex.first.x(), vertex.first.y(), index - 1, vertex.second[index]);
0461       }
0462 
0463       class lessScan45Point {
0464       public:
0465       typedef Point first_argument_type;
0466       typedef Point second_argument_type;
0467       typedef bool result_type;
0468         inline lessScan45Point() {} //default constructor is only constructor
0469         inline bool operator () (const Point& v1, const Point& v2) const {
0470           return (v1.x() < v2.x()) || (v1.x() == v2.x() && v1.y() < v2.y());
0471         }
0472       };
0473 
0474       typedef std::vector<Scan45Vertex> Scan45Vector;
0475 
0476       //definitions
0477       typedef std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> > Scan45Data;
0478       typedef typename Scan45Data::iterator iterator;
0479       typedef typename Scan45Data::const_iterator const_iterator;
0480       typedef std::set<Point, lessScan45Point> CrossQueue;
0481 
0482       //data
0483       Scan45Data scanData_;
0484       CrossQueue crossQueue_;
0485       Scan45Vector crossVector_;
0486       Unit x_;
0487       int justBefore_;
0488     public:
0489       inline Scan45() : scanData_(), crossQueue_(), crossVector_(),
0490                         x_((std::numeric_limits<Unit>::min)()), justBefore_(false) {
0491         lessScan45Element<CountType>  lessElm(&x_, &justBefore_);
0492         scanData_ = std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >(lessElm);
0493       }
0494       inline Scan45(const Scan45& that) : scanData_(), crossQueue_(), crossVector_(),
0495                                           x_((std::numeric_limits<Unit>::min)()), justBefore_(false) {
0496         (*this) = that; }
0497       inline Scan45& operator=(const Scan45& that) {
0498         x_ = that.x_;
0499         justBefore_ = that.justBefore_;
0500         crossQueue_ = that.crossQueue_;
0501         crossVector_ = that.crossVector_;
0502         lessScan45Element<CountType>  lessElm(&x_, &justBefore_);
0503         scanData_ = std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >(lessElm);
0504         for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
0505           scanData_.insert(scanData_.end(), *itr);
0506         }
0507         return *this;
0508       }
0509 
0510       //cT is an output container of Vertex45
0511       //iT is an iterator over Scan45Vertex elements
0512       template <class cT, class iT>
0513       void scan(cT& output, iT inputBegin, iT inputEnd) {
0514         //std::cout << "1\n";
0515         while(inputBegin != inputEnd) {
0516           //std::cout << "2\n";
0517           //std::cout << "x_ = " << x_ << "\n";
0518           //std::cout << "scan line size: " << scanData_.size() << "\n";
0519           //for(iterator iter = scanData_.begin();
0520           //     iter != scanData_.end(); ++iter) {
0521           //   std::cout << "scan element\n";
0522           //   std::cout << *iter << " " << iter->evalAtX(x_) << "\n";
0523           // }
0524           // std::cout << "cross queue size: " << crossQueue_.size() << "\n";
0525           // std::cout << "cross vector size: " << crossVector_.size() << "\n";
0526           //for(CrossQueue::iterator cqitr = crossQueue_.begin(); cqitr != crossQueue_.end(); ++cqitr) {
0527           //   std::cout << *cqitr << " ";
0528           //} std::cout << "\n";
0529           Unit nextX = (*inputBegin).first.x();
0530           if(!crossVector_.empty() && crossVector_[0].first.x() < nextX) nextX = crossVector_[0].first.x();
0531           if(nextX != x_) {
0532             //std::cout << "3\n";
0533             //we need to move to the next scanline stop
0534             //we need to process end events then cross events
0535             //process end events
0536             if(!crossQueue_.empty() &&
0537                (*crossQueue_.begin()).x() < nextX) {
0538               //std::cout << "4\n";
0539               nextX = (std::min)(nextX, (*crossQueue_.begin()).x());
0540             }
0541             //std::cout << "6\n";
0542             justBefore_ = true;
0543             x_ = nextX;
0544             advance_(output);
0545             justBefore_ = false;
0546             if(!crossVector_.empty() &&
0547                nextX == (*inputBegin).first.x()) {
0548               inputBegin = mergeCross_(inputBegin, inputEnd);
0549             }
0550             processEvent_(output, crossVector_.begin(), crossVector_.end());
0551             crossVector_.clear();
0552           } else {
0553             //std::cout << "7\n";
0554             //our scanline has progressed to the event that is next in the queue
0555             inputBegin = processEvent_(output, inputBegin, inputEnd);
0556           }
0557         }
0558         //std::cout << "done scanning\n";
0559       }
0560 
0561     private:
0562       //functions
0563 
0564       template <class cT>
0565       inline void advance_(cT& output) {
0566         //process all cross points on the cross queue at the current x_
0567         //std::cout << "advance_\n";
0568         std::vector<iterator> eraseVec;
0569         while(!crossQueue_.empty() &&
0570               (*crossQueue_.begin()).x() == x_){
0571           //std::cout << "loop\n";
0572           //pop point off the cross queue
0573           Point crossPoint = *(crossQueue_.begin());
0574           //std::cout << crossPoint << "\n";
0575           //for(iterator iter = scanData_.begin();
0576           //    iter != scanData_.end(); ++iter) {
0577           //  std::cout << "scan element\n";
0578           //  std::cout << *iter << " " << iter->evalAtX(x_) << "\n";
0579           //}
0580           crossQueue_.erase(crossQueue_.begin());
0581           Scan45Vertex vertex(crossPoint, Scan45Count());
0582           iterator lowIter = lookUp_(vertex.first.y());
0583           //std::cout << "searching at: " << vertex.first.y() << "\n";
0584           //if(lowIter == scanData_.end()) std::cout << "could not find\n";
0585           //else std::cout << "found: " << *lowIter << "\n";
0586           if(lowIter == scanData_.end() ||
0587              lowIter->evalAtX(x_) != vertex.first.y()) {
0588             //   std::cout << "skipping\n";
0589             //there weren't any edges at this potential cross point
0590             continue;
0591           }
0592           CountType countBelow;
0593           iterator searchDownItr = lowIter;
0594           while(searchDownItr != scanData_.begin()
0595                 && searchDownItr->evalAtX(x_) == vertex.first.y()) {
0596             //get count from below
0597             --searchDownItr;
0598             countBelow = searchDownItr->count;
0599           }
0600           //std::cout << "Below Count: " << countBelow << "\n";
0601           Scan45Count count(countBelow);
0602           std::size_t numEdges = 0;
0603           iterator eraseItrs[3];
0604           while(lowIter != scanData_.end() &&
0605                 lowIter->evalAtX(x_) == vertex.first.y()) {
0606             for(int index = lowIter->rise +1; index >= 0; --index)
0607               count[index] = lowIter->count;
0608             //std::cout << count << "\n";
0609             eraseItrs[numEdges] = lowIter;
0610             ++numEdges;
0611             ++lowIter;
0612           }
0613           if(numEdges == 1) {
0614             //look for the next crossing point and continue
0615             //std::cout << "found only one edge\n";
0616             findCross_(eraseItrs[0]);
0617             continue;
0618           }
0619           //before we erase the elements we need to decide if they should be written out
0620           CountType currentCount = countBelow;
0621           for(std::size_t i = 0; i < numEdges; ++i) {
0622             output_functor f;
0623             f(output, currentCount, eraseItrs[i]->count, crossPoint, eraseItrs[i]->rise, LOW);
0624             currentCount = eraseItrs[i]->count;
0625           }
0626           //schedule erase of the elements
0627           for(std::size_t i = 0; i < numEdges; ++i) {
0628             eraseVec.push_back(eraseItrs[i]);
0629           }
0630 
0631           //take the derivative wrt theta of the count at the crossing point
0632           vertex.second[2] = count[2] - countBelow;
0633           vertex.second[1] = count[1] - count[2];
0634           vertex.second[0] = count[0] - count[1];
0635           //add the point, deriviative pair into the cross vector
0636           //std::cout << "LOOK HERE!\n";
0637           //std::cout << count << "\n";
0638           //std::cout << vertex << "\n";
0639           crossVector_.push_back(vertex);
0640         }
0641         //erase crossing elements
0642         std::vector<iterator> searchVec;
0643         for(std::size_t i = 0; i < eraseVec.size(); ++i) {
0644           if(eraseVec[i] != scanData_.begin()) {
0645             iterator searchItr = eraseVec[i];
0646             --searchItr;
0647             if(searchVec.empty() ||
0648                searchVec.back() != searchItr)
0649               searchVec.push_back(searchItr);
0650           }
0651           scanData_.erase(eraseVec[i]);
0652         }
0653         for(std::size_t i = 0; i < searchVec.size(); ++i) {
0654           findCross_(searchVec[i]);
0655         }
0656       }
0657 
0658       template <class iT>
0659       inline iT mergeCross_(iT inputBegin, iT inputEnd) {
0660         Scan45Vector vec;
0661         swap(vec, crossVector_);
0662         iT mergeEnd = inputBegin;
0663         std::size_t mergeCount = 0;
0664         while(mergeEnd != inputEnd &&
0665               (*mergeEnd).first.x() == x_) {
0666           ++mergeCount;
0667           ++mergeEnd;
0668         }
0669         crossVector_.reserve((std::max)(vec.capacity(), vec.size() + mergeCount));
0670         for(std::size_t i = 0; i < vec.size(); ++i){
0671           while(inputBegin != mergeEnd &&
0672                 (*inputBegin).first.y() < vec[i].first.y()) {
0673             crossVector_.push_back(*inputBegin);
0674             ++inputBegin;
0675           }
0676           crossVector_.push_back(vec[i]);
0677         }
0678         while(inputBegin != mergeEnd){
0679           crossVector_.push_back(*inputBegin);
0680           ++inputBegin;
0681         }
0682         return inputBegin;
0683       }
0684 
0685       template <class cT, class iT>
0686       inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
0687         //std::cout << "processEvent_\n";
0688         CountType verticalCount = CountType();
0689         Point prevPoint;
0690         iterator prevIter = scanData_.end();
0691         while(inputBegin != inputEnd &&
0692               (*inputBegin).first.x() == x_) {
0693           //std::cout << (*inputBegin) << "\n";
0694           //std::cout << "loop\n";
0695           Scan45Vertex vertex = *inputBegin;
0696           //std::cout << vertex.first << "\n";
0697           //if vertical count propigating up fake a null event at the next element
0698           if(verticalCount != CountType() && (prevIter != scanData_.end() &&
0699                                               prevIter->evalAtX(x_) < vertex.first.y())) {
0700             //std::cout << "faking null event\n";
0701             vertex = Scan45Vertex(Point(x_, prevIter->evalAtX(x_)), Scan45Count());
0702           } else {
0703             ++inputBegin;
0704             //std::cout << "after increment\n";
0705             //accumulate overlapping changes in Scan45Count
0706             while(inputBegin != inputEnd &&
0707                   (*inputBegin).first.x() == x_ &&
0708                   (*inputBegin).first.y() == vertex.first.y()) {
0709               //std::cout << "accumulate\n";
0710               vertex.second += (*inputBegin).second;
0711               ++inputBegin;
0712             }
0713           }
0714           //std::cout << vertex.second << "\n";
0715           //integrate vertex
0716           CountType currentCount = verticalCount;// + vertex.second[0];
0717           for(unsigned int i = 0; i < 3; ++i) {
0718             vertex.second[i] = currentCount += vertex.second[i];
0719           }
0720           //std::cout << vertex.second << "\n";
0721           //vertex represents the change in state at this point
0722 
0723           //get counts at current vertex
0724           CountType countBelow;
0725           iterator lowIter = lookUp_(vertex.first.y());
0726           if(lowIter != scanData_.begin()) {
0727             //get count from below
0728             --lowIter;
0729             countBelow = lowIter->count;
0730             ++lowIter;
0731           }
0732           //std::cout << "Count Below: " << countBelow[0] << " " << countBelow[1] << "\n";
0733           //std::cout << "vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n";
0734           Scan45Count countAt(countBelow - verticalCount);
0735           //check if the vertical edge should be written out
0736           if(verticalCount != CountType()) {
0737             output_functor f;
0738             f(output, countBelow - verticalCount, countBelow, prevPoint, 2, HIGH);
0739             f(output, countBelow - verticalCount, countBelow, vertex.first, 2, LOW);
0740           }
0741           currentCount = countBelow - verticalCount;
0742           while(lowIter != scanData_.end() &&
0743                 lowIter->evalAtX(x_) == vertex.first.y()) {
0744             for(unsigned int i = lowIter->rise + 1; i < 3; ++i) {
0745               countAt[i] = lowIter->count;
0746             }
0747             Point lp(lowIter->x, lowIter->y);
0748             if(lp != vertex.first) {
0749               output_functor f;
0750               f(output, currentCount, lowIter->count, vertex.first, lowIter->rise, LOW);
0751             }
0752             currentCount = lowIter->count;
0753             iterator nextIter = lowIter;
0754             ++nextIter;
0755             //std::cout << "erase\n";
0756             scanData_.erase(lowIter);
0757             if(nextIter != scanData_.end())
0758               findCross_(nextIter);
0759             lowIter = nextIter;
0760           }
0761           verticalCount += vertex.second[3];
0762           prevPoint = vertex.first;
0763           //std::cout << "new vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n";
0764           prevIter = lowIter;
0765           //count represents the current state at this point
0766           //std::cout << vertex.second << "\n";
0767           //std::cout << countAt << "\n";
0768           //std::cout << "ADD\n";
0769           vertex.second += countAt;
0770           //std::cout << vertex.second << "\n";
0771 
0772           //add elements to the scanline
0773           for(int i = 0; i < 3; ++i) {
0774             if(vertex.second[i] != countBelow) {
0775               //std::cout << "insert: " << vertex.first.x() << " " << vertex.first.y() << " " << i-1 <<
0776               //  " " << vertex.second[i][0] << " " << vertex.second[i][1] << "\n";
0777               iterator insertIter = scanData_.insert(scanData_.end(),
0778                                                      Scan45ElementT<CountType>(vertex.first.x(),
0779                                                                                vertex.first.y(),
0780                                                                                i - 1, vertex.second[i]));
0781               findCross_(insertIter);
0782               output_functor f;
0783               f(output, countBelow, vertex.second[i], vertex.first, i - 1, HIGH);
0784             }
0785             countBelow = vertex.second[i];
0786           }
0787         }
0788         //std::cout << "end processEvent\n";
0789         return inputBegin;
0790       }
0791 
0792       //iter1 is horizontal
0793       inline void scheduleCross0_(iterator iter1, iterator iter2) {
0794         //std::cout << "0, ";
0795         Unit y1 = iter1->evalAtX(x_);
0796         Unit y2 = iter2->evalAtX(x_);
0797         LongUnit delta = local_abs(LongUnit(y1) - LongUnit(y2));
0798         if(delta + static_cast<LongUnit>(x_) <= (std::numeric_limits<Unit>::max)())
0799           crossQueue_.insert(crossQueue_.end(), Point(x_ + static_cast<Unit>(delta), y1));
0800         //std::cout <<  Point(x_ + delta, y1);
0801       }
0802 
0803       //neither iter is horizontal
0804       inline void scheduleCross1_(iterator iter1, iterator iter2) {
0805         //std::cout << "1, ";
0806         Unit y1 = iter1->evalAtX(x_);
0807         Unit y2 = iter2->evalAtX(x_);
0808         //std::cout << y1 << " " << y2 << ": ";
0809         //note that half the delta cannot exceed the positive inter range
0810         LongUnit delta = y1;
0811         delta -= y2;
0812         Unit UnitMax = (std::numeric_limits<Unit>::max)();
0813         if((delta & 1) == 1) {
0814           //delta is odd, division by 2 will result in integer trunctaion
0815           if(delta == 1) {
0816             //the cross point is not on the integer grid and cannot be represented
0817             //we must throw an exception
0818             std::string msg = "GTL 45 Boolean error, precision insufficient to represent edge intersection coordinate value.";
0819             throw(msg);
0820           } else {
0821             //note that result of this subtraction is always positive because itr1 is above itr2 in scanline
0822             LongUnit halfDelta2 = (LongUnit)((((LongUnit)y1) - y2)/2);
0823             //note that halfDelta2 has been truncated
0824             if(halfDelta2 + x_ <= UnitMax && halfDelta2 + y2 <= UnitMax) {
0825               crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta2), y2+static_cast<Unit>(halfDelta2)));
0826               crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta2), y2+static_cast<Unit>(halfDelta2)+1));
0827             }
0828           }
0829         } else {
0830           LongUnit halfDelta = (LongUnit)((((LongUnit)y1) - y2)/2);
0831           if(halfDelta + x_ <= UnitMax && halfDelta + y2 <= UnitMax)
0832             crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta), y2+static_cast<Unit>(halfDelta)));
0833           //std::cout << Point(x_+halfDelta, y2+halfDelta);
0834         }
0835       }
0836 
0837       inline void findCross_(iterator iter) {
0838         //std::cout << "find cross ";
0839         iterator iteratorBelow = iter;
0840         iterator iteratorAbove = iter;
0841         if(iter != scanData_.begin() && iter->rise < 1) {
0842           --iteratorBelow;
0843           if(iter->rise == 0){
0844             if(iteratorBelow->rise == 1) {
0845               scheduleCross0_(iter, iteratorBelow);
0846             }
0847           } else {
0848             //iter->rise == -1
0849             if(iteratorBelow->rise == 1) {
0850               scheduleCross1_(iter, iteratorBelow);
0851             } else if(iteratorBelow->rise == 0) {
0852               scheduleCross0_(iteratorBelow, iter);
0853             }
0854           }
0855         }
0856         ++iteratorAbove;
0857         if(iteratorAbove != scanData_.end() && iter->rise > -1) {
0858           if(iter->rise == 0) {
0859             if(iteratorAbove->rise == -1) {
0860               scheduleCross0_(iter, iteratorAbove);
0861             }
0862           } else {
0863             //iter->rise == 1
0864             if(iteratorAbove->rise == -1) {
0865               scheduleCross1_(iteratorAbove, iter);
0866             } else if(iteratorAbove->rise == 0) {
0867               scheduleCross0_(iteratorAbove, iter);
0868             }
0869           }
0870         }
0871         //std::cout << "\n";
0872       }
0873 
0874       inline iterator lookUp_(Unit y){
0875         //if just before then we need to look from 1 not -1
0876         return scanData_.lower_bound(Scan45ElementT<CountType>(x_, y, -1+2*justBefore_));
0877       }
0878     };
0879 
0880     //template <typename CountType>
0881     //static inline void print45Data(const std::set<Scan45ElementT<CountType>,
0882     //                               lessScan45Element<CountType> >& data) {
0883     //  typename std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >::const_iterator iter;
0884     //  for(iter = data.begin(); iter != data.end(); ++iter) {
0885     //    std::cout << iter->x << " " << iter->y << " " << iter->rise << "\n";
0886     //  }
0887     //}
0888 
0889     template <typename streamtype>
0890     static inline bool testScan45Data(streamtype& stdcout) {
0891       Unit x = 0;
0892       int justBefore = false;
0893       lessScan45Element<Count2> lessElm(&x, &justBefore);
0894       std::set<Scan45ElementT<Count2>, lessScan45Element<Count2> > testData(lessElm);
0895       //Unit size = testData.size();
0896       typedef std::set<Scan45ElementT<Count2>, lessScan45Element<Count2> > Scan45Data;
0897       typename Scan45Data::iterator itr10 = testData.insert(testData.end(), Scan45Element(0, 10, 1));
0898       typename Scan45Data::iterator itr20 = testData.insert(testData.end(), Scan45Element(0, 20, 1));
0899       typename Scan45Data::iterator itr30 = testData.insert(testData.end(), Scan45Element(0, 30, -1));
0900       typename Scan45Data::iterator itr40 = testData.insert(testData.end(), Scan45Element(0, 40, -1));
0901       typename Scan45Data::iterator itrA = testData.lower_bound(Scan45Element(0, 29, -1));
0902       typename Scan45Data::iterator itr1 = testData.lower_bound(Scan45Element(0, 10, -1));
0903       x = 4;
0904       //now at 14 24 26 36
0905       typename Scan45Data::iterator itrB = testData.lower_bound(Scan45Element(4, 29, -1));
0906       typename Scan45Data::iterator itr2 = testData.lower_bound(Scan45Element(4, 14, -1));
0907       if(itr1 != itr2) stdcout << "test1 failed\n";
0908       if(itrA == itrB) stdcout << "test2 failed\n";
0909       //remove crossing elements
0910       testData.erase(itr20);
0911       testData.erase(itr30);
0912       x = 5;
0913       itr20 = testData.insert(testData.end(), Scan45Element(0, 20, 1));
0914       itr30 = testData.insert(testData.end(), Scan45Element(0, 30, -1));
0915       //now at 15 25 25 35
0916       typename Scan45Data::iterator itr = testData.begin();
0917       if(itr != itr10) stdcout << "test3 failed\n";
0918       ++itr;
0919       if(itr != itr30) stdcout << "test4 failed\n";
0920       ++itr;
0921       if(itr != itr20) stdcout << "test5 failed\n";
0922       ++itr;
0923       if(itr != itr40) stdcout << "test6 failed\n";
0924       stdcout << "done testing Scan45Data\n";
0925       return true;
0926     }
0927 
0928     template <typename stream_type>
0929     static inline bool testScan45Rect(stream_type& stdcout) {
0930       stdcout << "testing Scan45Rect\n";
0931       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
0932       std::vector<Vertex45 > result;
0933       typedef std::pair<Point, Scan45Count> Scan45Vertex;
0934       std::vector<Scan45Vertex> vertices;
0935       //is a Rectnagle(0, 0, 10, 10);
0936       Count2 count(1, 0);
0937       Count2 ncount(-1, 0);
0938       vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
0939       vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
0940       vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
0941       vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
0942       stdcout << "scanning\n";
0943       scan45.scan(result, vertices.begin(), vertices.end());
0944       stdcout << "done scanning\n";
0945       // result size == 8
0946       // result == 0 0 0 1
0947       // result == 0 0 2 1
0948       // result == 0 10 2 -1
0949       // result == 0 10 0 -1
0950       // result == 10 0 0 -1
0951       // result == 10 0 2 -1
0952       // result == 10 10 2 1
0953       // result == 10 10 0 1
0954       std::vector<Vertex45> reference;
0955       reference.push_back(Vertex45(Point(0, 0), 0, 1));
0956       reference.push_back(Vertex45(Point(0, 0), 2, 1));
0957       reference.push_back(Vertex45(Point(0, 10), 2, -1));
0958       reference.push_back(Vertex45(Point(0, 10), 0, -1));
0959       reference.push_back(Vertex45(Point(10, 0), 0, -1));
0960       reference.push_back(Vertex45(Point(10, 0), 2, -1));
0961       reference.push_back(Vertex45(Point(10, 10), 2, 1));
0962       reference.push_back(Vertex45(Point(10, 10), 0, 1));
0963       if(result != reference) {
0964         stdcout << "result size == " << result.size() << "\n";
0965         for(std::size_t i = 0; i < result.size(); ++i) {
0966           //std::cout << "result == " << result[i]<< "\n";
0967         }
0968         stdcout << "reference size == " << reference.size() << "\n";
0969         for(std::size_t i = 0; i < reference.size(); ++i) {
0970           //std::cout << "reference == " << reference[i]<< "\n";
0971         }
0972         return false;
0973       }
0974       stdcout << "done testing Scan45Rect\n";
0975       return true;
0976     }
0977 
0978     template <typename stream_type>
0979     static inline bool testScan45P1(stream_type& stdcout) {
0980       stdcout << "testing Scan45P1\n";
0981       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
0982       std::vector<Vertex45 > result;
0983       typedef std::pair<Point, Scan45Count> Scan45Vertex;
0984       std::vector<Scan45Vertex> vertices;
0985       //is a Rectnagle(0, 0, 10, 10);
0986       Count2 count(1, 0);
0987       Count2 ncount(-1, 0);
0988       vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
0989       vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), Count2(0, 0), ncount, ncount)));
0990       vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), Count2(0, 0), ncount, ncount)));
0991       vertices.push_back(Scan45Vertex(Point(10,20), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
0992       stdcout << "scanning\n";
0993       scan45.scan(result, vertices.begin(), vertices.end());
0994       stdcout << "done scanning\n";
0995       // result size == 8
0996       // result == 0 0 1 1
0997       // result == 0 0 2 1
0998       // result == 0 10 2 -1
0999       // result == 0 10 1 -1
1000       // result == 10 10 1 -1
1001       // result == 10 10 2 -1
1002       // result == 10 20 2 1
1003       // result == 10 20 1 1
1004       std::vector<Vertex45> reference;
1005       reference.push_back(Vertex45(Point(0, 0), 1, 1));
1006       reference.push_back(Vertex45(Point(0, 0), 2, 1));
1007       reference.push_back(Vertex45(Point(0, 10), 2, -1));
1008       reference.push_back(Vertex45(Point(0, 10), 1, -1));
1009       reference.push_back(Vertex45(Point(10, 10), 1, -1));
1010       reference.push_back(Vertex45(Point(10, 10), 2, -1));
1011       reference.push_back(Vertex45(Point(10, 20), 2, 1));
1012       reference.push_back(Vertex45(Point(10, 20), 1, 1));
1013       if(result != reference) {
1014         stdcout << "result size == " << result.size() << "\n";
1015         for(std::size_t i = 0; i < result.size(); ++i) {
1016           //std::cout << "result == " << result[i]<< "\n";
1017         }
1018         stdcout << "reference size == " << reference.size() << "\n";
1019         for(std::size_t i = 0; i < reference.size(); ++i) {
1020           //std::cout << "reference == " << reference[i]<< "\n";
1021         }
1022         return false;
1023       }
1024       stdcout << "done testing Scan45P1\n";
1025       return true;
1026     }
1027 
1028     template <typename stream_type>
1029     static inline bool testScan45P2(stream_type& stdcout) {
1030       stdcout << "testing Scan45P2\n";
1031       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
1032       std::vector<Vertex45 > result;
1033       typedef std::pair<Point, Scan45Count> Scan45Vertex;
1034       std::vector<Scan45Vertex> vertices;
1035       //is a Rectnagle(0, 0, 10, 10);
1036       Count2 count(1, 0);
1037       Count2 ncount(-1, 0);
1038       vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
1039       vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, count, Count2(0, 0))));
1040       vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), ncount, count, Count2(0, 0))));
1041       vertices.push_back(Scan45Vertex(Point(20,10), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
1042       stdcout << "scanning\n";
1043       scan45.scan(result, vertices.begin(), vertices.end());
1044       stdcout << "done scanning\n";
1045       // result size == 8
1046       // result == 0 0 0 1
1047       // result == 0 0 1 -1
1048       // result == 10 0 0 -1
1049       // result == 10 0 1 1
1050       // result == 10 10 1 1
1051       // result == 10 10 0 -1
1052       // result == 20 10 1 -1
1053       // result == 20 10 0 1
1054       std::vector<Vertex45> reference;
1055       reference.push_back(Vertex45(Point(0, 0), 0, 1));
1056       reference.push_back(Vertex45(Point(0, 0), 1, -1));
1057       reference.push_back(Vertex45(Point(10, 0), 0, -1));
1058       reference.push_back(Vertex45(Point(10, 0), 1, 1));
1059       reference.push_back(Vertex45(Point(10, 10), 1, 1));
1060       reference.push_back(Vertex45(Point(10, 10), 0, -1));
1061       reference.push_back(Vertex45(Point(20, 10), 1, -1));
1062       reference.push_back(Vertex45(Point(20, 10), 0, 1));
1063       if(result != reference) {
1064         stdcout << "result size == " << result.size() << "\n";
1065         for(std::size_t i = 0; i < result.size(); ++i) {
1066           //stdcout << "result == " << result[i]<< "\n";
1067         }
1068         stdcout << "reference size == " << reference.size() << "\n";
1069         for(std::size_t i = 0; i < reference.size(); ++i) {
1070           //stdcout << "reference == " << reference[i]<< "\n";
1071         }
1072         return false;
1073       }
1074       stdcout << "done testing Scan45P2\n";
1075       return true;
1076     }
1077 
1078     template <typename streamtype>
1079     static inline bool testScan45And(streamtype& stdcout) {
1080       stdcout << "testing Scan45And\n";
1081       Scan45<Count2, boolean_op_45_output_functor<1> > scan45;
1082       std::vector<Vertex45 > result;
1083       typedef std::pair<Point, Scan45Count> Scan45Vertex;
1084       std::vector<Scan45Vertex> vertices;
1085       //is a Rectnagle(0, 0, 10, 10);
1086       Count2 count(1, 0);
1087       Count2 ncount(-1, 0);
1088       vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1089       vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1090       vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1091       vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1092       count = Count2(0, 1);
1093       ncount = count.invert();
1094       vertices.push_back(Scan45Vertex(Point(2,2), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1095       vertices.push_back(Scan45Vertex(Point(2,12), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1096       vertices.push_back(Scan45Vertex(Point(12,2), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1097       vertices.push_back(Scan45Vertex(Point(12,12), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1098       sortScan45Vector(vertices);
1099       stdcout << "scanning\n";
1100       scan45.scan(result, vertices.begin(), vertices.end());
1101       stdcout << "done scanning\n";
1102       //result size == 8
1103       //result == 2 2 0 1
1104       //result == 2 2 2 1
1105       //result == 2 10 2 -1
1106       //result == 2 10 0 -1
1107       //result == 10 2 0 -1
1108       //result == 10 2 2 -1
1109       //result == 10 10 2 1
1110       //result == 10 10 0 1
1111       std::vector<Vertex45> reference;
1112       reference.push_back(Vertex45(Point(2, 2), 0, 1));
1113       reference.push_back(Vertex45(Point(2, 2), 2, 1));
1114       reference.push_back(Vertex45(Point(2, 10), 2, -1));
1115       reference.push_back(Vertex45(Point(2, 10), 0, -1));
1116       reference.push_back(Vertex45(Point(10, 2), 0, -1));
1117       reference.push_back(Vertex45(Point(10, 2), 2, -1));
1118       reference.push_back(Vertex45(Point(10, 10), 2, 1));
1119       reference.push_back(Vertex45(Point(10, 10), 0, 1));
1120       if(result != reference) {
1121         stdcout << "result size == " << result.size() << "\n";
1122         for(std::size_t i = 0; i < result.size(); ++i) {
1123           //stdcout << "result == " << result[i]<< "\n";
1124         }
1125         stdcout << "reference size == " << reference.size() << "\n";
1126         for(std::size_t i = 0; i < reference.size(); ++i) {
1127           //stdcout << "reference == " << reference[i]<< "\n";
1128         }
1129         return false;
1130       }
1131       stdcout << "done testing Scan45And\n";
1132       return true;
1133     }
1134 
1135     template <typename stream_type>
1136     static inline bool testScan45Star1(stream_type& stdcout) {
1137       stdcout << "testing Scan45Star1\n";
1138       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
1139       std::vector<Vertex45 > result;
1140       typedef std::pair<Point, Scan45Count> Scan45Vertex;
1141       std::vector<Scan45Vertex> vertices;
1142       //is a Rectnagle(0, 0, 10, 10);
1143       Count2 count(1, 0);
1144       Count2 ncount(-1, 0);
1145       vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
1146       vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
1147       vertices.push_back(Scan45Vertex(Point(8,16), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
1148       count = Count2(0, 1);
1149       ncount = count.invert();
1150       vertices.push_back(Scan45Vertex(Point(12,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
1151       vertices.push_back(Scan45Vertex(Point(4,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
1152       vertices.push_back(Scan45Vertex(Point(4,16), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
1153       sortScan45Vector(vertices);
1154       stdcout << "scanning\n";
1155       scan45.scan(result, vertices.begin(), vertices.end());
1156       stdcout << "done scanning\n";
1157       // result size == 24
1158       // result == 0 8 -1 1
1159       // result == 0 8 1 -1
1160       // result == 4 0 1 1
1161       // result == 4 0 2 1
1162       // result == 4 4 2 -1
1163       // result == 4 4 -1 -1
1164       // result == 4 12 1 1
1165       // result == 4 12 2 1
1166       // result == 4 16 2 -1
1167       // result == 4 16 -1 -1
1168       // result == 6 2 1 -1
1169       // result == 6 14 -1 1
1170       // result == 6 2 -1 1
1171       // result == 6 14 1 -1
1172       // result == 8 0 -1 -1
1173       // result == 8 0 2 -1
1174       // result == 8 4 2 1
1175       // result == 8 4 1 1
1176       // result == 8 12 -1 -1
1177       // result == 8 12 2 -1
1178       // result == 8 16 2 1
1179       // result == 8 16 1 1
1180       // result == 12 8 1 -1
1181       // result == 12 8 -1 1
1182       if(result.size() != 24) {
1183         //stdcout << "result size == " << result.size() << "\n";
1184         //stdcout << "reference size == " << 24 << "\n";
1185         return false;
1186       }
1187       stdcout << "done testing Scan45Star1\n";
1188       return true;
1189     }
1190 
1191     template <typename stream_type>
1192     static inline bool testScan45Star2(stream_type& stdcout) {
1193       stdcout << "testing Scan45Star2\n";
1194       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
1195       std::vector<Vertex45 > result;
1196       typedef std::pair<Point, Scan45Count> Scan45Vertex;
1197       std::vector<Scan45Vertex> vertices;
1198       //is a Rectnagle(0, 0, 10, 10);
1199       Count2 count(1, 0);
1200       Count2 ncount(-1, 0);
1201       vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
1202       vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
1203       vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
1204       count = Count2(0, 1);
1205       ncount = count.invert();
1206       vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
1207       vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
1208       vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
1209       sortScan45Vector(vertices);
1210       stdcout << "scanning\n";
1211       scan45.scan(result, vertices.begin(), vertices.end());
1212       stdcout << "done scanning\n";
1213       // result size == 24
1214       // result == 0 4 0 1
1215       // result == 0 4 1 -1
1216       // result == 0 8 -1 1
1217       // result == 0 8 0 -1
1218       // result == 2 6 1 1
1219       // result == 2 6 -1 -1
1220       // result == 4 4 0 -1
1221       // result == 4 8 0 1
1222       // result == 4 4 -1 1
1223       // result == 4 8 1 -1
1224       // result == 8 0 -1 -1
1225       // result == 8 0 1 1
1226       // result == 8 12 1 1
1227       // result == 8 12 -1 -1
1228       // result == 12 4 1 -1
1229       // result == 12 8 -1 1
1230       // result == 12 4 0 1
1231       // result == 12 8 0 -1
1232       // result == 14 6 -1 -1
1233       // result == 14 6 1 1
1234       // result == 16 4 0 -1
1235       // result == 16 4 -1 1
1236       // result == 16 8 1 -1
1237       // result == 16 8 0 1
1238       if(result.size() != 24) {
1239         //std::cout << "result size == " << result.size() << "\n";
1240         //std::cout << "reference size == " << 24 << "\n";
1241         return false;
1242       }
1243       stdcout << "done testing Scan45Star2\n";
1244       return true;
1245     }
1246 
1247     template <typename stream_type>
1248     static inline bool testScan45Star3(stream_type& stdcout) {
1249       stdcout << "testing Scan45Star3\n";
1250       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
1251       std::vector<Vertex45 > result;
1252       typedef std::pair<Point, Scan45Count> Scan45Vertex;
1253       std::vector<Scan45Vertex> vertices;
1254       //is a Rectnagle(0, 0, 10, 10);
1255       Count2 count(1, 0);
1256       Count2 ncount(-1, 0);
1257       vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
1258       vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
1259       vertices.push_back(Scan45Vertex(Point(8,16), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
1260 
1261       vertices.push_back(Scan45Vertex(Point(6,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1262       vertices.push_back(Scan45Vertex(Point(6,14), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1263       vertices.push_back(Scan45Vertex(Point(12,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1264       vertices.push_back(Scan45Vertex(Point(12,14), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1265       count = Count2(0, 1);
1266       ncount = count.invert();
1267       vertices.push_back(Scan45Vertex(Point(12,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
1268       vertices.push_back(Scan45Vertex(Point(4,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
1269       vertices.push_back(Scan45Vertex(Point(4,16), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
1270       sortScan45Vector(vertices);
1271       stdcout << "scanning\n";
1272       scan45.scan(result, vertices.begin(), vertices.end());
1273       stdcout << "done scanning\n";
1274       // result size == 28
1275       // result == 0 8 -1 1
1276       // result == 0 8 1 -1
1277       // result == 4 0 1 1
1278       // result == 4 0 2 1
1279       // result == 4 4 2 -1
1280       // result == 4 4 -1 -1
1281       // result == 4 12 1 1
1282       // result == 4 12 2 1
1283       // result == 4 16 2 -1
1284       // result == 4 16 -1 -1
1285       // result == 6 2 1 -1
1286       // result == 6 14 -1 1
1287       // result == 6 0 0 1
1288       // result == 6 0 2 1
1289       // result == 6 2 2 -1
1290       // result == 6 14 1 -1
1291       // result == 8 0 0 -1
1292       // result == 8 0 0 1
1293       // result == 8 14 0 -1
1294       // result == 8 14 2 -1
1295       // result == 8 16 2 1
1296       // result == 8 16 1 1
1297       // result == 12 0 0 -1
1298       // result == 12 0 2 -1
1299       // result == 12 8 2 1
1300       // result == 12 8 2 -1
1301       // result == 12 14 2 1
1302       // result == 12 14 0 1
1303       if(result.size() != 28) {
1304         //std::cout << "result size == " << result.size() << "\n";
1305         //std::cout << "reference size == " << 28 << "\n";
1306         return false;
1307       }
1308 
1309       stdcout << "done testing Scan45Star3\n";
1310       return true;
1311     }
1312 
1313 
1314     template <typename stream_type>
1315     static inline bool testScan45Star4(stream_type& stdcout) {
1316       stdcout << "testing Scan45Star4\n";
1317       Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
1318       std::vector<Vertex45 > result;
1319       typedef std::pair<Point, Scan45Count> Scan45Vertex;
1320       std::vector<Scan45Vertex> vertices;
1321       //is a Rectnagle(0, 0, 10, 10);
1322       Count2 count(1, 0);
1323       Count2 ncount(-1, 0);
1324       vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
1325       vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
1326       vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
1327 
1328       vertices.push_back(Scan45Vertex(Point(0,6), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1329       vertices.push_back(Scan45Vertex(Point(0,12), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1330       vertices.push_back(Scan45Vertex(Point(16,6), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
1331       vertices.push_back(Scan45Vertex(Point(16,12), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
1332       count = Count2(0, 1);
1333       ncount = count.invert();
1334       vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
1335       vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
1336       vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
1337       sortScan45Vector(vertices);
1338       stdcout << "scanning\n";
1339       scan45.scan(result, vertices.begin(), vertices.end());
1340       stdcout << "done scanning\n";
1341       // result size == 28
1342       // result == 0 4 0 1
1343       // result == 0 4 1 -1
1344       // result == 0 6 0 1
1345       // result == 0 6 2 1
1346       // result == 0 8 2 -1
1347       // result == 0 8 2 1
1348       // result == 0 12 2 -1
1349       // result == 0 12 0 -1
1350       // result == 2 6 1 1
1351       // result == 2 6 0 -1
1352       // result == 4 4 0 -1
1353       // result == 4 4 -1 1
1354       // result == 8 12 0 1
1355       // result == 8 0 -1 -1
1356       // result == 8 0 1 1
1357       // result == 8 12 0 -1
1358       // result == 12 4 1 -1
1359       // result == 12 4 0 1
1360       // result == 14 6 -1 -1
1361       // result == 14 6 0 1
1362       // result == 16 4 0 -1
1363       // result == 16 4 -1 1
1364       // result == 16 6 0 -1
1365       // result == 16 6 2 -1
1366       // result == 16 8 2 1
1367       // result == 16 8 2 -1
1368       // result == 16 12 2 1
1369       // result == 16 12 0 1
1370       if(result.size() != 28) {
1371         //stdcout << "result size == " << result.size() << "\n";
1372         //stdcout << "reference size == " << 28 << "\n";
1373         return false;
1374       }
1375 
1376       stdcout << "done testing Scan45Star4\n";
1377       return true;
1378     }
1379 
1380     template <typename stream_type>
1381     static inline bool testScan45(stream_type& stdcout) {
1382       if(!testScan45Rect(stdcout)) return false;
1383       if(!testScan45P1(stdcout)) return false;
1384       if(!testScan45P2(stdcout)) return false;
1385       if(!testScan45And(stdcout)) return false;
1386       if(!testScan45Star1(stdcout)) return false;
1387       if(!testScan45Star2(stdcout)) return false;
1388       if(!testScan45Star3(stdcout)) return false;
1389       if(!testScan45Star4(stdcout)) return false;
1390       return true;
1391     }
1392 
1393   };
1394 
1395 }
1396 
1397 }
1398 #endif