annotate DEPENDENCIES/generic/include/boost/polygon/detail/polygon_45_formation.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*
Chris@16 2 Copyright 2008 Intel Corporation
Chris@16 3
Chris@16 4 Use, modification and distribution are subject to the Boost Software License,
Chris@16 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt).
Chris@16 7 */
Chris@16 8 #ifndef BOOST_POLYGON_POLYGON_45_FORMATION_HPP
Chris@16 9 #define BOOST_POLYGON_POLYGON_45_FORMATION_HPP
Chris@16 10 namespace boost { namespace polygon{
Chris@16 11
Chris@16 12 template <typename T, typename T2>
Chris@16 13 struct PolyLineByConcept {};
Chris@16 14
Chris@16 15 template <typename T>
Chris@16 16 class PolyLine45PolygonData;
Chris@16 17 template <typename T>
Chris@16 18 class PolyLine45HoleData;
Chris@16 19
Chris@16 20 //polygon45formation algorithm
Chris@16 21 template <typename Unit>
Chris@16 22 struct polygon_45_formation : public boolean_op_45<Unit> {
Chris@16 23 typedef point_data<Unit> Point;
Chris@16 24 typedef polygon_45_data<Unit> Polygon45;
Chris@16 25 typedef polygon_45_with_holes_data<Unit> Polygon45WithHoles;
Chris@16 26 typedef typename boolean_op_45<Unit>::Vertex45 Vertex45;
Chris@16 27 typedef typename boolean_op_45<Unit>::lessVertex45 lessVertex45;
Chris@16 28 typedef typename boolean_op_45<Unit>::Count2 Count2;
Chris@16 29 typedef typename boolean_op_45<Unit>::Scan45Count Scan45Count;
Chris@16 30 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 31 typedef typename boolean_op_45<Unit>::template
Chris@16 32 Scan45<Count2, typename boolean_op_45<Unit>::template boolean_op_45_output_functor<0> > Scan45;
Chris@16 33
Chris@16 34 class PolyLine45 {
Chris@16 35 public:
Chris@16 36 typedef typename std::list<Point>::const_iterator iterator;
Chris@16 37
Chris@16 38 // default constructor of point does not initialize x and y
Chris@16 39 inline PolyLine45() : points() {} //do nothing default constructor
Chris@16 40
Chris@16 41 // initialize a polygon from x,y values, it is assumed that the first is an x
Chris@16 42 // and that the input is a well behaved polygon
Chris@16 43 template<class iT>
Chris@16 44 inline PolyLine45& set(iT inputBegin, iT inputEnd) {
Chris@16 45 points.clear(); //just in case there was some old data there
Chris@16 46 while(inputBegin != inputEnd) {
Chris@16 47 points.insert(points.end(), *inputBegin);
Chris@16 48 ++inputBegin;
Chris@16 49 }
Chris@16 50 return *this;
Chris@16 51 }
Chris@16 52
Chris@16 53 // copy constructor (since we have dynamic memory)
Chris@16 54 inline PolyLine45(const PolyLine45& that) : points(that.points) {}
Chris@16 55
Chris@16 56 // assignment operator (since we have dynamic memory do a deep copy)
Chris@16 57 inline PolyLine45& operator=(const PolyLine45& that) {
Chris@16 58 points = that.points;
Chris@16 59 return *this;
Chris@16 60 }
Chris@16 61
Chris@16 62 // get begin iterator, returns a pointer to a const Unit
Chris@16 63 inline iterator begin() const { return points.begin(); }
Chris@16 64
Chris@16 65 // get end iterator, returns a pointer to a const Unit
Chris@16 66 inline iterator end() const { return points.end(); }
Chris@16 67
Chris@16 68 inline std::size_t size() const { return points.size(); }
Chris@16 69
Chris@16 70 //public data member
Chris@16 71 std::list<Point> points;
Chris@16 72 };
Chris@16 73
Chris@16 74 class ActiveTail45 {
Chris@16 75 private:
Chris@16 76 //data
Chris@16 77 PolyLine45* tailp_;
Chris@16 78 ActiveTail45 *otherTailp_;
Chris@16 79 std::list<ActiveTail45*> holesList_;
Chris@16 80 bool head_;
Chris@16 81 public:
Chris@16 82
Chris@16 83 /**
Chris@16 84 * @brief iterator over coordinates of the figure
Chris@16 85 */
Chris@16 86 typedef typename PolyLine45::iterator iterator;
Chris@16 87
Chris@16 88 /**
Chris@16 89 * @brief iterator over holes contained within the figure
Chris@16 90 */
Chris@16 91 typedef typename std::list<ActiveTail45*>::const_iterator iteratorHoles;
Chris@16 92
Chris@16 93 //default constructor
Chris@16 94 inline ActiveTail45() : tailp_(0), otherTailp_(0), holesList_(), head_(0) {}
Chris@16 95
Chris@16 96 //constructor
Chris@16 97 inline ActiveTail45(const Vertex45& vertex, ActiveTail45* otherTailp = 0) :
Chris@16 98 tailp_(0), otherTailp_(0), holesList_(), head_(0) {
Chris@16 99 tailp_ = new PolyLine45;
Chris@16 100 tailp_->points.push_back(vertex.pt);
Chris@16 101 bool headArray[4] = {false, true, true, true};
Chris@16 102 bool inverted = vertex.count == -1;
Chris@16 103 head_ = headArray[vertex.rise+1] ^ inverted;
Chris@16 104 otherTailp_ = otherTailp;
Chris@16 105 }
Chris@16 106
Chris@16 107 inline ActiveTail45(Point point, ActiveTail45* otherTailp, bool head = true) :
Chris@16 108 tailp_(0), otherTailp_(0), holesList_(), head_(0) {
Chris@16 109 tailp_ = new PolyLine45;
Chris@16 110 tailp_->points.push_back(point);
Chris@16 111 head_ = head;
Chris@16 112 otherTailp_ = otherTailp;
Chris@16 113
Chris@16 114 }
Chris@16 115 inline ActiveTail45(ActiveTail45* otherTailp) :
Chris@16 116 tailp_(0), otherTailp_(0), holesList_(), head_(0) {
Chris@16 117 tailp_ = otherTailp->tailp_;
Chris@16 118 otherTailp_ = otherTailp;
Chris@16 119 }
Chris@16 120
Chris@16 121 //copy constructor
Chris@16 122 inline ActiveTail45(const ActiveTail45& that) :
Chris@16 123 tailp_(0), otherTailp_(0), holesList_(), head_(0) { (*this) = that; }
Chris@16 124
Chris@16 125 //destructor
Chris@16 126 inline ~ActiveTail45() {
Chris@16 127 destroyContents();
Chris@16 128 }
Chris@16 129
Chris@16 130 //assignment operator
Chris@16 131 inline ActiveTail45& operator=(const ActiveTail45& that) {
Chris@16 132 tailp_ = new PolyLine45(*(that.tailp_));
Chris@16 133 head_ = that.head_;
Chris@16 134 otherTailp_ = that.otherTailp_;
Chris@16 135 holesList_ = that.holesList_;
Chris@16 136 return *this;
Chris@16 137 }
Chris@16 138
Chris@16 139 //equivalence operator
Chris@16 140 inline bool operator==(const ActiveTail45& b) const {
Chris@16 141 return tailp_ == b.tailp_ && head_ == b.head_;
Chris@16 142 }
Chris@16 143
Chris@16 144 /**
Chris@16 145 * @brief get the pointer to the polyline that this is an active tail of
Chris@16 146 */
Chris@16 147 inline PolyLine45* getTail() const { return tailp_; }
Chris@16 148
Chris@16 149 /**
Chris@16 150 * @brief get the pointer to the polyline at the other end of the chain
Chris@16 151 */
Chris@16 152 inline PolyLine45* getOtherTail() const { return otherTailp_->tailp_; }
Chris@16 153
Chris@16 154 /**
Chris@16 155 * @brief get the pointer to the activetail at the other end of the chain
Chris@16 156 */
Chris@16 157 inline ActiveTail45* getOtherActiveTail() const { return otherTailp_; }
Chris@16 158
Chris@16 159 /**
Chris@16 160 * @brief test if another active tail is the other end of the chain
Chris@16 161 */
Chris@16 162 inline bool isOtherTail(const ActiveTail45& b) const { return &b == otherTailp_; }
Chris@16 163
Chris@16 164 /**
Chris@16 165 * @brief update this end of chain pointer to new polyline
Chris@16 166 */
Chris@16 167 inline ActiveTail45& updateTail(PolyLine45* newTail) { tailp_ = newTail; return *this; }
Chris@16 168
Chris@16 169 inline bool join(ActiveTail45* tail) {
Chris@16 170 if(tail == otherTailp_) {
Chris@16 171 //std::cout << "joining to other tail!\n";
Chris@16 172 return false;
Chris@16 173 }
Chris@16 174 if(tail->head_ == head_) {
Chris@16 175 //std::cout << "joining head to head!\n";
Chris@16 176 return false;
Chris@16 177 }
Chris@16 178 if(!tailp_) {
Chris@16 179 //std::cout << "joining empty tail!\n";
Chris@16 180 return false;
Chris@16 181 }
Chris@16 182 if(!(otherTailp_->head_)) {
Chris@16 183 otherTailp_->copyHoles(*tail);
Chris@16 184 otherTailp_->copyHoles(*this);
Chris@16 185 } else {
Chris@16 186 tail->otherTailp_->copyHoles(*this);
Chris@16 187 tail->otherTailp_->copyHoles(*tail);
Chris@16 188 }
Chris@16 189 PolyLine45* tail1 = tailp_;
Chris@16 190 PolyLine45* tail2 = tail->tailp_;
Chris@16 191 if(head_) std::swap(tail1, tail2);
Chris@16 192 tail1->points.splice(tail1->points.end(), tail2->points);
Chris@16 193 delete tail2;
Chris@16 194 otherTailp_->tailp_ = tail1;
Chris@16 195 tail->otherTailp_->tailp_ = tail1;
Chris@16 196 otherTailp_->otherTailp_ = tail->otherTailp_;
Chris@16 197 tail->otherTailp_->otherTailp_ = otherTailp_;
Chris@16 198 tailp_ = 0;
Chris@16 199 tail->tailp_ = 0;
Chris@16 200 tail->otherTailp_ = 0;
Chris@16 201 otherTailp_ = 0;
Chris@16 202 return true;
Chris@16 203 }
Chris@16 204
Chris@16 205 /**
Chris@16 206 * @brief associate a hole to this active tail by the specified policy
Chris@16 207 */
Chris@16 208 inline ActiveTail45* addHole(ActiveTail45* hole) {
Chris@16 209 holesList_.push_back(hole);
Chris@16 210 copyHoles(*hole);
Chris@16 211 copyHoles(*(hole->otherTailp_));
Chris@16 212 return this;
Chris@16 213 }
Chris@16 214
Chris@16 215 /**
Chris@16 216 * @brief get the list of holes
Chris@16 217 */
Chris@16 218 inline const std::list<ActiveTail45*>& getHoles() const { return holesList_; }
Chris@16 219
Chris@16 220 /**
Chris@16 221 * @brief copy holes from that to this
Chris@16 222 */
Chris@16 223 inline void copyHoles(ActiveTail45& that) { holesList_.splice(holesList_.end(), that.holesList_); }
Chris@16 224
Chris@16 225 /**
Chris@16 226 * @brief find out if solid to right
Chris@16 227 */
Chris@16 228 inline bool solidToRight() const { return !head_; }
Chris@16 229 inline bool solidToLeft() const { return head_; }
Chris@16 230
Chris@16 231 /**
Chris@16 232 * @brief get vertex
Chris@16 233 */
Chris@16 234 inline Point getPoint() const {
Chris@16 235 if(head_) return tailp_->points.front();
Chris@16 236 return tailp_->points.back();
Chris@16 237 }
Chris@16 238
Chris@16 239 /**
Chris@16 240 * @brief add a coordinate to the polygon at this active tail end, properly handle degenerate edges by removing redundant coordinate
Chris@16 241 */
Chris@16 242 inline void pushPoint(Point point) {
Chris@16 243 if(head_) {
Chris@16 244 //if(tailp_->points.size() < 2) {
Chris@16 245 // tailp_->points.push_front(point);
Chris@16 246 // return;
Chris@16 247 //}
Chris@16 248 typename std::list<Point>::iterator iter = tailp_->points.begin();
Chris@16 249 if(iter == tailp_->points.end()) {
Chris@16 250 tailp_->points.push_front(point);
Chris@16 251 return;
Chris@16 252 }
Chris@16 253 Unit firstY = (*iter).y();
Chris@16 254 Unit firstX = (*iter).x();
Chris@16 255 ++iter;
Chris@16 256 if(iter == tailp_->points.end()) {
Chris@16 257 tailp_->points.push_front(point);
Chris@16 258 return;
Chris@16 259 }
Chris@16 260 if((iter->y() == point.y() && firstY == point.y()) ||
Chris@16 261 (iter->x() == point.x() && firstX == point.x())){
Chris@16 262 --iter;
Chris@16 263 *iter = point;
Chris@16 264 } else {
Chris@16 265 tailp_->points.push_front(point);
Chris@16 266 }
Chris@16 267 return;
Chris@16 268 }
Chris@16 269 //if(tailp_->points.size() < 2) {
Chris@16 270 // tailp_->points.push_back(point);
Chris@16 271 // return;
Chris@16 272 //}
Chris@16 273 typename std::list<Point>::reverse_iterator iter = tailp_->points.rbegin();
Chris@16 274 if(iter == tailp_->points.rend()) {
Chris@16 275 tailp_->points.push_back(point);
Chris@16 276 return;
Chris@16 277 }
Chris@16 278 Unit firstY = (*iter).y();
Chris@16 279 Unit firstX = (*iter).x();
Chris@16 280 ++iter;
Chris@16 281 if(iter == tailp_->points.rend()) {
Chris@16 282 tailp_->points.push_back(point);
Chris@16 283 return;
Chris@16 284 }
Chris@16 285 if((iter->y() == point.y() && firstY == point.y()) ||
Chris@16 286 (iter->x() == point.x() && firstX == point.x())){
Chris@16 287 --iter;
Chris@16 288 *iter = point;
Chris@16 289 } else {
Chris@16 290 tailp_->points.push_back(point);
Chris@16 291 }
Chris@16 292 }
Chris@16 293
Chris@16 294 /**
Chris@16 295 * @brief joins the two chains that the two active tail tails are ends of
Chris@16 296 * checks for closure of figure and writes out polygons appropriately
Chris@16 297 * returns a handle to a hole if one is closed
Chris@16 298 */
Chris@16 299
Chris@16 300 template <class cT>
Chris@16 301 static inline ActiveTail45* joinChains(Point point, ActiveTail45* at1, ActiveTail45* at2, bool solid,
Chris@16 302 cT& output) {
Chris@16 303 if(at1->otherTailp_ == at2) {
Chris@16 304 //if(at2->otherTailp_ != at1) std::cout << "half closed error\n";
Chris@16 305 //we are closing a figure
Chris@16 306 at1->pushPoint(point);
Chris@16 307 at2->pushPoint(point);
Chris@16 308 if(solid) {
Chris@16 309 //we are closing a solid figure, write to output
Chris@16 310 //std::cout << "test1\n";
Chris@16 311 at1->copyHoles(*(at1->otherTailp_));
Chris@16 312 //std::cout << "test2\n";
Chris@16 313 //Polygon45WithHolesImpl<PolyLine45PolygonData> poly(polyData);
Chris@16 314 //std::cout << poly << "\n";
Chris@16 315 //std::cout << "test3\n";
Chris@16 316 typedef typename cT::value_type pType;
Chris@16 317 output.push_back(pType());
Chris@16 318 typedef typename geometry_concept<pType>::type cType;
Chris@16 319 typename PolyLineByConcept<Unit, cType>::type polyData(at1);
Chris@16 320 assign(output.back(), polyData);
Chris@16 321 //std::cout << "test4\n";
Chris@16 322 //std::cout << "delete " << at1->otherTailp_ << "\n";
Chris@16 323 //at1->print();
Chris@16 324 //at1->otherTailp_->print();
Chris@16 325 delete at1->otherTailp_;
Chris@16 326 //at1->print();
Chris@16 327 //at1->otherTailp_->print();
Chris@16 328 //std::cout << "test5\n";
Chris@16 329 //std::cout << "delete " << at1 << "\n";
Chris@16 330 delete at1;
Chris@16 331 //std::cout << "test6\n";
Chris@16 332 return 0;
Chris@16 333 } else {
Chris@16 334 //we are closing a hole, return the tail end active tail of the figure
Chris@16 335 return at1;
Chris@16 336 }
Chris@16 337 }
Chris@16 338 //we are not closing a figure
Chris@16 339 at1->pushPoint(point);
Chris@16 340 at1->join(at2);
Chris@16 341 delete at1;
Chris@16 342 delete at2;
Chris@16 343 return 0;
Chris@16 344 }
Chris@16 345
Chris@16 346 inline void destroyContents() {
Chris@16 347 if(otherTailp_) {
Chris@16 348 //std::cout << "delete p " << tailp_ << "\n";
Chris@16 349 if(tailp_) delete tailp_;
Chris@16 350 tailp_ = 0;
Chris@16 351 otherTailp_->otherTailp_ = 0;
Chris@16 352 otherTailp_->tailp_ = 0;
Chris@16 353 otherTailp_ = 0;
Chris@16 354 }
Chris@16 355 for(typename std::list<ActiveTail45*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) {
Chris@16 356 //std::cout << "delete p " << (*itr) << "\n";
Chris@16 357 if(*itr) {
Chris@16 358 if((*itr)->otherTailp_) {
Chris@16 359 delete (*itr)->otherTailp_;
Chris@16 360 (*itr)->otherTailp_ = 0;
Chris@16 361 }
Chris@16 362 delete (*itr);
Chris@16 363 }
Chris@16 364 (*itr) = 0;
Chris@16 365 }
Chris@16 366 holesList_.clear();
Chris@16 367 }
Chris@16 368
Chris@16 369 // inline void print() {
Chris@16 370 // std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n";
Chris@16 371 // }
Chris@16 372
Chris@16 373 static inline std::pair<ActiveTail45*, ActiveTail45*> createActiveTail45sAsPair(Point point, bool solid,
Chris@16 374 ActiveTail45* phole, bool fractureHoles) {
Chris@16 375 ActiveTail45* at1 = 0;
Chris@16 376 ActiveTail45* at2 = 0;
Chris@16 377 if(phole && fractureHoles) {
Chris@16 378 //std::cout << "adding hole\n";
Chris@16 379 at1 = phole;
Chris@16 380 //assert solid == false, we should be creating a corner with solid below and to the left if there was a hole
Chris@16 381 at2 = at1->getOtherActiveTail();
Chris@16 382 at2->pushPoint(point);
Chris@16 383 at1->pushPoint(point);
Chris@16 384 } else {
Chris@16 385 at1 = new ActiveTail45(point, at2, solid);
Chris@16 386 at2 = new ActiveTail45(at1);
Chris@16 387 at1->otherTailp_ = at2;
Chris@16 388 at2->head_ = !solid;
Chris@16 389 if(phole)
Chris@16 390 at2->addHole(phole); //assert fractureHoles == false
Chris@16 391 }
Chris@16 392 return std::pair<ActiveTail45*, ActiveTail45*>(at1, at2);
Chris@16 393 }
Chris@16 394
Chris@16 395 };
Chris@16 396
Chris@16 397 template <typename ct>
Chris@16 398 class Vertex45CountT {
Chris@16 399 public:
Chris@16 400 typedef ct count_type;
Chris@16 401 inline Vertex45CountT()
Chris@16 402 #ifndef BOOST_POLYGON_MSVC
Chris@16 403 : counts()
Chris@16 404 #endif
Chris@16 405 { counts[0] = counts[1] = counts[2] = counts[3] = 0; }
Chris@16 406 //inline Vertex45CountT(ct count) { counts[0] = counts[1] = counts[2] = counts[3] = count; }
Chris@16 407 inline Vertex45CountT(const ct& count1, const ct& count2, const ct& count3,
Chris@16 408 const ct& count4)
Chris@16 409 #ifndef BOOST_POLYGON_MSVC
Chris@16 410 : counts()
Chris@16 411 #endif
Chris@16 412 {
Chris@16 413 counts[0] = count1;
Chris@16 414 counts[1] = count2;
Chris@16 415 counts[2] = count3;
Chris@16 416 counts[3] = count4;
Chris@16 417 }
Chris@16 418 inline Vertex45CountT(const Vertex45& vertex)
Chris@16 419 #ifndef BOOST_POLYGON_MSVC
Chris@16 420 : counts()
Chris@16 421 #endif
Chris@16 422 {
Chris@16 423 counts[0] = counts[1] = counts[2] = counts[3] = 0;
Chris@16 424 (*this) += vertex;
Chris@16 425 }
Chris@16 426 inline Vertex45CountT(const Vertex45CountT& count)
Chris@16 427 #ifndef BOOST_POLYGON_MSVC
Chris@16 428 : counts()
Chris@16 429 #endif
Chris@16 430 {
Chris@16 431 (*this) = count;
Chris@16 432 }
Chris@16 433 inline bool operator==(const Vertex45CountT& count) const {
Chris@16 434 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 435 if(counts[i] != count.counts[i]) return false;
Chris@16 436 }
Chris@16 437 return true;
Chris@16 438 }
Chris@16 439 inline bool operator!=(const Vertex45CountT& count) const { return !((*this) == count); }
Chris@16 440 inline Vertex45CountT& operator=(ct count) {
Chris@16 441 counts[0] = counts[1] = counts[2] = counts[3] = count; return *this; }
Chris@16 442 inline Vertex45CountT& operator=(const Vertex45CountT& count) {
Chris@16 443 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 444 counts[i] = count.counts[i];
Chris@16 445 }
Chris@16 446 return *this;
Chris@16 447 }
Chris@16 448 inline ct& operator[](int index) { return counts[index]; }
Chris@16 449 inline ct operator[](int index) const {return counts[index]; }
Chris@16 450 inline Vertex45CountT& operator+=(const Vertex45CountT& count){
Chris@16 451 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 452 counts[i] += count.counts[i];
Chris@16 453 }
Chris@16 454 return *this;
Chris@16 455 }
Chris@16 456 inline Vertex45CountT& operator-=(const Vertex45CountT& count){
Chris@16 457 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 458 counts[i] -= count.counts[i];
Chris@16 459 }
Chris@16 460 return *this;
Chris@16 461 }
Chris@16 462 inline Vertex45CountT operator+(const Vertex45CountT& count) const {
Chris@16 463 return Vertex45CountT(*this)+=count;
Chris@16 464 }
Chris@16 465 inline Vertex45CountT operator-(const Vertex45CountT& count) const {
Chris@16 466 return Vertex45CountT(*this)-=count;
Chris@16 467 }
Chris@16 468 inline Vertex45CountT invert() const {
Chris@16 469 return Vertex45CountT()-=(*this);
Chris@16 470 }
Chris@16 471 inline Vertex45CountT& operator+=(const Vertex45& element){
Chris@16 472 counts[element.rise+1] += element.count; return *this;
Chris@16 473 }
Chris@16 474 inline bool is_45() const {
Chris@16 475 return counts[0] != 0 || counts[2] != 0;
Chris@16 476 }
Chris@16 477 private:
Chris@16 478 ct counts[4];
Chris@16 479 };
Chris@16 480
Chris@16 481 typedef Vertex45CountT<int> Vertex45Count;
Chris@16 482
Chris@16 483 // inline std::ostream& operator<< (std::ostream& o, const Vertex45Count& c) {
Chris@16 484 // o << c[0] << ", " << c[1] << ", ";
Chris@16 485 // o << c[2] << ", " << c[3];
Chris@16 486 // return o;
Chris@16 487 // }
Chris@16 488
Chris@16 489 template <typename ct>
Chris@16 490 class Vertex45CompactT {
Chris@16 491 public:
Chris@16 492 Point pt;
Chris@16 493 ct count;
Chris@16 494 typedef typename boolean_op_45<Unit>::template Vertex45T<typename ct::count_type> Vertex45T;
Chris@16 495 inline Vertex45CompactT() : pt(), count() {}
Chris@16 496 inline Vertex45CompactT(const Point& point, int riseIn, int countIn) : pt(point), count() {
Chris@16 497 count[riseIn+1] = countIn;
Chris@16 498 }
Chris@16 499 template <typename ct2>
Chris@16 500 inline Vertex45CompactT(const typename boolean_op_45<Unit>::template Vertex45T<ct2>& vertex) : pt(vertex.pt), count() {
Chris@16 501 count[vertex.rise+1] = vertex.count;
Chris@16 502 }
Chris@16 503 inline Vertex45CompactT(const Vertex45CompactT& vertex) : pt(vertex.pt), count(vertex.count) {}
Chris@16 504 inline Vertex45CompactT& operator=(const Vertex45CompactT& vertex){
Chris@16 505 pt = vertex.pt; count = vertex.count; return *this; }
Chris@16 506 inline bool operator==(const Vertex45CompactT& vertex) const {
Chris@16 507 return pt == vertex.pt && count == vertex.count; }
Chris@16 508 inline bool operator!=(const Vertex45CompactT& vertex) const { return !((*this) == vertex); }
Chris@16 509 inline bool operator==(const std::pair<Point, Point>& vertex) const { return false; }
Chris@16 510 inline bool operator!=(const std::pair<Point, Point>& vertex) const { return !((*this) == vertex); }
Chris@16 511 inline bool operator<(const Vertex45CompactT& vertex) const {
Chris@16 512 if(pt.x() < vertex.pt.x()) return true;
Chris@16 513 if(pt.x() == vertex.pt.x()) {
Chris@16 514 return pt.y() < vertex.pt.y();
Chris@16 515 }
Chris@16 516 return false;
Chris@16 517 }
Chris@16 518 inline bool operator>(const Vertex45CompactT& vertex) const { return vertex < (*this); }
Chris@16 519 inline bool operator<=(const Vertex45CompactT& vertex) const { return !((*this) > vertex); }
Chris@16 520 inline bool operator>=(const Vertex45CompactT& vertex) const { return !((*this) < vertex); }
Chris@16 521 inline bool haveVertex45(int index) const { return count[index]; }
Chris@16 522 inline Vertex45T operator[](int index) const {
Chris@16 523 return Vertex45T(pt, index-1, count[index]); }
Chris@16 524 };
Chris@16 525
Chris@16 526 typedef Vertex45CompactT<Vertex45Count> Vertex45Compact;
Chris@16 527
Chris@16 528 // inline std::ostream& operator<< (std::ostream& o, const Vertex45Compact& c) {
Chris@16 529 // o << c.pt << ", " << c.count;
Chris@16 530 // return o;
Chris@16 531 // }
Chris@16 532
Chris@16 533 class Polygon45Formation {
Chris@16 534 private:
Chris@16 535 //definitions
Chris@16 536 typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData;
Chris@16 537 typedef typename Polygon45FormationData::iterator iterator;
Chris@16 538 typedef typename Polygon45FormationData::const_iterator const_iterator;
Chris@16 539
Chris@16 540 //data
Chris@16 541 Polygon45FormationData scanData_;
Chris@16 542 Unit x_;
Chris@16 543 int justBefore_;
Chris@16 544 int fractureHoles_;
Chris@16 545 public:
Chris@16 546 inline Polygon45Formation() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) {
Chris@16 547 lessVertex45 lessElm(&x_, &justBefore_);
Chris@16 548 scanData_ = Polygon45FormationData(lessElm);
Chris@16 549 }
Chris@16 550 inline Polygon45Formation(bool fractureHoles) : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(fractureHoles) {
Chris@16 551 lessVertex45 lessElm(&x_, &justBefore_);
Chris@16 552 scanData_ = Polygon45FormationData(lessElm);
Chris@16 553 }
Chris@16 554 inline Polygon45Formation(const Polygon45Formation& that) :
Chris@16 555 scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { (*this) = that; }
Chris@16 556 inline Polygon45Formation& operator=(const Polygon45Formation& that) {
Chris@16 557 x_ = that.x_;
Chris@16 558 justBefore_ = that.justBefore_;
Chris@16 559 fractureHoles_ = that.fractureHoles_;
Chris@16 560 lessVertex45 lessElm(&x_, &justBefore_);
Chris@16 561 scanData_ = Polygon45FormationData(lessElm);
Chris@16 562 for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
Chris@16 563 scanData_.insert(scanData_.end(), *itr);
Chris@16 564 }
Chris@16 565 return *this;
Chris@16 566 }
Chris@16 567
Chris@16 568 //cT is an output container of Polygon45 or Polygon45WithHoles
Chris@16 569 //iT is an iterator over Vertex45 elements
Chris@16 570 //inputBegin - inputEnd is a range of sorted iT that represents
Chris@16 571 //one or more scanline stops worth of data
Chris@16 572 template <class cT, class iT>
Chris@16 573 void scan(cT& output, iT inputBegin, iT inputEnd) {
Chris@16 574 //std::cout << "1\n";
Chris@16 575 while(inputBegin != inputEnd) {
Chris@16 576 //std::cout << "2\n";
Chris@16 577 x_ = (*inputBegin).pt.x();
Chris@16 578 //std::cout << "SCAN FORMATION " << x_ << "\n";
Chris@16 579 //std::cout << "x_ = " << x_ << "\n";
Chris@16 580 //std::cout << "scan line size: " << scanData_.size() << "\n";
Chris@16 581 inputBegin = processEvent_(output, inputBegin, inputEnd);
Chris@16 582 }
Chris@16 583 }
Chris@16 584
Chris@16 585 private:
Chris@16 586 //functions
Chris@16 587 template <class cT, class cT2>
Chris@16 588 inline std::pair<int, ActiveTail45*> processPoint_(cT& output, cT2& elements, Point point,
Chris@16 589 Vertex45Count& counts, ActiveTail45** tails, Vertex45Count& incoming) {
Chris@16 590 //std::cout << point << "\n";
Chris@16 591 //std::cout << counts[0] << " ";
Chris@16 592 //std::cout << counts[1] << " ";
Chris@16 593 //std::cout << counts[2] << " ";
Chris@16 594 //std::cout << counts[3] << "\n";
Chris@16 595 //std::cout << incoming[0] << " ";
Chris@16 596 //std::cout << incoming[1] << " ";
Chris@16 597 //std::cout << incoming[2] << " ";
Chris@16 598 //std::cout << incoming[3] << "\n";
Chris@16 599 //join any closing solid corners
Chris@16 600 ActiveTail45* returnValue = 0;
Chris@16 601 int returnCount = 0;
Chris@16 602 for(int i = 0; i < 3; ++i) {
Chris@16 603 //std::cout << i << "\n";
Chris@16 604 if(counts[i] == -1) {
Chris@16 605 //std::cout << "fixed i\n";
Chris@16 606 for(int j = i + 1; j < 4; ++j) {
Chris@16 607 //std::cout << j << "\n";
Chris@16 608 if(counts[j]) {
Chris@16 609 if(counts[j] == 1) {
Chris@16 610 //std::cout << "case1: " << i << " " << j << "\n";
Chris@16 611 //if a figure is closed it will be written out by this function to output
Chris@16 612 ActiveTail45::joinChains(point, tails[i], tails[j], true, output);
Chris@16 613 counts[i] = 0;
Chris@16 614 counts[j] = 0;
Chris@16 615 tails[i] = 0;
Chris@16 616 tails[j] = 0;
Chris@16 617 }
Chris@16 618 break;
Chris@16 619 }
Chris@16 620 }
Chris@16 621 }
Chris@16 622 }
Chris@16 623 //find any pairs of incoming edges that need to create pair for leading solid
Chris@16 624 //std::cout << "checking case2\n";
Chris@16 625 for(int i = 0; i < 3; ++i) {
Chris@16 626 //std::cout << i << "\n";
Chris@16 627 if(incoming[i] == 1) {
Chris@16 628 //std::cout << "fixed i\n";
Chris@16 629 for(int j = i + 1; j < 4; ++j) {
Chris@16 630 //std::cout << j << "\n";
Chris@16 631 if(incoming[j]) {
Chris@16 632 if(incoming[j] == -1) {
Chris@16 633 //std::cout << "case2: " << i << " " << j << "\n";
Chris@16 634 //std::cout << "creating active tail pair\n";
Chris@16 635 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
Chris@16 636 ActiveTail45::createActiveTail45sAsPair(point, true, 0, fractureHoles_ != 0);
Chris@16 637 //tailPair.first->print();
Chris@16 638 //tailPair.second->print();
Chris@16 639 if(j == 3) {
Chris@16 640 //vertical active tail becomes return value
Chris@16 641 returnValue = tailPair.first;
Chris@16 642 returnCount = 1;
Chris@16 643 } else {
Chris@16 644 Vertex45 vertex(point, i -1, incoming[i]);
Chris@16 645 //std::cout << "new element " << j-1 << " " << -1 << "\n";
Chris@16 646 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, -1), tailPair.first));
Chris@16 647 }
Chris@16 648 //std::cout << "new element " << i-1 << " " << 1 << "\n";
Chris@16 649 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, 1), tailPair.second));
Chris@16 650 incoming[i] = 0;
Chris@16 651 incoming[j] = 0;
Chris@16 652 }
Chris@16 653 break;
Chris@16 654 }
Chris@16 655 }
Chris@16 656 }
Chris@16 657 }
Chris@16 658
Chris@16 659 //find any active tail that needs to pass through to an incoming edge
Chris@16 660 //we expect to find no more than two pass through
Chris@16 661
Chris@16 662 //find pass through with solid on top
Chris@16 663 //std::cout << "checking case 3\n";
Chris@16 664 for(int i = 0; i < 4; ++i) {
Chris@16 665 //std::cout << i << "\n";
Chris@16 666 if(counts[i] != 0) {
Chris@16 667 if(counts[i] == 1) {
Chris@16 668 //std::cout << "fixed i\n";
Chris@16 669 for(int j = 3; j >= 0; --j) {
Chris@16 670 if(incoming[j] != 0) {
Chris@16 671 if(incoming[j] == 1) {
Chris@16 672 //std::cout << "case3: " << i << " " << j << "\n";
Chris@16 673 //tails[i]->print();
Chris@16 674 //pass through solid on top
Chris@16 675 tails[i]->pushPoint(point);
Chris@16 676 //std::cout << "after push\n";
Chris@16 677 if(j == 3) {
Chris@16 678 returnValue = tails[i];
Chris@16 679 returnCount = -1;
Chris@16 680 } else {
Chris@16 681 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i]));
Chris@16 682 }
Chris@16 683 tails[i] = 0;
Chris@16 684 counts[i] = 0;
Chris@16 685 incoming[j] = 0;
Chris@16 686 }
Chris@16 687 break;
Chris@16 688 }
Chris@16 689 }
Chris@16 690 }
Chris@16 691 break;
Chris@16 692 }
Chris@16 693 }
Chris@16 694 //std::cout << "checking case 4\n";
Chris@16 695 //find pass through with solid on bottom
Chris@16 696 for(int i = 3; i >= 0; --i) {
Chris@16 697 if(counts[i] != 0) {
Chris@16 698 if(counts[i] == -1) {
Chris@16 699 for(int j = 0; j < 4; ++j) {
Chris@16 700 if(incoming[j] != 0) {
Chris@16 701 if(incoming[j] == -1) {
Chris@16 702 //std::cout << "case4: " << i << " " << j << "\n";
Chris@16 703 //pass through solid on bottom
Chris@16 704 tails[i]->pushPoint(point);
Chris@16 705 if(j == 3) {
Chris@16 706 returnValue = tails[i];
Chris@16 707 returnCount = 1;
Chris@16 708 } else {
Chris@16 709 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
Chris@16 710 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i]));
Chris@16 711 }
Chris@16 712 tails[i] = 0;
Chris@16 713 counts[i] = 0;
Chris@16 714 incoming[j] = 0;
Chris@16 715 }
Chris@16 716 break;
Chris@16 717 }
Chris@16 718 }
Chris@16 719 }
Chris@16 720 break;
Chris@16 721 }
Chris@16 722 }
Chris@16 723
Chris@16 724 //find the end of a hole or the beginning of a hole
Chris@16 725
Chris@16 726 //find end of a hole
Chris@16 727 for(int i = 0; i < 3; ++i) {
Chris@16 728 if(counts[i] != 0) {
Chris@16 729 for(int j = i+1; j < 4; ++j) {
Chris@16 730 if(counts[j] != 0) {
Chris@16 731 //std::cout << "case5: " << i << " " << j << "\n";
Chris@16 732 //we are ending a hole and may potentially close a figure and have to handle the hole
Chris@16 733 returnValue = ActiveTail45::joinChains(point, tails[i], tails[j], false, output);
Chris@16 734 tails[i] = 0;
Chris@16 735 tails[j] = 0;
Chris@16 736 counts[i] = 0;
Chris@16 737 counts[j] = 0;
Chris@16 738 break;
Chris@16 739 }
Chris@16 740 }
Chris@16 741 break;
Chris@16 742 }
Chris@16 743 }
Chris@16 744 //find beginning of a hole
Chris@16 745 for(int i = 0; i < 3; ++i) {
Chris@16 746 if(incoming[i] != 0) {
Chris@16 747 for(int j = i+1; j < 4; ++j) {
Chris@16 748 if(incoming[j] != 0) {
Chris@16 749 //std::cout << "case6: " << i << " " << j << "\n";
Chris@16 750 //we are beginning a empty space
Chris@16 751 ActiveTail45* holep = 0;
Chris@16 752 if(counts[3] == 0) holep = tails[3];
Chris@16 753 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
Chris@16 754 ActiveTail45::createActiveTail45sAsPair(point, false, holep, fractureHoles_ != 0);
Chris@16 755 if(j == 3) {
Chris@16 756 returnValue = tailPair.first;
Chris@16 757 returnCount = -1;
Chris@16 758 } else {
Chris@16 759 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
Chris@16 760 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.first));
Chris@16 761 }
Chris@16 762 //std::cout << "new element " << i-1 << " " << incoming[i] << "\n";
Chris@16 763 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, incoming[i]), tailPair.second));
Chris@16 764 incoming[i] = 0;
Chris@16 765 incoming[j] = 0;
Chris@16 766 break;
Chris@16 767 }
Chris@16 768 }
Chris@16 769 break;
Chris@16 770 }
Chris@16 771 }
Chris@16 772 //assert that tails, counts and incoming are all null
Chris@16 773 return std::pair<int, ActiveTail45*>(returnCount, returnValue);
Chris@16 774 }
Chris@16 775
Chris@16 776 template <class cT, class iT>
Chris@16 777 inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
Chris@16 778 //std::cout << "processEvent_\n";
Chris@16 779 justBefore_ = true;
Chris@16 780 //collect up all elements from the tree that are at the y
Chris@16 781 //values of events in the input queue
Chris@16 782 //create vector of new elements to add into tree
Chris@16 783 ActiveTail45* verticalTail = 0;
Chris@16 784 int verticalCount = 0;
Chris@16 785 iT currentIter = inputBegin;
Chris@16 786 std::vector<iterator> elementIters;
Chris@16 787 std::vector<std::pair<Vertex45, ActiveTail45*> > elements;
Chris@16 788 while(currentIter != inputEnd && currentIter->pt.x() == x_) {
Chris@16 789 //std::cout << "loop\n";
Chris@16 790 Unit currentY = (*currentIter).pt.y();
Chris@16 791 iterator iter = lookUp_(currentY);
Chris@16 792 //int counts[4] = {0, 0, 0, 0};
Chris@16 793 Vertex45Count counts;
Chris@16 794 ActiveTail45* tails[4] = {0, 0, 0, verticalTail};
Chris@16 795 //std::cout << "finding elements in tree\n";
Chris@16 796 while(iter != scanData_.end() &&
Chris@16 797 iter->first.evalAtX(x_) == currentY) {
Chris@16 798 //std::cout << "loop2\n";
Chris@16 799 elementIters.push_back(iter);
Chris@16 800 int index = iter->first.rise + 1;
Chris@16 801 //std::cout << index << " " << iter->first.count << "\n";
Chris@16 802 counts[index] = iter->first.count;
Chris@16 803 tails[index] = iter->second;
Chris@16 804 ++iter;
Chris@16 805 }
Chris@16 806 //int incoming[4] = {0, 0, 0, 0};
Chris@16 807 Vertex45Count incoming;
Chris@16 808 //std::cout << "aggregating\n";
Chris@16 809 do {
Chris@16 810 //std::cout << "loop3\n";
Chris@16 811 Vertex45Compact currentVertex(*currentIter);
Chris@16 812 incoming += currentVertex.count;
Chris@16 813 ++currentIter;
Chris@16 814 } while(currentIter != inputEnd && currentIter->pt.y() == currentY &&
Chris@16 815 currentIter->pt.x() == x_);
Chris@16 816 //now counts and tails have the data from the left and
Chris@16 817 //incoming has the data from the right at this point
Chris@16 818 //cancel out any end points
Chris@16 819 //std::cout << counts[0] << " ";
Chris@16 820 //std::cout << counts[1] << " ";
Chris@16 821 //std::cout << counts[2] << " ";
Chris@16 822 //std::cout << counts[3] << "\n";
Chris@16 823 //std::cout << incoming[0] << " ";
Chris@16 824 //std::cout << incoming[1] << " ";
Chris@16 825 //std::cout << incoming[2] << " ";
Chris@16 826 //std::cout << incoming[3] << "\n";
Chris@16 827 if(verticalTail) {
Chris@16 828 counts[3] = -verticalCount;
Chris@16 829 }
Chris@16 830 incoming[3] *= -1;
Chris@16 831 for(unsigned int i = 0; i < 4; ++i) incoming[i] += counts[i];
Chris@16 832 //std::cout << "calling processPoint_\n";
Chris@16 833 std::pair<int, ActiveTail45*> result = processPoint_(output, elements, Point(x_, currentY), counts, tails, incoming);
Chris@16 834 verticalCount = result.first;
Chris@16 835 verticalTail = result.second;
Chris@16 836 //if(verticalTail) std::cout << "have vertical tail\n";
Chris@16 837 //std::cout << "verticalCount: " << verticalCount << "\n";
Chris@16 838 if(verticalTail && !verticalCount) {
Chris@16 839 //we got a hole out of the point we just processed
Chris@16 840 //iter is still at the next y element above the current y value in the tree
Chris@16 841 //std::cout << "checking whether ot handle hole\n";
Chris@16 842 if(currentIter == inputEnd ||
Chris@16 843 currentIter->pt.x() != x_ ||
Chris@16 844 currentIter->pt.y() >= iter->first.evalAtX(x_)) {
Chris@16 845 //std::cout << "handle hole here\n";
Chris@16 846 if(fractureHoles_) {
Chris@16 847 //std::cout << "fracture hole here\n";
Chris@16 848 //we need to handle the hole now and not at the next input vertex
Chris@16 849 ActiveTail45* at = iter->second;
Chris@16 850 Point point(x_, iter->first.evalAtX(x_));
Chris@16 851 verticalTail->getOtherActiveTail()->pushPoint(point);
Chris@16 852 iter->second = verticalTail->getOtherActiveTail();
Chris@16 853 at->pushPoint(point);
Chris@16 854 verticalTail->join(at);
Chris@16 855 delete at;
Chris@16 856 delete verticalTail;
Chris@16 857 verticalTail = 0;
Chris@16 858 } else {
Chris@16 859 //std::cout << "push hole onto list\n";
Chris@16 860 iter->second->addHole(verticalTail);
Chris@16 861 verticalTail = 0;
Chris@16 862 }
Chris@16 863 }
Chris@16 864 }
Chris@16 865 }
Chris@16 866 //std::cout << "erasing\n";
Chris@16 867 //erase all elements from the tree
Chris@16 868 for(typename std::vector<iterator>::iterator iter = elementIters.begin();
Chris@16 869 iter != elementIters.end(); ++iter) {
Chris@16 870 //std::cout << "erasing loop\n";
Chris@16 871 scanData_.erase(*iter);
Chris@16 872 }
Chris@16 873 //switch comparison tie breaking policy
Chris@16 874 justBefore_ = false;
Chris@16 875 //add new elements into tree
Chris@16 876 //std::cout << "inserting\n";
Chris@16 877 for(typename std::vector<std::pair<Vertex45, ActiveTail45*> >::iterator iter = elements.begin();
Chris@16 878 iter != elements.end(); ++iter) {
Chris@16 879 //std::cout << "inserting loop\n";
Chris@16 880 scanData_.insert(scanData_.end(), *iter);
Chris@16 881 }
Chris@16 882 //std::cout << "end processEvent\n";
Chris@16 883 return currentIter;
Chris@16 884 }
Chris@16 885
Chris@16 886 inline iterator lookUp_(Unit y){
Chris@16 887 //if just before then we need to look from 1 not -1
Chris@16 888 return scanData_.lower_bound(Vertex45(Point(x_, y), -1+2*justBefore_, 0));
Chris@16 889 }
Chris@16 890
Chris@16 891 };
Chris@16 892
Chris@16 893 template <typename stream_type>
Chris@16 894 static inline bool testPolygon45FormationRect(stream_type& stdcout) {
Chris@16 895 stdcout << "testing polygon formation\n";
Chris@16 896 Polygon45Formation pf(true);
Chris@16 897 std::vector<Polygon45> polys;
Chris@16 898 std::vector<Vertex45> data;
Chris@16 899 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 900 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 901 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 902 data.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 903 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 904 data.push_back(Vertex45(Point(10, 0), 2, -1));
Chris@16 905 data.push_back(Vertex45(Point(10, 10), 2, 1));
Chris@16 906 data.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 907 polygon_sort(data.begin(), data.end());
Chris@16 908 pf.scan(polys, data.begin(), data.end());
Chris@16 909 stdcout << "result size: " << polys.size() << "\n";
Chris@16 910 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 911 stdcout << polys[i] << "\n";
Chris@16 912 }
Chris@16 913 stdcout << "done testing polygon formation\n";
Chris@16 914 return true;
Chris@16 915 }
Chris@16 916
Chris@16 917 template <typename stream_type>
Chris@16 918 static inline bool testPolygon45FormationP1(stream_type& stdcout) {
Chris@16 919 stdcout << "testing polygon formation\n";
Chris@16 920 Polygon45Formation pf(true);
Chris@16 921 std::vector<Polygon45> polys;
Chris@16 922 std::vector<Vertex45> data;
Chris@16 923 data.push_back(Vertex45(Point(0, 0), 1, 1));
Chris@16 924 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 925 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 926 data.push_back(Vertex45(Point(0, 10), 1, -1));
Chris@16 927 data.push_back(Vertex45(Point(10, 10), 1, -1));
Chris@16 928 data.push_back(Vertex45(Point(10, 10), 2, -1));
Chris@16 929 data.push_back(Vertex45(Point(10, 20), 2, 1));
Chris@16 930 data.push_back(Vertex45(Point(10, 20), 1, 1));
Chris@16 931 polygon_sort(data.begin(), data.end());
Chris@16 932 pf.scan(polys, data.begin(), data.end());
Chris@16 933 stdcout << "result size: " << polys.size() << "\n";
Chris@16 934 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 935 stdcout << polys[i] << "\n";
Chris@16 936 }
Chris@16 937 stdcout << "done testing polygon formation\n";
Chris@16 938 return true;
Chris@16 939 }
Chris@16 940 //polygon45set class
Chris@16 941
Chris@16 942 template <typename stream_type>
Chris@16 943 static inline bool testPolygon45FormationP2(stream_type& stdcout) {
Chris@16 944 stdcout << "testing polygon formation\n";
Chris@16 945 Polygon45Formation pf(true);
Chris@16 946 std::vector<Polygon45> polys;
Chris@16 947 std::vector<Vertex45> data;
Chris@16 948 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 949 data.push_back(Vertex45(Point(0, 0), 1, -1));
Chris@16 950 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 951 data.push_back(Vertex45(Point(10, 0), 1, 1));
Chris@16 952 data.push_back(Vertex45(Point(10, 10), 1, 1));
Chris@16 953 data.push_back(Vertex45(Point(10, 10), 0, -1));
Chris@16 954 data.push_back(Vertex45(Point(20, 10), 1, -1));
Chris@16 955 data.push_back(Vertex45(Point(20, 10), 0, 1));
Chris@16 956 polygon_sort(data.begin(), data.end());
Chris@16 957 pf.scan(polys, data.begin(), data.end());
Chris@16 958 stdcout << "result size: " << polys.size() << "\n";
Chris@16 959 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 960 stdcout << polys[i] << "\n";
Chris@16 961 }
Chris@16 962 stdcout << "done testing polygon formation\n";
Chris@16 963 return true;
Chris@16 964 }
Chris@16 965 //polygon45set class
Chris@16 966
Chris@16 967 template <typename stream_type>
Chris@16 968 static inline bool testPolygon45FormationStar1(stream_type& stdcout) {
Chris@16 969 stdcout << "testing polygon formation\n";
Chris@16 970 Polygon45Formation pf(true);
Chris@16 971 std::vector<Polygon45> polys;
Chris@16 972 std::vector<Vertex45> data;
Chris@16 973 // result == 0 8 -1 1
Chris@16 974 data.push_back(Vertex45(Point(0, 8), -1, 1));
Chris@16 975 // result == 0 8 1 -1
Chris@16 976 data.push_back(Vertex45(Point(0, 8), 1, -1));
Chris@16 977 // result == 4 0 1 1
Chris@16 978 data.push_back(Vertex45(Point(4, 0), 1, 1));
Chris@16 979 // result == 4 0 2 1
Chris@16 980 data.push_back(Vertex45(Point(4, 0), 2, 1));
Chris@16 981 // result == 4 4 2 -1
Chris@16 982 data.push_back(Vertex45(Point(4, 4), 2, -1));
Chris@16 983 // result == 4 4 -1 -1
Chris@16 984 data.push_back(Vertex45(Point(4, 4), -1, -1));
Chris@16 985 // result == 4 12 1 1
Chris@16 986 data.push_back(Vertex45(Point(4, 12), 1, 1));
Chris@16 987 // result == 4 12 2 1
Chris@16 988 data.push_back(Vertex45(Point(4, 12), 2, 1));
Chris@16 989 // result == 4 16 2 -1
Chris@16 990 data.push_back(Vertex45(Point(4, 16), 2, 1));
Chris@16 991 // result == 4 16 -1 -1
Chris@16 992 data.push_back(Vertex45(Point(4, 16), -1, -1));
Chris@16 993 // result == 6 2 1 -1
Chris@16 994 data.push_back(Vertex45(Point(6, 2), 1, -1));
Chris@16 995 // result == 6 14 -1 1
Chris@16 996 data.push_back(Vertex45(Point(6, 14), -1, 1));
Chris@16 997 // result == 6 2 -1 1
Chris@16 998 data.push_back(Vertex45(Point(6, 2), -1, 1));
Chris@16 999 // result == 6 14 1 -1
Chris@16 1000 data.push_back(Vertex45(Point(6, 14), 1, -1));
Chris@16 1001 // result == 8 0 -1 -1
Chris@16 1002 data.push_back(Vertex45(Point(8, 0), -1, -1));
Chris@16 1003 // result == 8 0 2 -1
Chris@16 1004 data.push_back(Vertex45(Point(8, 0), 2, -1));
Chris@16 1005 // result == 8 4 2 1
Chris@16 1006 data.push_back(Vertex45(Point(8, 4), 2, 1));
Chris@16 1007 // result == 8 4 1 1
Chris@16 1008 data.push_back(Vertex45(Point(8, 4), 1, 1));
Chris@16 1009 // result == 8 12 -1 -1
Chris@16 1010 data.push_back(Vertex45(Point(8, 12), -1, -1));
Chris@16 1011 // result == 8 12 2 -1
Chris@16 1012 data.push_back(Vertex45(Point(8, 12), 2, -1));
Chris@16 1013 // result == 8 16 2 1
Chris@16 1014 data.push_back(Vertex45(Point(8, 16), 2, 1));
Chris@16 1015 // result == 8 16 1 1
Chris@16 1016 data.push_back(Vertex45(Point(8, 16), 1, 1));
Chris@16 1017 // result == 12 8 1 -1
Chris@16 1018 data.push_back(Vertex45(Point(12, 8), 1, -1));
Chris@16 1019 // result == 12 8 -1 1
Chris@16 1020 data.push_back(Vertex45(Point(12, 8), -1, 1));
Chris@16 1021 polygon_sort(data.begin(), data.end());
Chris@16 1022 pf.scan(polys, data.begin(), data.end());
Chris@16 1023 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1024 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1025 stdcout << polys[i] << "\n";
Chris@16 1026 }
Chris@16 1027 stdcout << "done testing polygon formation\n";
Chris@16 1028 return true;
Chris@16 1029 }
Chris@16 1030
Chris@16 1031 template <typename stream_type>
Chris@16 1032 static inline bool testPolygon45FormationStar2(stream_type& stdcout) {
Chris@16 1033 stdcout << "testing polygon formation\n";
Chris@16 1034 Polygon45Formation pf(true);
Chris@16 1035 std::vector<Polygon45> polys;
Chris@16 1036 Scan45 scan45;
Chris@16 1037 std::vector<Vertex45 > result;
Chris@16 1038 std::vector<Scan45Vertex> vertices;
Chris@16 1039 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1040 Count2 count(1, 0);
Chris@16 1041 Count2 ncount(-1, 0);
Chris@16 1042 vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1043 vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1044 vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1045 count = Count2(0, 1);
Chris@16 1046 ncount = count.invert();
Chris@16 1047 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1048 vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1049 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1050 sortScan45Vector(vertices);
Chris@16 1051 stdcout << "scanning\n";
Chris@16 1052 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1053
Chris@16 1054 polygon_sort(result.begin(), result.end());
Chris@16 1055 pf.scan(polys, result.begin(), result.end());
Chris@16 1056 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1057 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1058 stdcout << polys[i] << "\n";
Chris@16 1059 }
Chris@16 1060 stdcout << "done testing polygon formation\n";
Chris@16 1061 return true;
Chris@16 1062 }
Chris@16 1063
Chris@16 1064 template <typename stream_type>
Chris@16 1065 static inline bool testPolygon45FormationStarHole1(stream_type& stdcout) {
Chris@16 1066 stdcout << "testing polygon formation\n";
Chris@16 1067 Polygon45Formation pf(true);
Chris@16 1068 std::vector<Polygon45> polys;
Chris@16 1069 std::vector<Vertex45> data;
Chris@16 1070 // result == 0 8 -1 1
Chris@16 1071 data.push_back(Vertex45(Point(0, 8), -1, 1));
Chris@16 1072 // result == 0 8 1 -1
Chris@16 1073 data.push_back(Vertex45(Point(0, 8), 1, -1));
Chris@16 1074 // result == 4 0 1 1
Chris@16 1075 data.push_back(Vertex45(Point(4, 0), 1, 1));
Chris@16 1076 // result == 4 0 2 1
Chris@16 1077 data.push_back(Vertex45(Point(4, 0), 2, 1));
Chris@16 1078 // result == 4 4 2 -1
Chris@16 1079 data.push_back(Vertex45(Point(4, 4), 2, -1));
Chris@16 1080 // result == 4 4 -1 -1
Chris@16 1081 data.push_back(Vertex45(Point(4, 4), -1, -1));
Chris@16 1082 // result == 4 12 1 1
Chris@16 1083 data.push_back(Vertex45(Point(4, 12), 1, 1));
Chris@16 1084 // result == 4 12 2 1
Chris@16 1085 data.push_back(Vertex45(Point(4, 12), 2, 1));
Chris@16 1086 // result == 4 16 2 -1
Chris@16 1087 data.push_back(Vertex45(Point(4, 16), 2, 1));
Chris@16 1088 // result == 4 16 -1 -1
Chris@16 1089 data.push_back(Vertex45(Point(4, 16), -1, -1));
Chris@16 1090 // result == 6 2 1 -1
Chris@16 1091 data.push_back(Vertex45(Point(6, 2), 1, -1));
Chris@16 1092 // result == 6 14 -1 1
Chris@16 1093 data.push_back(Vertex45(Point(6, 14), -1, 1));
Chris@16 1094 // result == 6 2 -1 1
Chris@16 1095 data.push_back(Vertex45(Point(6, 2), -1, 1));
Chris@16 1096 // result == 6 14 1 -1
Chris@16 1097 data.push_back(Vertex45(Point(6, 14), 1, -1));
Chris@16 1098 // result == 8 0 -1 -1
Chris@16 1099 data.push_back(Vertex45(Point(8, 0), -1, -1));
Chris@16 1100 // result == 8 0 2 -1
Chris@16 1101 data.push_back(Vertex45(Point(8, 0), 2, -1));
Chris@16 1102 // result == 8 4 2 1
Chris@16 1103 data.push_back(Vertex45(Point(8, 4), 2, 1));
Chris@16 1104 // result == 8 4 1 1
Chris@16 1105 data.push_back(Vertex45(Point(8, 4), 1, 1));
Chris@16 1106 // result == 8 12 -1 -1
Chris@16 1107 data.push_back(Vertex45(Point(8, 12), -1, -1));
Chris@16 1108 // result == 8 12 2 -1
Chris@16 1109 data.push_back(Vertex45(Point(8, 12), 2, -1));
Chris@16 1110 // result == 8 16 2 1
Chris@16 1111 data.push_back(Vertex45(Point(8, 16), 2, 1));
Chris@16 1112 // result == 8 16 1 1
Chris@16 1113 data.push_back(Vertex45(Point(8, 16), 1, 1));
Chris@16 1114 // result == 12 8 1 -1
Chris@16 1115 data.push_back(Vertex45(Point(12, 8), 1, -1));
Chris@16 1116 // result == 12 8 -1 1
Chris@16 1117 data.push_back(Vertex45(Point(12, 8), -1, 1));
Chris@16 1118
Chris@16 1119 data.push_back(Vertex45(Point(6, 4), 1, -1));
Chris@16 1120 data.push_back(Vertex45(Point(6, 4), 2, -1));
Chris@16 1121 data.push_back(Vertex45(Point(6, 8), -1, 1));
Chris@16 1122 data.push_back(Vertex45(Point(6, 8), 2, 1));
Chris@16 1123 data.push_back(Vertex45(Point(8, 6), -1, -1));
Chris@16 1124 data.push_back(Vertex45(Point(8, 6), 1, 1));
Chris@16 1125
Chris@16 1126 polygon_sort(data.begin(), data.end());
Chris@16 1127 pf.scan(polys, data.begin(), data.end());
Chris@16 1128 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1129 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1130 stdcout << polys[i] << "\n";
Chris@16 1131 }
Chris@16 1132 stdcout << "done testing polygon formation\n";
Chris@16 1133 return true;
Chris@16 1134 }
Chris@16 1135
Chris@16 1136 template <typename stream_type>
Chris@16 1137 static inline bool testPolygon45FormationStarHole2(stream_type& stdcout) {
Chris@16 1138 stdcout << "testing polygon formation\n";
Chris@16 1139 Polygon45Formation pf(false);
Chris@16 1140 std::vector<Polygon45WithHoles> polys;
Chris@16 1141 std::vector<Vertex45> data;
Chris@16 1142 // result == 0 8 -1 1
Chris@16 1143 data.push_back(Vertex45(Point(0, 8), -1, 1));
Chris@16 1144 // result == 0 8 1 -1
Chris@16 1145 data.push_back(Vertex45(Point(0, 8), 1, -1));
Chris@16 1146 // result == 4 0 1 1
Chris@16 1147 data.push_back(Vertex45(Point(4, 0), 1, 1));
Chris@16 1148 // result == 4 0 2 1
Chris@16 1149 data.push_back(Vertex45(Point(4, 0), 2, 1));
Chris@16 1150 // result == 4 4 2 -1
Chris@16 1151 data.push_back(Vertex45(Point(4, 4), 2, -1));
Chris@16 1152 // result == 4 4 -1 -1
Chris@16 1153 data.push_back(Vertex45(Point(4, 4), -1, -1));
Chris@16 1154 // result == 4 12 1 1
Chris@16 1155 data.push_back(Vertex45(Point(4, 12), 1, 1));
Chris@16 1156 // result == 4 12 2 1
Chris@16 1157 data.push_back(Vertex45(Point(4, 12), 2, 1));
Chris@16 1158 // result == 4 16 2 -1
Chris@16 1159 data.push_back(Vertex45(Point(4, 16), 2, 1));
Chris@16 1160 // result == 4 16 -1 -1
Chris@16 1161 data.push_back(Vertex45(Point(4, 16), -1, -1));
Chris@16 1162 // result == 6 2 1 -1
Chris@16 1163 data.push_back(Vertex45(Point(6, 2), 1, -1));
Chris@16 1164 // result == 6 14 -1 1
Chris@16 1165 data.push_back(Vertex45(Point(6, 14), -1, 1));
Chris@16 1166 // result == 6 2 -1 1
Chris@16 1167 data.push_back(Vertex45(Point(6, 2), -1, 1));
Chris@16 1168 // result == 6 14 1 -1
Chris@16 1169 data.push_back(Vertex45(Point(6, 14), 1, -1));
Chris@16 1170 // result == 8 0 -1 -1
Chris@16 1171 data.push_back(Vertex45(Point(8, 0), -1, -1));
Chris@16 1172 // result == 8 0 2 -1
Chris@16 1173 data.push_back(Vertex45(Point(8, 0), 2, -1));
Chris@16 1174 // result == 8 4 2 1
Chris@16 1175 data.push_back(Vertex45(Point(8, 4), 2, 1));
Chris@16 1176 // result == 8 4 1 1
Chris@16 1177 data.push_back(Vertex45(Point(8, 4), 1, 1));
Chris@16 1178 // result == 8 12 -1 -1
Chris@16 1179 data.push_back(Vertex45(Point(8, 12), -1, -1));
Chris@16 1180 // result == 8 12 2 -1
Chris@16 1181 data.push_back(Vertex45(Point(8, 12), 2, -1));
Chris@16 1182 // result == 8 16 2 1
Chris@16 1183 data.push_back(Vertex45(Point(8, 16), 2, 1));
Chris@16 1184 // result == 8 16 1 1
Chris@16 1185 data.push_back(Vertex45(Point(8, 16), 1, 1));
Chris@16 1186 // result == 12 8 1 -1
Chris@16 1187 data.push_back(Vertex45(Point(12, 8), 1, -1));
Chris@16 1188 // result == 12 8 -1 1
Chris@16 1189 data.push_back(Vertex45(Point(12, 8), -1, 1));
Chris@16 1190
Chris@16 1191 data.push_back(Vertex45(Point(6, 4), 1, -1));
Chris@16 1192 data.push_back(Vertex45(Point(6, 4), 2, -1));
Chris@16 1193 data.push_back(Vertex45(Point(6, 12), -1, 1));
Chris@16 1194 data.push_back(Vertex45(Point(6, 12), 2, 1));
Chris@16 1195 data.push_back(Vertex45(Point(10, 8), -1, -1));
Chris@16 1196 data.push_back(Vertex45(Point(10, 8), 1, 1));
Chris@16 1197
Chris@16 1198 polygon_sort(data.begin(), data.end());
Chris@16 1199 pf.scan(polys, data.begin(), data.end());
Chris@16 1200 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1201 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1202 stdcout << polys[i] << "\n";
Chris@16 1203 }
Chris@16 1204 stdcout << "done testing polygon formation\n";
Chris@16 1205 return true;
Chris@16 1206 }
Chris@16 1207
Chris@16 1208 template <typename stream_type>
Chris@16 1209 static inline bool testPolygon45Formation(stream_type& stdcout) {
Chris@16 1210 stdcout << "testing polygon formation\n";
Chris@16 1211 Polygon45Formation pf(false);
Chris@16 1212 std::vector<Polygon45WithHoles> polys;
Chris@16 1213 std::vector<Vertex45> data;
Chris@16 1214
Chris@16 1215 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1216 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1217 data.push_back(Vertex45(Point(0, 100), 2, -1));
Chris@16 1218 data.push_back(Vertex45(Point(0, 100), 0, -1));
Chris@16 1219 data.push_back(Vertex45(Point(100, 0), 0, -1));
Chris@16 1220 data.push_back(Vertex45(Point(100, 0), 2, -1));
Chris@16 1221 data.push_back(Vertex45(Point(100, 100), 2, 1));
Chris@16 1222 data.push_back(Vertex45(Point(100, 100), 0, 1));
Chris@16 1223
Chris@16 1224 data.push_back(Vertex45(Point(2, 2), 0, -1));
Chris@16 1225 data.push_back(Vertex45(Point(2, 2), 2, -1));
Chris@16 1226 data.push_back(Vertex45(Point(2, 10), 2, 1));
Chris@16 1227 data.push_back(Vertex45(Point(2, 10), 0, 1));
Chris@16 1228 data.push_back(Vertex45(Point(10, 2), 0, 1));
Chris@16 1229 data.push_back(Vertex45(Point(10, 2), 2, 1));
Chris@16 1230 data.push_back(Vertex45(Point(10, 10), 2, -1));
Chris@16 1231 data.push_back(Vertex45(Point(10, 10), 0, -1));
Chris@16 1232
Chris@16 1233 data.push_back(Vertex45(Point(2, 12), 0, -1));
Chris@16 1234 data.push_back(Vertex45(Point(2, 12), 2, -1));
Chris@16 1235 data.push_back(Vertex45(Point(2, 22), 2, 1));
Chris@16 1236 data.push_back(Vertex45(Point(2, 22), 0, 1));
Chris@16 1237 data.push_back(Vertex45(Point(10, 12), 0, 1));
Chris@16 1238 data.push_back(Vertex45(Point(10, 12), 2, 1));
Chris@16 1239 data.push_back(Vertex45(Point(10, 22), 2, -1));
Chris@16 1240 data.push_back(Vertex45(Point(10, 22), 0, -1));
Chris@16 1241
Chris@16 1242 polygon_sort(data.begin(), data.end());
Chris@16 1243 pf.scan(polys, data.begin(), data.end());
Chris@16 1244 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1245 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1246 stdcout << polys[i] << "\n";
Chris@16 1247 }
Chris@16 1248 stdcout << "done testing polygon formation\n";
Chris@16 1249 return true;
Chris@16 1250 }
Chris@16 1251
Chris@16 1252
Chris@16 1253 class Polygon45Tiling {
Chris@16 1254 private:
Chris@16 1255 //definitions
Chris@16 1256 typedef std::map<Vertex45, ActiveTail45*, lessVertex45> Polygon45FormationData;
Chris@16 1257 typedef typename Polygon45FormationData::iterator iterator;
Chris@16 1258 typedef typename Polygon45FormationData::const_iterator const_iterator;
Chris@16 1259
Chris@16 1260 //data
Chris@16 1261 Polygon45FormationData scanData_;
Chris@16 1262 Unit x_;
Chris@16 1263 int justBefore_;
Chris@16 1264 public:
Chris@16 1265 inline Polygon45Tiling() : scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false) {
Chris@16 1266 lessVertex45 lessElm(&x_, &justBefore_);
Chris@16 1267 scanData_ = Polygon45FormationData(lessElm);
Chris@16 1268 }
Chris@16 1269 inline Polygon45Tiling(const Polygon45Tiling& that) :
Chris@16 1270 scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false) { (*this) = that; }
Chris@16 1271 inline Polygon45Tiling& operator=(const Polygon45Tiling& that) {
Chris@16 1272 x_ = that.x_;
Chris@16 1273 justBefore_ = that.justBefore_;
Chris@16 1274 lessVertex45 lessElm(&x_, &justBefore_);
Chris@16 1275 scanData_ = Polygon45FormationData(lessElm);
Chris@16 1276 for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
Chris@16 1277 scanData_.insert(scanData_.end(), *itr);
Chris@16 1278 }
Chris@16 1279 return *this;
Chris@16 1280 }
Chris@16 1281
Chris@16 1282 //cT is an output container of Polygon45 or Polygon45WithHoles
Chris@16 1283 //iT is an iterator over Vertex45 elements
Chris@16 1284 //inputBegin - inputEnd is a range of sorted iT that represents
Chris@16 1285 //one or more scanline stops worth of data
Chris@16 1286 template <class cT, class iT>
Chris@16 1287 void scan(cT& output, iT inputBegin, iT inputEnd) {
Chris@16 1288 //std::cout << "1\n";
Chris@16 1289 while(inputBegin != inputEnd) {
Chris@16 1290 //std::cout << "2\n";
Chris@16 1291 x_ = (*inputBegin).pt.x();
Chris@16 1292 //std::cout << "SCAN FORMATION " << x_ << "\n";
Chris@16 1293 //std::cout << "x_ = " << x_ << "\n";
Chris@16 1294 //std::cout << "scan line size: " << scanData_.size() << "\n";
Chris@16 1295 inputBegin = processEvent_(output, inputBegin, inputEnd);
Chris@16 1296 }
Chris@16 1297 }
Chris@16 1298
Chris@16 1299 private:
Chris@16 1300 //functions
Chris@16 1301
Chris@16 1302 inline void getVerticalPair_(std::pair<ActiveTail45*, ActiveTail45*>& verticalPair,
Chris@16 1303 iterator previter) {
Chris@16 1304 ActiveTail45* iterTail = (*previter).second;
Chris@16 1305 Point prevPoint(x_, previter->first.evalAtX(x_));
Chris@16 1306 iterTail->pushPoint(prevPoint);
Chris@16 1307 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
Chris@16 1308 ActiveTail45::createActiveTail45sAsPair(prevPoint, true, 0, false);
Chris@16 1309 verticalPair.first = iterTail;
Chris@16 1310 verticalPair.second = tailPair.first;
Chris@16 1311 (*previter).second = tailPair.second;
Chris@16 1312 }
Chris@16 1313
Chris@16 1314 template <class cT, class cT2>
Chris@16 1315 inline std::pair<int, ActiveTail45*> processPoint_(cT& output, cT2& elements,
Chris@16 1316 std::pair<ActiveTail45*, ActiveTail45*>& verticalPair,
Chris@16 1317 iterator previter, Point point,
Chris@16 1318 Vertex45Count& counts, ActiveTail45** tails, Vertex45Count& incoming) {
Chris@16 1319 //std::cout << point << "\n";
Chris@16 1320 //std::cout << counts[0] << " ";
Chris@16 1321 //std::cout << counts[1] << " ";
Chris@16 1322 //std::cout << counts[2] << " ";
Chris@16 1323 //std::cout << counts[3] << "\n";
Chris@16 1324 //std::cout << incoming[0] << " ";
Chris@16 1325 //std::cout << incoming[1] << " ";
Chris@16 1326 //std::cout << incoming[2] << " ";
Chris@16 1327 //std::cout << incoming[3] << "\n";
Chris@16 1328 //join any closing solid corners
Chris@16 1329 ActiveTail45* returnValue = 0;
Chris@16 1330 std::pair<ActiveTail45*, ActiveTail45*> verticalPairOut;
Chris@16 1331 verticalPairOut.first = 0;
Chris@16 1332 verticalPairOut.second = 0;
Chris@16 1333 int returnCount = 0;
Chris@16 1334 for(int i = 0; i < 3; ++i) {
Chris@16 1335 //std::cout << i << "\n";
Chris@16 1336 if(counts[i] == -1) {
Chris@16 1337 //std::cout << "fixed i\n";
Chris@16 1338 for(int j = i + 1; j < 4; ++j) {
Chris@16 1339 //std::cout << j << "\n";
Chris@16 1340 if(counts[j]) {
Chris@16 1341 if(counts[j] == 1) {
Chris@16 1342 //std::cout << "case1: " << i << " " << j << "\n";
Chris@16 1343 //if a figure is closed it will be written out by this function to output
Chris@16 1344 ActiveTail45::joinChains(point, tails[i], tails[j], true, output);
Chris@16 1345 counts[i] = 0;
Chris@16 1346 counts[j] = 0;
Chris@16 1347 tails[i] = 0;
Chris@16 1348 tails[j] = 0;
Chris@16 1349 }
Chris@16 1350 break;
Chris@16 1351 }
Chris@16 1352 }
Chris@16 1353 }
Chris@16 1354 }
Chris@16 1355 //find any pairs of incoming edges that need to create pair for leading solid
Chris@16 1356 //std::cout << "checking case2\n";
Chris@16 1357 for(int i = 0; i < 3; ++i) {
Chris@16 1358 //std::cout << i << "\n";
Chris@16 1359 if(incoming[i] == 1) {
Chris@16 1360 //std::cout << "fixed i\n";
Chris@16 1361 for(int j = i + 1; j < 4; ++j) {
Chris@16 1362 //std::cout << j << "\n";
Chris@16 1363 if(incoming[j]) {
Chris@16 1364 if(incoming[j] == -1) {
Chris@16 1365 //std::cout << "case2: " << i << " " << j << "\n";
Chris@16 1366 //std::cout << "creating active tail pair\n";
Chris@16 1367 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
Chris@16 1368 ActiveTail45::createActiveTail45sAsPair(point, true, 0, false);
Chris@16 1369 //tailPair.first->print();
Chris@16 1370 //tailPair.second->print();
Chris@16 1371 if(j == 3) {
Chris@16 1372 //vertical active tail becomes return value
Chris@16 1373 returnValue = tailPair.first;
Chris@16 1374 returnCount = 1;
Chris@16 1375 } else {
Chris@16 1376 Vertex45 vertex(point, i -1, incoming[i]);
Chris@16 1377 //std::cout << "new element " << j-1 << " " << -1 << "\n";
Chris@16 1378 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, -1), tailPair.first));
Chris@16 1379 }
Chris@16 1380 //std::cout << "new element " << i-1 << " " << 1 << "\n";
Chris@16 1381 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, 1), tailPair.second));
Chris@16 1382 incoming[i] = 0;
Chris@16 1383 incoming[j] = 0;
Chris@16 1384 }
Chris@16 1385 break;
Chris@16 1386 }
Chris@16 1387 }
Chris@16 1388 }
Chris@16 1389 }
Chris@16 1390
Chris@16 1391 //find any active tail that needs to pass through to an incoming edge
Chris@16 1392 //we expect to find no more than two pass through
Chris@16 1393
Chris@16 1394 //find pass through with solid on top
Chris@16 1395 //std::cout << "checking case 3\n";
Chris@16 1396 for(int i = 0; i < 4; ++i) {
Chris@16 1397 //std::cout << i << "\n";
Chris@16 1398 if(counts[i] != 0) {
Chris@16 1399 if(counts[i] == 1) {
Chris@16 1400 //std::cout << "fixed i\n";
Chris@16 1401 for(int j = 3; j >= 0; --j) {
Chris@16 1402 if(incoming[j] != 0) {
Chris@16 1403 if(incoming[j] == 1) {
Chris@16 1404 //std::cout << "case3: " << i << " " << j << "\n";
Chris@16 1405 //tails[i]->print();
Chris@16 1406 //pass through solid on top
Chris@16 1407 if(i != 3)
Chris@16 1408 tails[i]->pushPoint(point);
Chris@16 1409 //std::cout << "after push\n";
Chris@16 1410 if(j == 3) {
Chris@16 1411 returnValue = tails[i];
Chris@16 1412 returnCount = -1;
Chris@16 1413 } else {
Chris@16 1414 verticalPairOut.first = tails[i];
Chris@16 1415 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
Chris@16 1416 ActiveTail45::createActiveTail45sAsPair(point, true, 0, false);
Chris@16 1417 verticalPairOut.second = tailPair.first;
Chris@16 1418 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]),
Chris@16 1419 tailPair.second));
Chris@16 1420 }
Chris@16 1421 tails[i] = 0;
Chris@16 1422 counts[i] = 0;
Chris@16 1423 incoming[j] = 0;
Chris@16 1424 }
Chris@16 1425 break;
Chris@16 1426 }
Chris@16 1427 }
Chris@16 1428 }
Chris@16 1429 break;
Chris@16 1430 }
Chris@16 1431 }
Chris@16 1432 //std::cout << "checking case 4\n";
Chris@16 1433 //find pass through with solid on bottom
Chris@16 1434 for(int i = 3; i >= 0; --i) {
Chris@16 1435 if(counts[i] != 0) {
Chris@16 1436 if(counts[i] == -1) {
Chris@16 1437 for(int j = 0; j < 4; ++j) {
Chris@16 1438 if(incoming[j] != 0) {
Chris@16 1439 if(incoming[j] == -1) {
Chris@16 1440 //std::cout << "case4: " << i << " " << j << "\n";
Chris@16 1441 //pass through solid on bottom
Chris@16 1442 if(i == 3) {
Chris@16 1443 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
Chris@16 1444 if(j == 3) {
Chris@16 1445 returnValue = tails[i];
Chris@16 1446 returnCount = 1;
Chris@16 1447 } else {
Chris@16 1448 tails[i]->pushPoint(point);
Chris@16 1449 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tails[i]));
Chris@16 1450 }
Chris@16 1451 } else if(j == 3) {
Chris@16 1452 if(verticalPair.first == 0) {
Chris@16 1453 getVerticalPair_(verticalPair, previter);
Chris@16 1454 }
Chris@16 1455 ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output);
Chris@16 1456 returnValue = verticalPair.second;
Chris@16 1457 returnCount = 1;
Chris@16 1458 } else {
Chris@16 1459 if(verticalPair.first == 0) {
Chris@16 1460 getVerticalPair_(verticalPair, previter);
Chris@16 1461 }
Chris@16 1462 ActiveTail45::joinChains(point, tails[i], verticalPair.first, true, output);
Chris@16 1463 verticalPair.second->pushPoint(point);
Chris@16 1464 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]),
Chris@16 1465 verticalPair.second));
Chris@16 1466 }
Chris@16 1467 tails[i] = 0;
Chris@16 1468 counts[i] = 0;
Chris@16 1469 incoming[j] = 0;
Chris@16 1470 }
Chris@16 1471 break;
Chris@16 1472 }
Chris@16 1473 }
Chris@16 1474 }
Chris@16 1475 break;
Chris@16 1476 }
Chris@16 1477 }
Chris@16 1478
Chris@16 1479 //find the end of a hole or the beginning of a hole
Chris@16 1480
Chris@16 1481 //find end of a hole
Chris@16 1482 for(int i = 0; i < 3; ++i) {
Chris@16 1483 if(counts[i] != 0) {
Chris@16 1484 for(int j = i+1; j < 4; ++j) {
Chris@16 1485 if(counts[j] != 0) {
Chris@16 1486 //std::cout << "case5: " << i << " " << j << "\n";
Chris@16 1487 //we are ending a hole and may potentially close a figure and have to handle the hole
Chris@16 1488 tails[i]->pushPoint(point);
Chris@16 1489 verticalPairOut.first = tails[i];
Chris@16 1490 if(j == 3) {
Chris@16 1491 verticalPairOut.second = tails[j];
Chris@16 1492 } else {
Chris@16 1493 if(verticalPair.first == 0) {
Chris@16 1494 getVerticalPair_(verticalPair, previter);
Chris@16 1495 }
Chris@16 1496 ActiveTail45::joinChains(point, tails[j], verticalPair.first, true, output);
Chris@16 1497 verticalPairOut.second = verticalPair.second;
Chris@16 1498 }
Chris@16 1499 tails[i] = 0;
Chris@16 1500 tails[j] = 0;
Chris@16 1501 counts[i] = 0;
Chris@16 1502 counts[j] = 0;
Chris@16 1503 break;
Chris@16 1504 }
Chris@16 1505 }
Chris@16 1506 break;
Chris@16 1507 }
Chris@16 1508 }
Chris@16 1509 //find beginning of a hole
Chris@16 1510 for(int i = 0; i < 3; ++i) {
Chris@16 1511 if(incoming[i] != 0) {
Chris@16 1512 for(int j = i+1; j < 4; ++j) {
Chris@16 1513 if(incoming[j] != 0) {
Chris@16 1514 //std::cout << "case6: " << i << " " << j << "\n";
Chris@16 1515 //we are beginning a empty space
Chris@16 1516 if(verticalPair.first == 0) {
Chris@16 1517 getVerticalPair_(verticalPair, previter);
Chris@16 1518 }
Chris@16 1519 verticalPair.second->pushPoint(point);
Chris@16 1520 if(j == 3) {
Chris@16 1521 returnValue = verticalPair.first;
Chris@16 1522 returnCount = -1;
Chris@16 1523 } else {
Chris@16 1524 std::pair<ActiveTail45*, ActiveTail45*> tailPair =
Chris@16 1525 ActiveTail45::createActiveTail45sAsPair(point, true, 0, false);
Chris@16 1526 //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
Chris@16 1527 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, j -1, incoming[j]), tailPair.second));
Chris@16 1528 verticalPairOut.second = tailPair.first;
Chris@16 1529 verticalPairOut.first = verticalPair.first;
Chris@16 1530 }
Chris@16 1531 //std::cout << "new element " << i-1 << " " << incoming[i] << "\n";
Chris@16 1532 elements.push_back(std::pair<Vertex45, ActiveTail45*>(Vertex45(point, i -1, incoming[i]), verticalPair.second));
Chris@16 1533 incoming[i] = 0;
Chris@16 1534 incoming[j] = 0;
Chris@16 1535 break;
Chris@16 1536 }
Chris@16 1537 }
Chris@16 1538 break;
Chris@16 1539 }
Chris@16 1540 }
Chris@16 1541 verticalPair = verticalPairOut;
Chris@16 1542 //assert that verticalPair is either both null, or neither null
Chris@16 1543 //assert that returnValue is null if verticalPair is not null
Chris@16 1544 //assert that tails, counts and incoming are all null
Chris@16 1545 return std::pair<int, ActiveTail45*>(returnCount, returnValue);
Chris@16 1546 }
Chris@16 1547
Chris@16 1548 template <class cT, class iT>
Chris@16 1549 inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
Chris@16 1550 //std::cout << "processEvent_\n";
Chris@16 1551 justBefore_ = true;
Chris@16 1552 //collect up all elements from the tree that are at the y
Chris@16 1553 //values of events in the input queue
Chris@16 1554 //create vector of new elements to add into tree
Chris@16 1555 ActiveTail45* verticalTail = 0;
Chris@16 1556 std::pair<ActiveTail45*, ActiveTail45*> verticalPair;
Chris@16 1557 verticalPair.first = 0;
Chris@16 1558 verticalPair.second = 0;
Chris@16 1559 int verticalCount = 0;
Chris@16 1560 iT currentIter = inputBegin;
Chris@16 1561 std::vector<iterator> elementIters;
Chris@16 1562 std::vector<std::pair<Vertex45, ActiveTail45*> > elements;
Chris@16 1563 while(currentIter != inputEnd && currentIter->pt.x() == x_) {
Chris@16 1564 //std::cout << "loop\n";
Chris@16 1565 Unit currentY = (*currentIter).pt.y();
Chris@16 1566 iterator iter = lookUp_(currentY);
Chris@16 1567 //int counts[4] = {0, 0, 0, 0};
Chris@16 1568 Vertex45Count counts;
Chris@16 1569 ActiveTail45* tails[4] = {0, 0, 0, verticalTail};
Chris@16 1570 //std::cout << "finding elements in tree\n";
Chris@16 1571 iterator previter = iter;
Chris@16 1572 if(previter != scanData_.end() &&
Chris@16 1573 previter->first.evalAtX(x_) >= currentY &&
Chris@16 1574 previter != scanData_.begin())
Chris@16 1575 --previter;
Chris@16 1576 while(iter != scanData_.end() &&
Chris@16 1577 iter->first.evalAtX(x_) == currentY) {
Chris@16 1578 //std::cout << "loop2\n";
Chris@16 1579 elementIters.push_back(iter);
Chris@16 1580 int index = iter->first.rise + 1;
Chris@16 1581 //std::cout << index << " " << iter->first.count << "\n";
Chris@16 1582 counts[index] = iter->first.count;
Chris@16 1583 tails[index] = iter->second;
Chris@16 1584 ++iter;
Chris@16 1585 }
Chris@16 1586 //int incoming[4] = {0, 0, 0, 0};
Chris@16 1587 Vertex45Count incoming;
Chris@16 1588 //std::cout << "aggregating\n";
Chris@16 1589 do {
Chris@16 1590 //std::cout << "loop3\n";
Chris@16 1591 Vertex45Compact currentVertex(*currentIter);
Chris@16 1592 incoming += currentVertex.count;
Chris@16 1593 ++currentIter;
Chris@16 1594 } while(currentIter != inputEnd && currentIter->pt.y() == currentY &&
Chris@16 1595 currentIter->pt.x() == x_);
Chris@16 1596 //now counts and tails have the data from the left and
Chris@16 1597 //incoming has the data from the right at this point
Chris@16 1598 //cancel out any end points
Chris@16 1599 //std::cout << counts[0] << " ";
Chris@16 1600 //std::cout << counts[1] << " ";
Chris@16 1601 //std::cout << counts[2] << " ";
Chris@16 1602 //std::cout << counts[3] << "\n";
Chris@16 1603 //std::cout << incoming[0] << " ";
Chris@16 1604 //std::cout << incoming[1] << " ";
Chris@16 1605 //std::cout << incoming[2] << " ";
Chris@16 1606 //std::cout << incoming[3] << "\n";
Chris@16 1607 if(verticalTail) {
Chris@16 1608 counts[3] = -verticalCount;
Chris@16 1609 }
Chris@16 1610 incoming[3] *= -1;
Chris@16 1611 for(unsigned int i = 0; i < 4; ++i) incoming[i] += counts[i];
Chris@16 1612 //std::cout << "calling processPoint_\n";
Chris@16 1613 std::pair<int, ActiveTail45*> result = processPoint_(output, elements, verticalPair, previter,
Chris@16 1614 Point(x_, currentY), counts, tails, incoming);
Chris@16 1615 verticalCount = result.first;
Chris@16 1616 verticalTail = result.second;
Chris@16 1617 if(verticalPair.first != 0 && iter != scanData_.end() &&
Chris@16 1618 (currentIter == inputEnd || currentIter->pt.x() != x_ ||
Chris@16 1619 currentIter->pt.y() > (*iter).first.evalAtX(x_))) {
Chris@16 1620 //splice vertical pair into edge above
Chris@16 1621 ActiveTail45* tailabove = (*iter).second;
Chris@16 1622 Point point(x_, (*iter).first.evalAtX(x_));
Chris@16 1623 verticalPair.second->pushPoint(point);
Chris@16 1624 ActiveTail45::joinChains(point, tailabove, verticalPair.first, true, output);
Chris@16 1625 (*iter).second = verticalPair.second;
Chris@16 1626 verticalPair.first = 0;
Chris@16 1627 verticalPair.second = 0;
Chris@16 1628 }
Chris@16 1629 }
Chris@16 1630 //std::cout << "erasing\n";
Chris@16 1631 //erase all elements from the tree
Chris@16 1632 for(typename std::vector<iterator>::iterator iter = elementIters.begin();
Chris@16 1633 iter != elementIters.end(); ++iter) {
Chris@16 1634 //std::cout << "erasing loop\n";
Chris@16 1635 scanData_.erase(*iter);
Chris@16 1636 }
Chris@16 1637 //switch comparison tie breaking policy
Chris@16 1638 justBefore_ = false;
Chris@16 1639 //add new elements into tree
Chris@16 1640 //std::cout << "inserting\n";
Chris@16 1641 for(typename std::vector<std::pair<Vertex45, ActiveTail45*> >::iterator iter = elements.begin();
Chris@16 1642 iter != elements.end(); ++iter) {
Chris@16 1643 //std::cout << "inserting loop\n";
Chris@16 1644 scanData_.insert(scanData_.end(), *iter);
Chris@16 1645 }
Chris@16 1646 //std::cout << "end processEvent\n";
Chris@16 1647 return currentIter;
Chris@16 1648 }
Chris@16 1649
Chris@16 1650 inline iterator lookUp_(Unit y){
Chris@16 1651 //if just before then we need to look from 1 not -1
Chris@16 1652 return scanData_.lower_bound(Vertex45(Point(x_, y), -1+2*justBefore_, 0));
Chris@16 1653 }
Chris@16 1654
Chris@16 1655 };
Chris@16 1656
Chris@16 1657 template <typename stream_type>
Chris@16 1658 static inline bool testPolygon45TilingRect(stream_type& stdcout) {
Chris@16 1659 stdcout << "testing polygon tiling\n";
Chris@16 1660 Polygon45Tiling pf;
Chris@16 1661 std::vector<Polygon45> polys;
Chris@16 1662 std::vector<Vertex45> data;
Chris@16 1663 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1664 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1665 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1666 data.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 1667 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 1668 data.push_back(Vertex45(Point(10, 0), 2, -1));
Chris@16 1669 data.push_back(Vertex45(Point(10, 10), 2, 1));
Chris@16 1670 data.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 1671 polygon_sort(data.begin(), data.end());
Chris@16 1672 pf.scan(polys, data.begin(), data.end());
Chris@16 1673 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1674 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1675 stdcout << polys[i] << "\n";
Chris@16 1676 }
Chris@16 1677 stdcout << "done testing polygon tiling\n";
Chris@16 1678 return true;
Chris@16 1679 }
Chris@16 1680
Chris@16 1681 template <typename stream_type>
Chris@16 1682 static inline bool testPolygon45TilingP1(stream_type& stdcout) {
Chris@16 1683 stdcout << "testing polygon tiling\n";
Chris@16 1684 Polygon45Tiling pf;
Chris@16 1685 std::vector<Polygon45> polys;
Chris@16 1686 std::vector<Vertex45> data;
Chris@16 1687 data.push_back(Vertex45(Point(0, 0), 1, 1));
Chris@16 1688 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1689 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1690 data.push_back(Vertex45(Point(0, 10), 1, -1));
Chris@16 1691 data.push_back(Vertex45(Point(10, 10), 1, -1));
Chris@16 1692 data.push_back(Vertex45(Point(10, 10), 2, -1));
Chris@16 1693 data.push_back(Vertex45(Point(10, 20), 2, 1));
Chris@16 1694 data.push_back(Vertex45(Point(10, 20), 1, 1));
Chris@16 1695 polygon_sort(data.begin(), data.end());
Chris@16 1696 pf.scan(polys, data.begin(), data.end());
Chris@16 1697 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1698 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1699 stdcout << polys[i] << "\n";
Chris@16 1700 }
Chris@16 1701 stdcout << "done testing polygon tiling\n";
Chris@16 1702 return true;
Chris@16 1703 }
Chris@16 1704
Chris@16 1705 template <typename stream_type>
Chris@16 1706 static inline bool testPolygon45TilingP2(stream_type& stdcout) {
Chris@16 1707 stdcout << "testing polygon tiling\n";
Chris@16 1708 Polygon45Tiling pf;
Chris@16 1709 std::vector<Polygon45> polys;
Chris@16 1710 std::vector<Vertex45> data;
Chris@16 1711 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1712 data.push_back(Vertex45(Point(0, 0), 1, -1));
Chris@16 1713 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 1714 data.push_back(Vertex45(Point(10, 0), 1, 1));
Chris@16 1715 data.push_back(Vertex45(Point(10, 10), 1, 1));
Chris@16 1716 data.push_back(Vertex45(Point(10, 10), 0, -1));
Chris@16 1717 data.push_back(Vertex45(Point(20, 10), 1, -1));
Chris@16 1718 data.push_back(Vertex45(Point(20, 10), 0, 1));
Chris@16 1719 polygon_sort(data.begin(), data.end());
Chris@16 1720 pf.scan(polys, data.begin(), data.end());
Chris@16 1721 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1722 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1723 stdcout << polys[i] << "\n";
Chris@16 1724 }
Chris@16 1725 stdcout << "done testing polygon tiling\n";
Chris@16 1726 return true;
Chris@16 1727 }
Chris@16 1728
Chris@16 1729 template <typename stream_type>
Chris@16 1730 static inline bool testPolygon45TilingP3(stream_type& stdcout) {
Chris@16 1731 stdcout << "testing polygon tiling\n";
Chris@16 1732 Polygon45Tiling pf;
Chris@16 1733 std::vector<Polygon45> polys;
Chris@16 1734 std::vector<Vertex45> data;
Chris@16 1735 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1736 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1737 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1738 data.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 1739 data.push_back(Vertex45(Point(20, 0), 0, -1));
Chris@16 1740 data.push_back(Vertex45(Point(20, 0), 2, -1));
Chris@16 1741 data.push_back(Vertex45(Point(10, 10), 1, -1));
Chris@16 1742 data.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 1743 data.push_back(Vertex45(Point(20, 20), 1, 1));
Chris@16 1744 data.push_back(Vertex45(Point(20, 20), 2, 1));
Chris@16 1745 polygon_sort(data.begin(), data.end());
Chris@16 1746 pf.scan(polys, data.begin(), data.end());
Chris@16 1747 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1748 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1749 stdcout << polys[i] << "\n";
Chris@16 1750 }
Chris@16 1751 stdcout << "done testing polygon tiling\n";
Chris@16 1752 return true;
Chris@16 1753 }
Chris@16 1754
Chris@16 1755 template <typename stream_type>
Chris@16 1756 static inline bool testPolygon45TilingP4(stream_type& stdcout) {
Chris@16 1757 stdcout << "testing polygon tiling p4\n";
Chris@16 1758 Polygon45Tiling pf;
Chris@16 1759 std::vector<Polygon45> polys;
Chris@16 1760 std::vector<Vertex45> data;
Chris@16 1761 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1762 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1763 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1764 data.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 1765 data.push_back(Vertex45(Point(10, 0), -1, 1));
Chris@16 1766 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 1767 data.push_back(Vertex45(Point(20, 10), 2, 1));
Chris@16 1768 data.push_back(Vertex45(Point(20, 10), 0, 1));
Chris@16 1769 data.push_back(Vertex45(Point(20, -10), -1, -1));
Chris@16 1770 data.push_back(Vertex45(Point(20, -10), 2, -1));
Chris@16 1771 polygon_sort(data.begin(), data.end());
Chris@16 1772 pf.scan(polys, data.begin(), data.end());
Chris@16 1773 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1774 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1775 stdcout << polys[i] << "\n";
Chris@16 1776 }
Chris@16 1777 stdcout << "done testing polygon tiling\n";
Chris@16 1778 return true;
Chris@16 1779 }
Chris@16 1780
Chris@16 1781 template <typename stream_type>
Chris@16 1782 static inline bool testPolygon45TilingP5(stream_type& stdcout) {
Chris@16 1783 stdcout << "testing polygon tiling P5\n";
Chris@16 1784 Polygon45Tiling pf;
Chris@16 1785 std::vector<Polygon45> polys;
Chris@16 1786 std::vector<Vertex45> data;
Chris@16 1787 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1788 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1789 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1790 data.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 1791 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 1792 data.push_back(Vertex45(Point(10, 0), 2, -1));
Chris@16 1793 data.push_back(Vertex45(Point(10, 10), 2, 1));
Chris@16 1794 data.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 1795
Chris@16 1796 data.push_back(Vertex45(Point(1, 1), 0, -1));
Chris@16 1797 data.push_back(Vertex45(Point(1, 1), 1, 1));
Chris@16 1798 data.push_back(Vertex45(Point(2, 1), 0, 1));
Chris@16 1799 data.push_back(Vertex45(Point(2, 1), 1, -1));
Chris@16 1800 data.push_back(Vertex45(Point(2, 2), 1, -1));
Chris@16 1801 data.push_back(Vertex45(Point(2, 2), 0, 1));
Chris@16 1802 data.push_back(Vertex45(Point(3, 2), 1, 1));
Chris@16 1803 data.push_back(Vertex45(Point(3, 2), 0, -1));
Chris@16 1804 polygon_sort(data.begin(), data.end());
Chris@16 1805 pf.scan(polys, data.begin(), data.end());
Chris@16 1806 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1807 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1808 stdcout << polys[i] << "\n";
Chris@16 1809 }
Chris@16 1810 stdcout << "done testing polygon tiling\n";
Chris@16 1811 return true;
Chris@16 1812 }
Chris@16 1813
Chris@16 1814 template <typename stream_type>
Chris@16 1815 static inline bool testPolygon45TilingP6(stream_type& stdcout) {
Chris@16 1816 stdcout << "testing polygon tiling P6\n";
Chris@16 1817 Polygon45Tiling pf;
Chris@16 1818 std::vector<Polygon45> polys;
Chris@16 1819 std::vector<Vertex45> data;
Chris@16 1820 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1821 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1822 data.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1823 data.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 1824 data.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 1825 data.push_back(Vertex45(Point(10, 0), 2, -1));
Chris@16 1826 data.push_back(Vertex45(Point(10, 10), 2, 1));
Chris@16 1827 data.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 1828
Chris@16 1829 data.push_back(Vertex45(Point(1, 1), 0, -1));
Chris@16 1830 data.push_back(Vertex45(Point(1, 1), 2, -1));
Chris@16 1831 data.push_back(Vertex45(Point(1, 2), 2, 1));
Chris@16 1832 data.push_back(Vertex45(Point(1, 2), 0, 1));
Chris@16 1833 data.push_back(Vertex45(Point(2, 1), 0, 1));
Chris@16 1834 data.push_back(Vertex45(Point(2, 1), 2, 1));
Chris@16 1835 data.push_back(Vertex45(Point(2, 2), 2, -1));
Chris@16 1836 data.push_back(Vertex45(Point(2, 2), 0, -1));
Chris@16 1837
Chris@16 1838 polygon_sort(data.begin(), data.end());
Chris@16 1839 pf.scan(polys, data.begin(), data.end());
Chris@16 1840 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1841 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1842 stdcout << polys[i] << "\n";
Chris@16 1843 }
Chris@16 1844 stdcout << "done testing polygon tiling\n";
Chris@16 1845 return true;
Chris@16 1846 }
Chris@16 1847
Chris@16 1848 template <typename stream_type>
Chris@16 1849 static inline bool testPolygon45TilingStar1(stream_type& stdcout) {
Chris@16 1850 stdcout << "testing polygon tiling star1\n";
Chris@16 1851 Polygon45Tiling pf;
Chris@16 1852 std::vector<Polygon45> polys;
Chris@16 1853 std::vector<Vertex45> data;
Chris@16 1854 // result == 0 8 -1 1
Chris@16 1855 data.push_back(Vertex45(Point(0, 8), -1, 1));
Chris@16 1856 // result == 0 8 1 -1
Chris@16 1857 data.push_back(Vertex45(Point(0, 8), 1, -1));
Chris@16 1858 // result == 4 0 1 1
Chris@16 1859 data.push_back(Vertex45(Point(4, 0), 1, 1));
Chris@16 1860 // result == 4 0 2 1
Chris@16 1861 data.push_back(Vertex45(Point(4, 0), 2, 1));
Chris@16 1862 // result == 4 4 2 -1
Chris@16 1863 data.push_back(Vertex45(Point(4, 4), 2, -1));
Chris@16 1864 // result == 4 4 -1 -1
Chris@16 1865 data.push_back(Vertex45(Point(4, 4), -1, -1));
Chris@16 1866 // result == 4 12 1 1
Chris@16 1867 data.push_back(Vertex45(Point(4, 12), 1, 1));
Chris@16 1868 // result == 4 12 2 1
Chris@16 1869 data.push_back(Vertex45(Point(4, 12), 2, 1));
Chris@16 1870 // result == 4 16 2 -1
Chris@16 1871 data.push_back(Vertex45(Point(4, 16), 2, 1));
Chris@16 1872 // result == 4 16 -1 -1
Chris@16 1873 data.push_back(Vertex45(Point(4, 16), -1, -1));
Chris@16 1874 // result == 6 2 1 -1
Chris@16 1875 data.push_back(Vertex45(Point(6, 2), 1, -1));
Chris@16 1876 // result == 6 14 -1 1
Chris@16 1877 data.push_back(Vertex45(Point(6, 14), -1, 1));
Chris@16 1878 // result == 6 2 -1 1
Chris@16 1879 data.push_back(Vertex45(Point(6, 2), -1, 1));
Chris@16 1880 // result == 6 14 1 -1
Chris@16 1881 data.push_back(Vertex45(Point(6, 14), 1, -1));
Chris@16 1882 // result == 8 0 -1 -1
Chris@16 1883 data.push_back(Vertex45(Point(8, 0), -1, -1));
Chris@16 1884 // result == 8 0 2 -1
Chris@16 1885 data.push_back(Vertex45(Point(8, 0), 2, -1));
Chris@16 1886 // result == 8 4 2 1
Chris@16 1887 data.push_back(Vertex45(Point(8, 4), 2, 1));
Chris@16 1888 // result == 8 4 1 1
Chris@16 1889 data.push_back(Vertex45(Point(8, 4), 1, 1));
Chris@16 1890 // result == 8 12 -1 -1
Chris@16 1891 data.push_back(Vertex45(Point(8, 12), -1, -1));
Chris@16 1892 // result == 8 12 2 -1
Chris@16 1893 data.push_back(Vertex45(Point(8, 12), 2, -1));
Chris@16 1894 // result == 8 16 2 1
Chris@16 1895 data.push_back(Vertex45(Point(8, 16), 2, 1));
Chris@16 1896 // result == 8 16 1 1
Chris@16 1897 data.push_back(Vertex45(Point(8, 16), 1, 1));
Chris@16 1898 // result == 12 8 1 -1
Chris@16 1899 data.push_back(Vertex45(Point(12, 8), 1, -1));
Chris@16 1900 // result == 12 8 -1 1
Chris@16 1901 data.push_back(Vertex45(Point(12, 8), -1, 1));
Chris@16 1902 polygon_sort(data.begin(), data.end());
Chris@16 1903 pf.scan(polys, data.begin(), data.end());
Chris@16 1904 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1905 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1906 stdcout << polys[i] << "\n";
Chris@16 1907 }
Chris@16 1908 stdcout << "done testing polygon tiling\n";
Chris@16 1909 return true;
Chris@16 1910 }
Chris@16 1911
Chris@16 1912 template <typename stream_type>
Chris@16 1913 static inline bool testPolygon45TilingStar2(stream_type& stdcout) {
Chris@16 1914 stdcout << "testing polygon tiling\n";
Chris@16 1915 Polygon45Tiling pf;
Chris@16 1916 std::vector<Polygon45> polys;
Chris@16 1917
Chris@16 1918 Scan45 scan45;
Chris@16 1919 std::vector<Vertex45 > result;
Chris@16 1920 std::vector<Scan45Vertex> vertices;
Chris@16 1921 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1922 Count2 count(1, 0);
Chris@16 1923 Count2 ncount(-1, 0);
Chris@16 1924 vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1925 vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1926 vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1927 count = Count2(0, 1);
Chris@16 1928 ncount = count.invert();
Chris@16 1929 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1930 vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1931 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1932 sortScan45Vector(vertices);
Chris@16 1933 stdcout << "scanning\n";
Chris@16 1934 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1935
Chris@16 1936 polygon_sort(result.begin(), result.end());
Chris@16 1937 pf.scan(polys, result.begin(), result.end());
Chris@16 1938 stdcout << "result size: " << polys.size() << "\n";
Chris@16 1939 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 1940 stdcout << polys[i] << "\n";
Chris@16 1941 }
Chris@16 1942 stdcout << "done testing polygon tiling\n";
Chris@16 1943 return true;
Chris@16 1944 }
Chris@16 1945
Chris@16 1946 template <typename stream_type>
Chris@16 1947 static inline bool testPolygon45TilingStarHole1(stream_type& stdcout) {
Chris@16 1948 stdcout << "testing polygon tiling star hole 1\n";
Chris@16 1949 Polygon45Tiling pf;
Chris@16 1950 std::vector<Polygon45> polys;
Chris@16 1951 std::vector<Vertex45> data;
Chris@16 1952 // result == 0 8 -1 1
Chris@16 1953 data.push_back(Vertex45(Point(0, 8), -1, 1));
Chris@16 1954 // result == 0 8 1 -1
Chris@16 1955 data.push_back(Vertex45(Point(0, 8), 1, -1));
Chris@16 1956 // result == 4 0 1 1
Chris@16 1957 data.push_back(Vertex45(Point(4, 0), 1, 1));
Chris@16 1958 // result == 4 0 2 1
Chris@16 1959 data.push_back(Vertex45(Point(4, 0), 2, 1));
Chris@16 1960 // result == 4 4 2 -1
Chris@16 1961 data.push_back(Vertex45(Point(4, 4), 2, -1));
Chris@16 1962 // result == 4 4 -1 -1
Chris@16 1963 data.push_back(Vertex45(Point(4, 4), -1, -1));
Chris@16 1964 // result == 4 12 1 1
Chris@16 1965 data.push_back(Vertex45(Point(4, 12), 1, 1));
Chris@16 1966 // result == 4 12 2 1
Chris@16 1967 data.push_back(Vertex45(Point(4, 12), 2, 1));
Chris@16 1968 // result == 4 16 2 -1
Chris@16 1969 data.push_back(Vertex45(Point(4, 16), 2, 1));
Chris@16 1970 // result == 4 16 -1 -1
Chris@16 1971 data.push_back(Vertex45(Point(4, 16), -1, -1));
Chris@16 1972 // result == 6 2 1 -1
Chris@16 1973 data.push_back(Vertex45(Point(6, 2), 1, -1));
Chris@16 1974 // result == 6 14 -1 1
Chris@16 1975 data.push_back(Vertex45(Point(6, 14), -1, 1));
Chris@16 1976 // result == 6 2 -1 1
Chris@16 1977 data.push_back(Vertex45(Point(6, 2), -1, 1));
Chris@16 1978 // result == 6 14 1 -1
Chris@16 1979 data.push_back(Vertex45(Point(6, 14), 1, -1));
Chris@16 1980 // result == 8 0 -1 -1
Chris@16 1981 data.push_back(Vertex45(Point(8, 0), -1, -1));
Chris@16 1982 // result == 8 0 2 -1
Chris@16 1983 data.push_back(Vertex45(Point(8, 0), 2, -1));
Chris@16 1984 // result == 8 4 2 1
Chris@16 1985 data.push_back(Vertex45(Point(8, 4), 2, 1));
Chris@16 1986 // result == 8 4 1 1
Chris@16 1987 data.push_back(Vertex45(Point(8, 4), 1, 1));
Chris@16 1988 // result == 8 12 -1 -1
Chris@16 1989 data.push_back(Vertex45(Point(8, 12), -1, -1));
Chris@16 1990 // result == 8 12 2 -1
Chris@16 1991 data.push_back(Vertex45(Point(8, 12), 2, -1));
Chris@16 1992 // result == 8 16 2 1
Chris@16 1993 data.push_back(Vertex45(Point(8, 16), 2, 1));
Chris@16 1994 // result == 8 16 1 1
Chris@16 1995 data.push_back(Vertex45(Point(8, 16), 1, 1));
Chris@16 1996 // result == 12 8 1 -1
Chris@16 1997 data.push_back(Vertex45(Point(12, 8), 1, -1));
Chris@16 1998 // result == 12 8 -1 1
Chris@16 1999 data.push_back(Vertex45(Point(12, 8), -1, 1));
Chris@16 2000
Chris@16 2001 data.push_back(Vertex45(Point(6, 4), 1, -1));
Chris@16 2002 data.push_back(Vertex45(Point(6, 4), 2, -1));
Chris@16 2003 data.push_back(Vertex45(Point(6, 8), -1, 1));
Chris@16 2004 data.push_back(Vertex45(Point(6, 8), 2, 1));
Chris@16 2005 data.push_back(Vertex45(Point(8, 6), -1, -1));
Chris@16 2006 data.push_back(Vertex45(Point(8, 6), 1, 1));
Chris@16 2007
Chris@16 2008 polygon_sort(data.begin(), data.end());
Chris@16 2009 pf.scan(polys, data.begin(), data.end());
Chris@16 2010 stdcout << "result size: " << polys.size() << "\n";
Chris@16 2011 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 2012 stdcout << polys[i] << "\n";
Chris@16 2013 }
Chris@16 2014 stdcout << "done testing polygon tiling\n";
Chris@16 2015 return true;
Chris@16 2016 }
Chris@16 2017
Chris@16 2018 template <typename stream_type>
Chris@16 2019 static inline bool testPolygon45TilingStarHole2(stream_type& stdcout) {
Chris@16 2020 stdcout << "testing polygon tiling star hole 2\n";
Chris@16 2021 Polygon45Tiling pf;
Chris@16 2022 std::vector<Polygon45WithHoles> polys;
Chris@16 2023 std::vector<Vertex45> data;
Chris@16 2024 // result == 0 8 -1 1
Chris@16 2025 data.push_back(Vertex45(Point(0, 8), -1, 1));
Chris@16 2026 // result == 0 8 1 -1
Chris@16 2027 data.push_back(Vertex45(Point(0, 8), 1, -1));
Chris@16 2028 // result == 4 0 1 1
Chris@16 2029 data.push_back(Vertex45(Point(4, 0), 1, 1));
Chris@16 2030 // result == 4 0 2 1
Chris@16 2031 data.push_back(Vertex45(Point(4, 0), 2, 1));
Chris@16 2032 // result == 4 4 2 -1
Chris@16 2033 data.push_back(Vertex45(Point(4, 4), 2, -1));
Chris@16 2034 // result == 4 4 -1 -1
Chris@16 2035 data.push_back(Vertex45(Point(4, 4), -1, -1));
Chris@16 2036 // result == 4 12 1 1
Chris@16 2037 data.push_back(Vertex45(Point(4, 12), 1, 1));
Chris@16 2038 // result == 4 12 2 1
Chris@16 2039 data.push_back(Vertex45(Point(4, 12), 2, 1));
Chris@16 2040 // result == 4 16 2 -1
Chris@16 2041 data.push_back(Vertex45(Point(4, 16), 2, 1));
Chris@16 2042 // result == 4 16 -1 -1
Chris@16 2043 data.push_back(Vertex45(Point(4, 16), -1, -1));
Chris@16 2044 // result == 6 2 1 -1
Chris@16 2045 data.push_back(Vertex45(Point(6, 2), 1, -1));
Chris@16 2046 // result == 6 14 -1 1
Chris@16 2047 data.push_back(Vertex45(Point(6, 14), -1, 1));
Chris@16 2048 // result == 6 2 -1 1
Chris@16 2049 data.push_back(Vertex45(Point(6, 2), -1, 1));
Chris@16 2050 // result == 6 14 1 -1
Chris@16 2051 data.push_back(Vertex45(Point(6, 14), 1, -1));
Chris@16 2052 // result == 8 0 -1 -1
Chris@16 2053 data.push_back(Vertex45(Point(8, 0), -1, -1));
Chris@16 2054 // result == 8 0 2 -1
Chris@16 2055 data.push_back(Vertex45(Point(8, 0), 2, -1));
Chris@16 2056 // result == 8 4 2 1
Chris@16 2057 data.push_back(Vertex45(Point(8, 4), 2, 1));
Chris@16 2058 // result == 8 4 1 1
Chris@16 2059 data.push_back(Vertex45(Point(8, 4), 1, 1));
Chris@16 2060 // result == 8 12 -1 -1
Chris@16 2061 data.push_back(Vertex45(Point(8, 12), -1, -1));
Chris@16 2062 // result == 8 12 2 -1
Chris@16 2063 data.push_back(Vertex45(Point(8, 12), 2, -1));
Chris@16 2064 // result == 8 16 2 1
Chris@16 2065 data.push_back(Vertex45(Point(8, 16), 2, 1));
Chris@16 2066 // result == 8 16 1 1
Chris@16 2067 data.push_back(Vertex45(Point(8, 16), 1, 1));
Chris@16 2068 // result == 12 8 1 -1
Chris@16 2069 data.push_back(Vertex45(Point(12, 8), 1, -1));
Chris@16 2070 // result == 12 8 -1 1
Chris@16 2071 data.push_back(Vertex45(Point(12, 8), -1, 1));
Chris@16 2072
Chris@16 2073 data.push_back(Vertex45(Point(6, 4), 1, -1));
Chris@16 2074 data.push_back(Vertex45(Point(6, 4), 2, -1));
Chris@16 2075 data.push_back(Vertex45(Point(6, 12), -1, 1));
Chris@16 2076 data.push_back(Vertex45(Point(6, 12), 2, 1));
Chris@16 2077 data.push_back(Vertex45(Point(10, 8), -1, -1));
Chris@16 2078 data.push_back(Vertex45(Point(10, 8), 1, 1));
Chris@16 2079
Chris@16 2080 polygon_sort(data.begin(), data.end());
Chris@16 2081 pf.scan(polys, data.begin(), data.end());
Chris@16 2082 stdcout << "result size: " << polys.size() << "\n";
Chris@16 2083 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 2084 stdcout << polys[i] << "\n";
Chris@16 2085 }
Chris@16 2086 stdcout << "done testing polygon tiling\n";
Chris@16 2087 return true;
Chris@16 2088 }
Chris@16 2089
Chris@16 2090 template <typename stream_type>
Chris@16 2091 static inline bool testPolygon45Tiling(stream_type& stdcout) {
Chris@16 2092 stdcout << "testing polygon tiling\n";
Chris@16 2093 Polygon45Tiling pf;
Chris@16 2094 std::vector<Polygon45WithHoles> polys;
Chris@16 2095 std::vector<Vertex45> data;
Chris@16 2096
Chris@16 2097 data.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 2098 data.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 2099 data.push_back(Vertex45(Point(0, 100), 2, -1));
Chris@16 2100 data.push_back(Vertex45(Point(0, 100), 0, -1));
Chris@16 2101 data.push_back(Vertex45(Point(100, 0), 0, -1));
Chris@16 2102 data.push_back(Vertex45(Point(100, 0), 2, -1));
Chris@16 2103 data.push_back(Vertex45(Point(100, 100), 2, 1));
Chris@16 2104 data.push_back(Vertex45(Point(100, 100), 0, 1));
Chris@16 2105
Chris@16 2106 data.push_back(Vertex45(Point(2, 2), 0, -1));
Chris@16 2107 data.push_back(Vertex45(Point(2, 2), 2, -1));
Chris@16 2108 data.push_back(Vertex45(Point(2, 10), 2, 1));
Chris@16 2109 data.push_back(Vertex45(Point(2, 10), 0, 1));
Chris@16 2110 data.push_back(Vertex45(Point(10, 2), 0, 1));
Chris@16 2111 data.push_back(Vertex45(Point(10, 2), 2, 1));
Chris@16 2112 data.push_back(Vertex45(Point(10, 10), 2, -1));
Chris@16 2113 data.push_back(Vertex45(Point(10, 10), 0, -1));
Chris@16 2114
Chris@16 2115 data.push_back(Vertex45(Point(2, 12), 0, -1));
Chris@16 2116 data.push_back(Vertex45(Point(2, 12), 2, -1));
Chris@16 2117 data.push_back(Vertex45(Point(2, 22), 2, 1));
Chris@16 2118 data.push_back(Vertex45(Point(2, 22), 0, 1));
Chris@16 2119 data.push_back(Vertex45(Point(10, 12), 0, 1));
Chris@16 2120 data.push_back(Vertex45(Point(10, 12), 2, 1));
Chris@16 2121 data.push_back(Vertex45(Point(10, 22), 2, -1));
Chris@16 2122 data.push_back(Vertex45(Point(10, 22), 0, -1));
Chris@16 2123
Chris@16 2124 polygon_sort(data.begin(), data.end());
Chris@16 2125 pf.scan(polys, data.begin(), data.end());
Chris@16 2126 stdcout << "result size: " << polys.size() << "\n";
Chris@16 2127 for(std::size_t i = 0; i < polys.size(); ++i) {
Chris@16 2128 stdcout << polys[i] << "\n";
Chris@16 2129 }
Chris@16 2130 stdcout << "done testing polygon tiling\n";
Chris@16 2131 return true;
Chris@16 2132 }
Chris@16 2133 };
Chris@16 2134
Chris@16 2135 template <typename Unit>
Chris@16 2136 class PolyLine45HoleData {
Chris@16 2137 public:
Chris@16 2138 typedef typename polygon_45_formation<Unit>::ActiveTail45 ActiveTail45;
Chris@16 2139 typedef typename ActiveTail45::iterator iterator;
Chris@16 2140
Chris@16 2141 typedef polygon_45_concept geometry_type;
Chris@16 2142 typedef Unit coordinate_type;
Chris@16 2143 typedef point_data<Unit> Point;
Chris@16 2144 typedef Point point_type;
Chris@16 2145 // typedef iterator_points_to_compact<iterator, Point> compact_iterator_type;
Chris@16 2146 typedef iterator iterator_type;
Chris@16 2147 typedef typename coordinate_traits<Unit>::area_type area_type;
Chris@16 2148
Chris@16 2149 inline PolyLine45HoleData() : p_(0) {}
Chris@16 2150 inline PolyLine45HoleData(ActiveTail45* p) : p_(p) {}
Chris@16 2151 //use default copy and assign
Chris@16 2152 inline iterator begin() const { return p_->getTail()->begin(); }
Chris@16 2153 inline iterator end() const { return p_->getTail()->end(); }
Chris@16 2154 inline std::size_t size() const { return 0; }
Chris@16 2155 template<class iT>
Chris@16 2156 inline PolyLine45HoleData& set(iT inputBegin, iT inputEnd) {
Chris@16 2157 return *this;
Chris@16 2158 }
Chris@16 2159 private:
Chris@16 2160 ActiveTail45* p_;
Chris@16 2161 };
Chris@16 2162
Chris@16 2163 template <typename Unit>
Chris@16 2164 class PolyLine45PolygonData {
Chris@16 2165 public:
Chris@16 2166 typedef typename polygon_45_formation<Unit>::ActiveTail45 ActiveTail45;
Chris@16 2167 typedef typename ActiveTail45::iterator iterator;
Chris@16 2168 typedef PolyLine45HoleData<Unit> holeType;
Chris@16 2169
Chris@16 2170 typedef polygon_45_with_holes_concept geometry_type;
Chris@16 2171 typedef Unit coordinate_type;
Chris@16 2172 typedef point_data<Unit> Point;
Chris@16 2173 typedef Point point_type;
Chris@16 2174 // typedef iterator_points_to_compact<iterator, Point> compact_iterator_type;
Chris@16 2175 typedef iterator iterator_type;
Chris@16 2176 typedef holeType hole_type;
Chris@16 2177 typedef typename coordinate_traits<Unit>::area_type area_type;
Chris@16 2178 class iteratorHoles {
Chris@16 2179 private:
Chris@16 2180 typename ActiveTail45::iteratorHoles itr_;
Chris@16 2181 public:
Chris@16 2182 typedef PolyLine45HoleData<Unit> holeType;
Chris@16 2183 typedef holeType value_type;
Chris@16 2184 typedef std::forward_iterator_tag iterator_category;
Chris@16 2185 typedef std::ptrdiff_t difference_type;
Chris@16 2186 typedef const value_type* pointer; //immutable
Chris@16 2187 typedef const value_type& reference; //immutable
Chris@16 2188 inline iteratorHoles() : itr_() {}
Chris@16 2189 inline iteratorHoles(typename ActiveTail45::iteratorHoles itr) : itr_(itr) {}
Chris@16 2190 inline iteratorHoles(const iteratorHoles& that) : itr_(that.itr_) {}
Chris@16 2191 inline iteratorHoles& operator=(const iteratorHoles& that) {
Chris@16 2192 itr_ = that.itr_;
Chris@16 2193 return *this;
Chris@16 2194 }
Chris@16 2195 inline bool operator==(const iteratorHoles& that) { return itr_ == that.itr_; }
Chris@16 2196 inline bool operator!=(const iteratorHoles& that) { return itr_ != that.itr_; }
Chris@16 2197 inline iteratorHoles& operator++() {
Chris@16 2198 ++itr_;
Chris@16 2199 return *this;
Chris@16 2200 }
Chris@16 2201 inline const iteratorHoles operator++(int) {
Chris@16 2202 iteratorHoles tmp = *this;
Chris@16 2203 ++(*this);
Chris@16 2204 return tmp;
Chris@16 2205 }
Chris@16 2206 inline holeType operator*() {
Chris@16 2207 return *itr_;
Chris@16 2208 }
Chris@16 2209 };
Chris@16 2210 typedef iteratorHoles iterator_holes_type;
Chris@16 2211
Chris@16 2212
Chris@16 2213 inline PolyLine45PolygonData() : p_(0) {}
Chris@16 2214 inline PolyLine45PolygonData(ActiveTail45* p) : p_(p) {}
Chris@16 2215 //use default copy and assign
Chris@16 2216 inline iterator begin() const { return p_->getTail()->begin(); }
Chris@16 2217 inline iterator end() const { return p_->getTail()->end(); }
Chris@16 2218 inline iteratorHoles begin_holes() const { return iteratorHoles(p_->getHoles().begin()); }
Chris@16 2219 inline iteratorHoles end_holes() const { return iteratorHoles(p_->getHoles().end()); }
Chris@16 2220 inline ActiveTail45* yield() { return p_; }
Chris@16 2221 //stub out these four required functions that will not be used but are needed for the interface
Chris@16 2222 inline std::size_t size_holes() const { return 0; }
Chris@16 2223 inline std::size_t size() const { return 0; }
Chris@16 2224 template<class iT>
Chris@16 2225 inline PolyLine45PolygonData& set(iT inputBegin, iT inputEnd) {
Chris@16 2226 return *this;
Chris@16 2227 }
Chris@16 2228
Chris@16 2229 // initialize a polygon from x,y values, it is assumed that the first is an x
Chris@16 2230 // and that the input is a well behaved polygon
Chris@16 2231 template<class iT>
Chris@16 2232 inline PolyLine45PolygonData& set_holes(iT inputBegin, iT inputEnd) {
Chris@16 2233 return *this;
Chris@16 2234 }
Chris@16 2235 private:
Chris@16 2236 ActiveTail45* p_;
Chris@16 2237 };
Chris@16 2238
Chris@16 2239 template <typename T>
Chris@16 2240 struct PolyLineByConcept<T, polygon_45_with_holes_concept> { typedef PolyLine45PolygonData<T> type; };
Chris@16 2241 template <typename T>
Chris@16 2242 struct PolyLineByConcept<T, polygon_with_holes_concept> { typedef PolyLine45PolygonData<T> type; };
Chris@16 2243 template <typename T>
Chris@16 2244 struct PolyLineByConcept<T, polygon_45_concept> { typedef PolyLine45HoleData<T> type; };
Chris@16 2245 template <typename T>
Chris@16 2246 struct PolyLineByConcept<T, polygon_concept> { typedef PolyLine45HoleData<T> type; };
Chris@16 2247
Chris@16 2248 template <typename T>
Chris@16 2249 struct geometry_concept<PolyLine45PolygonData<T> > { typedef polygon_45_with_holes_concept type; };
Chris@16 2250 template <typename T>
Chris@16 2251 struct geometry_concept<PolyLine45HoleData<T> > { typedef polygon_45_concept type; };
Chris@16 2252
Chris@16 2253 }
Chris@16 2254 }
Chris@16 2255 #endif