annotate DEPENDENCIES/generic/include/boost/polygon/detail/boolean_op_45.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_BOOLEAN_OP_45_HPP
Chris@16 9 #define BOOST_POLYGON_BOOLEAN_OP_45_HPP
Chris@16 10 namespace boost { namespace polygon{
Chris@16 11
Chris@16 12 template <typename Unit>
Chris@16 13 struct boolean_op_45 {
Chris@16 14 typedef point_data<Unit> Point;
Chris@16 15 typedef typename coordinate_traits<Unit>::manhattan_area_type LongUnit;
Chris@16 16
Chris@16 17 class Count2 {
Chris@16 18 public:
Chris@16 19 inline Count2()
Chris@16 20 #ifndef BOOST_POLYGON_MSVC
Chris@16 21 : counts()
Chris@16 22 #endif
Chris@16 23 { counts[0] = counts[1] = 0; }
Chris@16 24 //inline Count2(int count) { counts[0] = counts[1] = count; }
Chris@16 25 inline Count2(int count1, int count2)
Chris@16 26 #ifndef BOOST_POLYGON_MSVC
Chris@16 27 : counts()
Chris@16 28 #endif
Chris@16 29 { counts[0] = count1; counts[1] = count2; }
Chris@16 30 inline Count2(const Count2& count)
Chris@16 31 #ifndef BOOST_POLYGON_MSVC
Chris@16 32 : counts()
Chris@16 33 #endif
Chris@16 34 { counts[0] = count.counts[0]; counts[1] = count.counts[1]; }
Chris@16 35 inline bool operator==(const Count2& count) const { return counts[0] == count.counts[0] && counts[1] == count.counts[1]; }
Chris@16 36 inline bool operator!=(const Count2& count) const { return !((*this) == count); }
Chris@16 37 inline Count2& operator=(int count) { counts[0] = counts[1] = count; return *this; }
Chris@16 38 inline Count2& operator=(const Count2& count) { counts[0] = count.counts[0]; counts[1] = count.counts[1]; return *this; }
Chris@16 39 inline int& operator[](bool index) { return counts[index]; }
Chris@16 40 inline int operator[](bool index) const {return counts[index]; }
Chris@16 41 inline Count2& operator+=(const Count2& count){
Chris@16 42 counts[0] += count[0];
Chris@16 43 counts[1] += count[1];
Chris@16 44 return *this;
Chris@16 45 }
Chris@16 46 inline Count2& operator-=(const Count2& count){
Chris@16 47 counts[0] -= count[0];
Chris@16 48 counts[1] -= count[1];
Chris@16 49 return *this;
Chris@16 50 }
Chris@16 51 inline Count2 operator+(const Count2& count) const {
Chris@16 52 return Count2(*this)+=count;
Chris@16 53 }
Chris@16 54 inline Count2 operator-(const Count2& count) const {
Chris@16 55 return Count2(*this)-=count;
Chris@16 56 }
Chris@16 57 inline Count2 invert() const {
Chris@16 58 return Count2(-counts[0], -counts[1]);
Chris@16 59 }
Chris@16 60 private:
Chris@16 61 int counts[2];
Chris@16 62 };
Chris@16 63
Chris@16 64 class Count1 {
Chris@16 65 public:
Chris@16 66 inline Count1() : count_(0) { }
Chris@16 67 inline Count1(int count) : count_(count) { }
Chris@16 68 inline Count1(const Count1& count) : count_(count.count_) { }
Chris@16 69 inline bool operator==(const Count1& count) const { return count_ == count.count_; }
Chris@16 70 inline bool operator!=(const Count1& count) const { return !((*this) == count); }
Chris@16 71 inline Count1& operator=(int count) { count_ = count; return *this; }
Chris@16 72 inline Count1& operator=(const Count1& count) { count_ = count.count_; return *this; }
Chris@16 73 inline Count1& operator+=(const Count1& count){
Chris@16 74 count_ += count.count_;
Chris@16 75 return *this;
Chris@16 76 }
Chris@16 77 inline Count1& operator-=(const Count1& count){
Chris@16 78 count_ -= count.count_;
Chris@16 79 return *this;
Chris@16 80 }
Chris@16 81 inline Count1 operator+(const Count1& count) const {
Chris@16 82 return Count1(*this)+=count;
Chris@16 83 }
Chris@16 84 inline Count1 operator-(const Count1& count) const {
Chris@16 85 return Count1(*this)-=count;
Chris@16 86 }
Chris@16 87 inline Count1 invert() const {
Chris@16 88 return Count1(-count_);
Chris@16 89 }
Chris@16 90 int count_;
Chris@16 91 };
Chris@16 92
Chris@16 93 // inline std::ostream& operator<< (std::ostream& o, const Count2& c) {
Chris@16 94 // o << c[0] << " " << c[1];
Chris@16 95 // return o;
Chris@16 96 // }
Chris@16 97
Chris@16 98 template <typename CountType>
Chris@16 99 class Scan45ElementT {
Chris@16 100 public:
Chris@16 101 Unit x;
Chris@16 102 Unit y;
Chris@16 103 int rise; //-1, 0, +1
Chris@16 104 mutable CountType count;
Chris@16 105 inline Scan45ElementT() : x(), y(), rise(), count() {}
Chris@16 106 inline Scan45ElementT(Unit xIn, Unit yIn, int riseIn, CountType countIn = CountType()) :
Chris@16 107 x(xIn), y(yIn), rise(riseIn), count(countIn) {}
Chris@16 108 inline Scan45ElementT(const Scan45ElementT& that) :
Chris@16 109 x(that.x), y(that.y), rise(that.rise), count(that.count) {}
Chris@16 110 inline Scan45ElementT& operator=(const Scan45ElementT& that) {
Chris@16 111 x = that.x; y = that.y; rise = that.rise; count = that.count;
Chris@16 112 return *this;
Chris@16 113 }
Chris@16 114 inline Unit evalAtX(Unit xIn) const {
Chris@16 115 return y + rise * (xIn - x);
Chris@16 116 }
Chris@16 117
Chris@16 118 inline bool cross(Point& crossPoint, const Scan45ElementT& edge, Unit currentX) const {
Chris@16 119 Unit y1 = evalAtX(currentX);
Chris@16 120 Unit y2 = edge.evalAtX(currentX);
Chris@16 121 int rise1 = rise;
Chris@16 122 int rise2 = edge.rise;
Chris@16 123 if(rise > edge.rise){
Chris@16 124 if(y1 > y2) return false;
Chris@16 125 } else if(rise < edge.rise){
Chris@16 126 if(y2 > y1) return false;
Chris@16 127 std::swap(y1, y2);
Chris@16 128 std::swap(rise1, rise2);
Chris@16 129 } else { return false; }
Chris@16 130 if(rise1 == 1) {
Chris@16 131 if(rise2 == 0) {
Chris@16 132 crossPoint = Point(currentX + y2 - y1, y2);
Chris@16 133 } else {
Chris@16 134 //rise2 == -1
Chris@16 135 Unit delta = (y2 - y1)/2;
Chris@16 136 crossPoint = Point(currentX + delta, y1 + delta);
Chris@16 137 }
Chris@16 138 } else {
Chris@16 139 //rise1 == 0 and rise2 == -1
Chris@16 140 crossPoint = Point(currentX + y2 - y1, y1);
Chris@16 141 }
Chris@16 142 return true;
Chris@16 143 }
Chris@16 144 };
Chris@16 145
Chris@16 146 typedef Scan45ElementT<Count2> Scan45Element;
Chris@16 147
Chris@16 148 // inline std::ostream& operator<< (std::ostream& o, const Scan45Element& c) {
Chris@16 149 // o << c.x << " " << c.y << " " << c.rise << " " << c.count;
Chris@16 150 // return o;
Chris@16 151 // }
Chris@16 152
Chris@16 153 class lessScan45ElementRise : public std::binary_function<Scan45Element, Scan45Element, bool> {
Chris@16 154 public:
Chris@16 155 inline lessScan45ElementRise() {} //default constructor is only constructor
Chris@16 156 inline bool operator () (Scan45Element elm1, Scan45Element elm2) const {
Chris@16 157 return elm1.rise < elm2.rise;
Chris@16 158 }
Chris@16 159 };
Chris@16 160
Chris@16 161 template <typename CountType>
Chris@16 162 class lessScan45Element {
Chris@16 163 private:
Chris@16 164 Unit *x_; //x value at which to apply comparison
Chris@16 165 int *justBefore_;
Chris@16 166 public:
Chris@16 167 inline lessScan45Element() : x_(0), justBefore_(0) {}
Chris@16 168 inline lessScan45Element(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {}
Chris@16 169 inline lessScan45Element(const lessScan45Element& that) : x_(that.x_), justBefore_(that.justBefore_) {}
Chris@16 170 inline lessScan45Element& operator=(const lessScan45Element& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; }
Chris@16 171 inline bool operator () (const Scan45ElementT<CountType>& elm1,
Chris@16 172 const Scan45ElementT<CountType>& elm2) const {
Chris@16 173 Unit y1 = elm1.evalAtX(*x_);
Chris@16 174 Unit y2 = elm2.evalAtX(*x_);
Chris@16 175 if(y1 < y2) return true;
Chris@16 176 if(y1 == y2) {
Chris@16 177 //if justBefore is true we invert the result of the comparison of slopes
Chris@16 178 if(*justBefore_) {
Chris@16 179 return elm1.rise > elm2.rise;
Chris@16 180 } else {
Chris@16 181 return elm1.rise < elm2.rise;
Chris@16 182 }
Chris@16 183 }
Chris@16 184 return false;
Chris@16 185 }
Chris@16 186 };
Chris@16 187
Chris@16 188 template <typename CountType>
Chris@16 189 class Scan45CountT {
Chris@16 190 public:
Chris@16 191 inline Scan45CountT() : counts() {} //counts[0] = counts[1] = counts[2] = counts[3] = 0; }
Chris@16 192 inline Scan45CountT(CountType count) : counts() { counts[0] = counts[1] = counts[2] = counts[3] = count; }
Chris@16 193 inline Scan45CountT(const CountType& count1, const CountType& count2, const CountType& count3,
Chris@16 194 const CountType& count4) : counts() {
Chris@16 195 counts[0] = count1;
Chris@16 196 counts[1] = count2;
Chris@16 197 counts[2] = count3;
Chris@16 198 counts[3] = count4;
Chris@16 199 }
Chris@16 200 inline Scan45CountT(const Scan45CountT& count) : counts() {
Chris@16 201 (*this) = count;
Chris@16 202 }
Chris@16 203 inline bool operator==(const Scan45CountT& count) const {
Chris@16 204 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 205 if(counts[i] != count.counts[i]) return false;
Chris@16 206 }
Chris@16 207 return true;
Chris@16 208 }
Chris@16 209 inline bool operator!=(const Scan45CountT& count) const { return !((*this) == count); }
Chris@16 210 inline Scan45CountT& operator=(CountType count) {
Chris@16 211 counts[0] = counts[1] = counts[2] = counts[3] = count; return *this; }
Chris@16 212 inline Scan45CountT& operator=(const Scan45CountT& count) {
Chris@16 213 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 214 counts[i] = count.counts[i];
Chris@16 215 }
Chris@16 216 return *this;
Chris@16 217 }
Chris@16 218 inline CountType& operator[](int index) { return counts[index]; }
Chris@16 219 inline CountType operator[](int index) const {return counts[index]; }
Chris@16 220 inline Scan45CountT& operator+=(const Scan45CountT& count){
Chris@16 221 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 222 counts[i] += count.counts[i];
Chris@16 223 }
Chris@16 224 return *this;
Chris@16 225 }
Chris@16 226 inline Scan45CountT& operator-=(const Scan45CountT& count){
Chris@16 227 for(unsigned int i = 0; i < 4; ++i) {
Chris@16 228 counts[i] -= count.counts[i];
Chris@16 229 }
Chris@16 230 return *this;
Chris@16 231 }
Chris@16 232 inline Scan45CountT operator+(const Scan45CountT& count) const {
Chris@16 233 return Scan45CountT(*this)+=count;
Chris@16 234 }
Chris@16 235 inline Scan45CountT operator-(const Scan45CountT& count) const {
Chris@16 236 return Scan45CountT(*this)-=count;
Chris@16 237 }
Chris@16 238 inline Scan45CountT invert() const {
Chris@16 239 return Scan45CountT(CountType())-=(*this);
Chris@16 240 }
Chris@16 241 inline Scan45CountT& operator+=(const Scan45ElementT<CountType>& element){
Chris@16 242 counts[element.rise+1] += element.count; return *this;
Chris@16 243 }
Chris@16 244 private:
Chris@16 245 CountType counts[4];
Chris@16 246 };
Chris@16 247
Chris@16 248 typedef Scan45CountT<Count2> Scan45Count;
Chris@16 249
Chris@16 250 // inline std::ostream& operator<< (std::ostream& o, const Scan45Count& c) {
Chris@16 251 // o << c[0] << ", " << c[1] << ", ";
Chris@16 252 // o << c[2] << ", " << c[3];
Chris@16 253 // return o;
Chris@16 254 // }
Chris@16 255
Chris@16 256
Chris@16 257 // inline std::ostream& operator<< (std::ostream& o, const Scan45Vertex& c) {
Chris@16 258 // o << c.first << ": " << c.second;
Chris@16 259 // return o;
Chris@16 260 // }
Chris@16 261
Chris@16 262
Chris@16 263 //vetex45 is sortable
Chris@16 264 template <typename ct>
Chris@16 265 class Vertex45T {
Chris@16 266 public:
Chris@16 267 Point pt;
Chris@16 268 int rise; // 1, 0 or -1
Chris@16 269 ct count; //dxdydTheta
Chris@16 270 inline Vertex45T() : pt(), rise(), count() {}
Chris@16 271 inline Vertex45T(const Point& point, int riseIn, ct countIn) : pt(point), rise(riseIn), count(countIn) {}
Chris@16 272 inline Vertex45T(const Vertex45T& vertex) : pt(vertex.pt), rise(vertex.rise), count(vertex.count) {}
Chris@16 273 inline Vertex45T& operator=(const Vertex45T& vertex){
Chris@16 274 pt = vertex.pt; rise = vertex.rise; count = vertex.count; return *this; }
Chris@16 275 inline Vertex45T(const std::pair<Point, Point>& vertex) : pt(), rise(), count() {}
Chris@16 276 inline Vertex45T& operator=(const std::pair<Point, Point>& vertex){ return *this; }
Chris@16 277 inline bool operator==(const Vertex45T& vertex) const {
Chris@16 278 return pt == vertex.pt && rise == vertex.rise && count == vertex.count; }
Chris@16 279 inline bool operator!=(const Vertex45T& vertex) const { return !((*this) == vertex); }
Chris@16 280 inline bool operator==(const std::pair<Point, Point>& vertex) const { return false; }
Chris@16 281 inline bool operator!=(const std::pair<Point, Point>& vertex) const { return !((*this) == vertex); }
Chris@16 282 inline bool operator<(const Vertex45T& vertex) const {
Chris@16 283 if(pt.x() < vertex.pt.x()) return true;
Chris@16 284 if(pt.x() == vertex.pt.x()) {
Chris@16 285 if(pt.y() < vertex.pt.y()) return true;
Chris@16 286 if(pt.y() == vertex.pt.y()) { return rise < vertex.rise; }
Chris@16 287 }
Chris@16 288 return false;
Chris@16 289 }
Chris@16 290 inline bool operator>(const Vertex45T& vertex) const { return vertex < (*this); }
Chris@16 291 inline bool operator<=(const Vertex45T& vertex) const { return !((*this) > vertex); }
Chris@16 292 inline bool operator>=(const Vertex45T& vertex) const { return !((*this) < vertex); }
Chris@16 293 inline Unit evalAtX(Unit xIn) const { return pt.y() + rise * (xIn - pt.x()); }
Chris@16 294 };
Chris@16 295
Chris@16 296 typedef Vertex45T<int> Vertex45;
Chris@16 297
Chris@16 298 // inline std::ostream& operator<< (std::ostream& o, const Vertex45& c) {
Chris@16 299 // o << c.pt << " " << c.rise << " " << c.count;
Chris@16 300 // return o;
Chris@16 301 // }
Chris@16 302
Chris@16 303 //when scanning Vertex45 for polygon formation we need a scanline comparator functor
Chris@16 304 class lessVertex45 {
Chris@16 305 private:
Chris@16 306 Unit *x_; //x value at which to apply comparison
Chris@16 307 int *justBefore_;
Chris@16 308 public:
Chris@16 309 inline lessVertex45() : x_(0), justBefore_() {}
Chris@16 310
Chris@16 311 inline lessVertex45(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {}
Chris@16 312
Chris@16 313 inline lessVertex45(const lessVertex45& that) : x_(that.x_), justBefore_(that.justBefore_) {}
Chris@16 314
Chris@16 315 inline lessVertex45& operator=(const lessVertex45& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; }
Chris@16 316
Chris@16 317 template <typename ct>
Chris@16 318 inline bool operator () (const Vertex45T<ct>& elm1, const Vertex45T<ct>& elm2) const {
Chris@16 319 Unit y1 = elm1.evalAtX(*x_);
Chris@16 320 Unit y2 = elm2.evalAtX(*x_);
Chris@16 321 if(y1 < y2) return true;
Chris@16 322 if(y1 == y2) {
Chris@16 323 //if justBefore is true we invert the result of the comparison of slopes
Chris@16 324 if(*justBefore_) {
Chris@16 325 return elm1.rise > elm2.rise;
Chris@16 326 } else {
Chris@16 327 return elm1.rise < elm2.rise;
Chris@16 328 }
Chris@16 329 }
Chris@16 330 return false;
Chris@16 331 }
Chris@16 332 };
Chris@16 333
Chris@16 334 // 0 right to left
Chris@16 335 // 1 upper right to lower left
Chris@16 336 // 2 high to low
Chris@16 337 // 3 upper left to lower right
Chris@16 338 // 4 left to right
Chris@16 339 // 5 lower left to upper right
Chris@16 340 // 6 low to high
Chris@16 341 // 7 lower right to upper left
Chris@16 342 static inline int classifyEdge45(const Point& prevPt, const Point& nextPt) {
Chris@16 343 if(prevPt.x() == nextPt.x()) {
Chris@16 344 //2 or 6
Chris@16 345 return predicated_value(prevPt.y() < nextPt.y(), 6, 2);
Chris@16 346 }
Chris@16 347 if(prevPt.y() == nextPt.y()) {
Chris@16 348 //0 or 4
Chris@16 349 return predicated_value(prevPt.x() < nextPt.x(), 4, 0);
Chris@16 350 }
Chris@16 351 if(prevPt.x() < nextPt.x()) {
Chris@16 352 //3 or 5
Chris@16 353 return predicated_value(prevPt.y() < nextPt.y(), 5, 3);
Chris@16 354 }
Chris@16 355 //prevPt.x() > nextPt.y()
Chris@16 356 //1 or 7
Chris@16 357 return predicated_value(prevPt.y() < nextPt.y(), 7, 1);
Chris@16 358 }
Chris@16 359
Chris@16 360 template <int op, typename CountType>
Chris@16 361 static int applyLogic(CountType count1, CountType count2){
Chris@16 362 bool l1 = applyLogic<op>(count1);
Chris@16 363 bool l2 = applyLogic<op>(count2);
Chris@16 364 if(l1 && !l2)
Chris@16 365 return -1; //was true before and became false like a trailing edge
Chris@16 366 if(!l1 && l2)
Chris@16 367 return 1; //was false before and became true like a leading edge
Chris@16 368 return 0; //no change in logic between the two counts
Chris@16 369 }
Chris@16 370 template <int op>
Chris@16 371 static bool applyLogic(Count2 count) {
Chris@16 372 #ifdef BOOST_POLYGON_MSVC
Chris@16 373 #pragma warning (push)
Chris@16 374 #pragma warning (disable: 4127)
Chris@16 375 #endif
Chris@16 376 if(op == 0) { //apply or
Chris@16 377 return count[0] > 0 || count[1] > 0;
Chris@16 378 } else if(op == 1) { //apply and
Chris@16 379 return count[0] > 0 && count[1] > 0;
Chris@16 380 } else if(op == 2) { //apply not
Chris@16 381 return count[0] > 0 && !(count[1] > 0);
Chris@16 382 } else if(op == 3) { //apply xor
Chris@16 383 return (count[0] > 0) ^ (count[1] > 0);
Chris@16 384 } else
Chris@16 385 return false;
Chris@16 386 #ifdef BOOST_POLYGON_MSVC
Chris@16 387 #pragma warning (pop)
Chris@16 388 #endif
Chris@16 389 }
Chris@16 390
Chris@16 391 template <int op>
Chris@16 392 struct boolean_op_45_output_functor {
Chris@16 393 template <typename cT>
Chris@16 394 void operator()(cT& output, const Count2& count1, const Count2& count2,
Chris@16 395 const Point& pt, int rise, direction_1d end) {
Chris@16 396 int edgeType = applyLogic<op>(count1, count2);
Chris@16 397 if(edgeType) {
Chris@16 398 int multiplier = end == LOW ? -1 : 1;
Chris@16 399 //std::cout << "cross logic: " << edgeType << "\n";
Chris@16 400 output.insert(output.end(), Vertex45(pt, rise, edgeType * multiplier));
Chris@16 401 //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n";
Chris@16 402 }
Chris@16 403 }
Chris@16 404 };
Chris@16 405
Chris@16 406 template <int op>
Chris@16 407 static bool applyLogic(Count1 count) {
Chris@16 408 #ifdef BOOST_POLYGON_MSVC
Chris@16 409 #pragma warning (push)
Chris@16 410 #pragma warning (disable: 4127)
Chris@16 411 #endif
Chris@16 412 if(op == 0) { //apply or
Chris@16 413 return count.count_ > 0;
Chris@16 414 } else if(op == 1) { //apply and
Chris@16 415 return count.count_ > 1;
Chris@16 416 } else if(op == 3) { //apply xor
Chris@16 417 return (count.count_ % 2) != 0;
Chris@16 418 } else
Chris@16 419 return false;
Chris@16 420 #ifdef BOOST_POLYGON_MSVC
Chris@16 421 #pragma warning (pop)
Chris@16 422 #endif
Chris@16 423 }
Chris@16 424
Chris@16 425 template <int op>
Chris@16 426 struct unary_op_45_output_functor {
Chris@16 427 template <typename cT>
Chris@16 428 void operator()(cT& output, const Count1& count1, const Count1& count2,
Chris@16 429 const Point& pt, int rise, direction_1d end) {
Chris@16 430 int edgeType = applyLogic<op>(count1, count2);
Chris@16 431 if(edgeType) {
Chris@16 432 int multiplier = end == LOW ? -1 : 1;
Chris@16 433 //std::cout << "cross logic: " << edgeType << "\n";
Chris@16 434 output.insert(output.end(), Vertex45(pt, rise, edgeType * multiplier));
Chris@16 435 //std::cout << "write out: " << crossPoint << " " << Point(eraseItrs[i]->x, eraseItrs[i]->y) << "\n";
Chris@16 436 }
Chris@16 437 }
Chris@16 438 };
Chris@16 439
Chris@16 440 class lessScan45Vertex {
Chris@16 441 public:
Chris@16 442 inline lessScan45Vertex() {} //default constructor is only constructor
Chris@16 443 template <typename Scan45Vertex>
Chris@16 444 inline bool operator () (const Scan45Vertex& v1, const Scan45Vertex& v2) const {
Chris@16 445 return (v1.first.x() < v2.first.x()) || (v1.first.x() == v2.first.x() && v1.first.y() < v2.first.y());
Chris@16 446 }
Chris@16 447 };
Chris@16 448 template <typename S45V>
Chris@16 449 static inline void sortScan45Vector(S45V& vec) {
Chris@16 450 polygon_sort(vec.begin(), vec.end(), lessScan45Vertex());
Chris@16 451 }
Chris@16 452
Chris@16 453 template <typename CountType, typename output_functor>
Chris@16 454 class Scan45 {
Chris@16 455 public:
Chris@16 456 typedef Scan45CountT<CountType> Scan45Count;
Chris@16 457 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 458
Chris@16 459 //index is the index into the vertex
Chris@16 460 static inline Scan45Element getElement(const Scan45Vertex& vertex, int index) {
Chris@16 461 return Scan45Element(vertex.first.x(), vertex.first.y(), index - 1, vertex.second[index]);
Chris@16 462 }
Chris@16 463
Chris@16 464 class lessScan45Point : public std::binary_function<Point, Point, bool> {
Chris@16 465 public:
Chris@16 466 inline lessScan45Point() {} //default constructor is only constructor
Chris@16 467 inline bool operator () (const Point& v1, const Point& v2) const {
Chris@16 468 return (v1.x() < v2.x()) || (v1.x() == v2.x() && v1.y() < v2.y());
Chris@16 469 }
Chris@16 470 };
Chris@16 471
Chris@16 472 typedef std::vector<Scan45Vertex> Scan45Vector;
Chris@16 473
Chris@16 474 //definitions
Chris@16 475 typedef std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> > Scan45Data;
Chris@16 476 typedef typename Scan45Data::iterator iterator;
Chris@16 477 typedef typename Scan45Data::const_iterator const_iterator;
Chris@16 478 typedef std::set<Point, lessScan45Point> CrossQueue;
Chris@16 479
Chris@16 480 //data
Chris@16 481 Scan45Data scanData_;
Chris@16 482 CrossQueue crossQueue_;
Chris@16 483 Scan45Vector crossVector_;
Chris@16 484 Unit x_;
Chris@16 485 int justBefore_;
Chris@16 486 public:
Chris@16 487 inline Scan45() : scanData_(), crossQueue_(), crossVector_(),
Chris@16 488 x_((std::numeric_limits<Unit>::min)()), justBefore_(false) {
Chris@16 489 lessScan45Element<CountType> lessElm(&x_, &justBefore_);
Chris@16 490 scanData_ = std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >(lessElm);
Chris@16 491 }
Chris@16 492 inline Scan45(const Scan45& that) : scanData_(), crossQueue_(), crossVector_(),
Chris@16 493 x_((std::numeric_limits<Unit>::min)()), justBefore_(false) {
Chris@16 494 (*this) = that; }
Chris@16 495 inline Scan45& operator=(const Scan45& that) {
Chris@16 496 x_ = that.x_;
Chris@16 497 justBefore_ = that.justBefore_;
Chris@16 498 crossQueue_ = that.crossQueue_;
Chris@16 499 crossVector_ = that.crossVector_;
Chris@16 500 lessScan45Element<CountType> lessElm(&x_, &justBefore_);
Chris@16 501 scanData_ = std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >(lessElm);
Chris@16 502 for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
Chris@16 503 scanData_.insert(scanData_.end(), *itr);
Chris@16 504 }
Chris@16 505 return *this;
Chris@16 506 }
Chris@16 507
Chris@16 508 //cT is an output container of Vertex45
Chris@16 509 //iT is an iterator over Scan45Vertex elements
Chris@16 510 template <class cT, class iT>
Chris@16 511 void scan(cT& output, iT inputBegin, iT inputEnd) {
Chris@16 512 //std::cout << "1\n";
Chris@16 513 while(inputBegin != inputEnd) {
Chris@16 514 //std::cout << "2\n";
Chris@16 515 //std::cout << "x_ = " << x_ << "\n";
Chris@16 516 //std::cout << "scan line size: " << scanData_.size() << "\n";
Chris@16 517 //for(iterator iter = scanData_.begin();
Chris@16 518 // iter != scanData_.end(); ++iter) {
Chris@16 519 // std::cout << "scan element\n";
Chris@16 520 // std::cout << *iter << " " << iter->evalAtX(x_) << "\n";
Chris@16 521 // }
Chris@16 522 // std::cout << "cross queue size: " << crossQueue_.size() << "\n";
Chris@16 523 // std::cout << "cross vector size: " << crossVector_.size() << "\n";
Chris@16 524 //for(CrossQueue::iterator cqitr = crossQueue_.begin(); cqitr != crossQueue_.end(); ++cqitr) {
Chris@16 525 // std::cout << *cqitr << " ";
Chris@16 526 //} std::cout << "\n";
Chris@16 527 Unit nextX = (*inputBegin).first.x();
Chris@16 528 if(!crossVector_.empty() && crossVector_[0].first.x() < nextX) nextX = crossVector_[0].first.x();
Chris@16 529 if(nextX != x_) {
Chris@16 530 //std::cout << "3\n";
Chris@16 531 //we need to move to the next scanline stop
Chris@16 532 //we need to process end events then cross events
Chris@16 533 //process end events
Chris@16 534 if(!crossQueue_.empty() &&
Chris@16 535 (*crossQueue_.begin()).x() < nextX) {
Chris@16 536 //std::cout << "4\n";
Chris@16 537 nextX = (std::min)(nextX, (*crossQueue_.begin()).x());
Chris@16 538 }
Chris@16 539 //std::cout << "6\n";
Chris@16 540 justBefore_ = true;
Chris@16 541 x_ = nextX;
Chris@16 542 advance_(output);
Chris@16 543 justBefore_ = false;
Chris@16 544 if(!crossVector_.empty() &&
Chris@16 545 nextX == (*inputBegin).first.x()) {
Chris@16 546 inputBegin = mergeCross_(inputBegin, inputEnd);
Chris@16 547 }
Chris@16 548 processEvent_(output, crossVector_.begin(), crossVector_.end());
Chris@16 549 crossVector_.clear();
Chris@16 550 } else {
Chris@16 551 //std::cout << "7\n";
Chris@16 552 //our scanline has progressed to the event that is next in the queue
Chris@16 553 inputBegin = processEvent_(output, inputBegin, inputEnd);
Chris@16 554 }
Chris@16 555 }
Chris@16 556 //std::cout << "done scanning\n";
Chris@16 557 }
Chris@16 558
Chris@16 559 private:
Chris@16 560 //functions
Chris@16 561
Chris@16 562 template <class cT>
Chris@16 563 inline void advance_(cT& output) {
Chris@16 564 //process all cross points on the cross queue at the current x_
Chris@16 565 //std::cout << "advance_\n";
Chris@16 566 std::vector<iterator> eraseVec;
Chris@16 567 while(!crossQueue_.empty() &&
Chris@16 568 (*crossQueue_.begin()).x() == x_){
Chris@16 569 //std::cout << "loop\n";
Chris@16 570 //pop point off the cross queue
Chris@16 571 Point crossPoint = *(crossQueue_.begin());
Chris@16 572 //std::cout << crossPoint << "\n";
Chris@16 573 //for(iterator iter = scanData_.begin();
Chris@16 574 // iter != scanData_.end(); ++iter) {
Chris@16 575 // std::cout << "scan element\n";
Chris@16 576 // std::cout << *iter << " " << iter->evalAtX(x_) << "\n";
Chris@16 577 //}
Chris@16 578 crossQueue_.erase(crossQueue_.begin());
Chris@16 579 Scan45Vertex vertex(crossPoint, Scan45Count());
Chris@16 580 iterator lowIter = lookUp_(vertex.first.y());
Chris@16 581 //std::cout << "searching at: " << vertex.first.y() << "\n";
Chris@16 582 //if(lowIter == scanData_.end()) std::cout << "could not find\n";
Chris@16 583 //else std::cout << "found: " << *lowIter << "\n";
Chris@16 584 if(lowIter == scanData_.end() ||
Chris@16 585 lowIter->evalAtX(x_) != vertex.first.y()) {
Chris@16 586 // std::cout << "skipping\n";
Chris@16 587 //there weren't any edges at this potential cross point
Chris@16 588 continue;
Chris@16 589 }
Chris@16 590 CountType countBelow;
Chris@16 591 iterator searchDownItr = lowIter;
Chris@16 592 while(searchDownItr != scanData_.begin()
Chris@16 593 && searchDownItr->evalAtX(x_) == vertex.first.y()) {
Chris@16 594 //get count from below
Chris@16 595 --searchDownItr;
Chris@16 596 countBelow = searchDownItr->count;
Chris@16 597 }
Chris@16 598 //std::cout << "Below Count: " << countBelow << "\n";
Chris@16 599 Scan45Count count(countBelow);
Chris@16 600 std::size_t numEdges = 0;
Chris@16 601 iterator eraseItrs[3];
Chris@16 602 while(lowIter != scanData_.end() &&
Chris@16 603 lowIter->evalAtX(x_) == vertex.first.y()) {
Chris@16 604 for(int index = lowIter->rise +1; index >= 0; --index)
Chris@16 605 count[index] = lowIter->count;
Chris@16 606 //std::cout << count << "\n";
Chris@16 607 eraseItrs[numEdges] = lowIter;
Chris@16 608 ++numEdges;
Chris@16 609 ++lowIter;
Chris@16 610 }
Chris@16 611 if(numEdges == 1) {
Chris@16 612 //look for the next crossing point and continue
Chris@16 613 //std::cout << "found only one edge\n";
Chris@16 614 findCross_(eraseItrs[0]);
Chris@16 615 continue;
Chris@16 616 }
Chris@16 617 //before we erase the elements we need to decide if they should be written out
Chris@16 618 CountType currentCount = countBelow;
Chris@16 619 for(std::size_t i = 0; i < numEdges; ++i) {
Chris@16 620 output_functor f;
Chris@16 621 f(output, currentCount, eraseItrs[i]->count, crossPoint, eraseItrs[i]->rise, LOW);
Chris@16 622 currentCount = eraseItrs[i]->count;
Chris@16 623 }
Chris@16 624 //schedule erase of the elements
Chris@16 625 for(std::size_t i = 0; i < numEdges; ++i) {
Chris@16 626 eraseVec.push_back(eraseItrs[i]);
Chris@16 627 }
Chris@16 628
Chris@16 629 //take the derivative wrt theta of the count at the crossing point
Chris@16 630 vertex.second[2] = count[2] - countBelow;
Chris@16 631 vertex.second[1] = count[1] - count[2];
Chris@16 632 vertex.second[0] = count[0] - count[1];
Chris@16 633 //add the point, deriviative pair into the cross vector
Chris@16 634 //std::cout << "LOOK HERE!\n";
Chris@16 635 //std::cout << count << "\n";
Chris@16 636 //std::cout << vertex << "\n";
Chris@16 637 crossVector_.push_back(vertex);
Chris@16 638 }
Chris@16 639 //erase crossing elements
Chris@16 640 std::vector<iterator> searchVec;
Chris@16 641 for(std::size_t i = 0; i < eraseVec.size(); ++i) {
Chris@16 642 if(eraseVec[i] != scanData_.begin()) {
Chris@16 643 iterator searchItr = eraseVec[i];
Chris@16 644 --searchItr;
Chris@16 645 if(searchVec.empty() ||
Chris@16 646 searchVec.back() != searchItr)
Chris@16 647 searchVec.push_back(searchItr);
Chris@16 648 }
Chris@16 649 scanData_.erase(eraseVec[i]);
Chris@16 650 }
Chris@16 651 for(std::size_t i = 0; i < searchVec.size(); ++i) {
Chris@16 652 findCross_(searchVec[i]);
Chris@16 653 }
Chris@16 654 }
Chris@16 655
Chris@16 656 template <class iT>
Chris@16 657 inline iT mergeCross_(iT inputBegin, iT inputEnd) {
Chris@16 658 Scan45Vector vec;
Chris@16 659 swap(vec, crossVector_);
Chris@16 660 iT mergeEnd = inputBegin;
Chris@16 661 std::size_t mergeCount = 0;
Chris@16 662 while(mergeEnd != inputEnd &&
Chris@16 663 (*mergeEnd).first.x() == x_) {
Chris@16 664 ++mergeCount;
Chris@16 665 ++mergeEnd;
Chris@16 666 }
Chris@16 667 crossVector_.reserve((std::max)(vec.capacity(), vec.size() + mergeCount));
Chris@16 668 for(std::size_t i = 0; i < vec.size(); ++i){
Chris@16 669 while(inputBegin != mergeEnd &&
Chris@16 670 (*inputBegin).first.y() < vec[i].first.y()) {
Chris@16 671 crossVector_.push_back(*inputBegin);
Chris@16 672 ++inputBegin;
Chris@16 673 }
Chris@16 674 crossVector_.push_back(vec[i]);
Chris@16 675 }
Chris@16 676 while(inputBegin != mergeEnd){
Chris@16 677 crossVector_.push_back(*inputBegin);
Chris@16 678 ++inputBegin;
Chris@16 679 }
Chris@16 680 return inputBegin;
Chris@16 681 }
Chris@16 682
Chris@16 683 template <class cT, class iT>
Chris@16 684 inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
Chris@16 685 //std::cout << "processEvent_\n";
Chris@16 686 CountType verticalCount = CountType();
Chris@16 687 Point prevPoint;
Chris@16 688 iterator prevIter = scanData_.end();
Chris@16 689 while(inputBegin != inputEnd &&
Chris@16 690 (*inputBegin).first.x() == x_) {
Chris@16 691 //std::cout << (*inputBegin) << "\n";
Chris@16 692 //std::cout << "loop\n";
Chris@16 693 Scan45Vertex vertex = *inputBegin;
Chris@16 694 //std::cout << vertex.first << "\n";
Chris@16 695 //if vertical count propigating up fake a null event at the next element
Chris@16 696 if(verticalCount != CountType() && (prevIter != scanData_.end() &&
Chris@16 697 prevIter->evalAtX(x_) < vertex.first.y())) {
Chris@16 698 //std::cout << "faking null event\n";
Chris@16 699 vertex = Scan45Vertex(Point(x_, prevIter->evalAtX(x_)), Scan45Count());
Chris@16 700 } else {
Chris@16 701 ++inputBegin;
Chris@16 702 //std::cout << "after increment\n";
Chris@16 703 //accumulate overlapping changes in Scan45Count
Chris@16 704 while(inputBegin != inputEnd &&
Chris@16 705 (*inputBegin).first.x() == x_ &&
Chris@16 706 (*inputBegin).first.y() == vertex.first.y()) {
Chris@16 707 //std::cout << "accumulate\n";
Chris@16 708 vertex.second += (*inputBegin).second;
Chris@16 709 ++inputBegin;
Chris@16 710 }
Chris@16 711 }
Chris@16 712 //std::cout << vertex.second << "\n";
Chris@16 713 //integrate vertex
Chris@16 714 CountType currentCount = verticalCount;// + vertex.second[0];
Chris@16 715 for(unsigned int i = 0; i < 3; ++i) {
Chris@16 716 vertex.second[i] = currentCount += vertex.second[i];
Chris@16 717 }
Chris@16 718 //std::cout << vertex.second << "\n";
Chris@16 719 //vertex represents the change in state at this point
Chris@16 720
Chris@16 721 //get counts at current vertex
Chris@16 722 CountType countBelow;
Chris@16 723 iterator lowIter = lookUp_(vertex.first.y());
Chris@16 724 if(lowIter != scanData_.begin()) {
Chris@16 725 //get count from below
Chris@16 726 --lowIter;
Chris@16 727 countBelow = lowIter->count;
Chris@16 728 ++lowIter;
Chris@16 729 }
Chris@16 730 //std::cout << "Count Below: " << countBelow[0] << " " << countBelow[1] << "\n";
Chris@16 731 //std::cout << "vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n";
Chris@16 732 Scan45Count countAt(countBelow - verticalCount);
Chris@16 733 //check if the vertical edge should be written out
Chris@16 734 if(verticalCount != CountType()) {
Chris@16 735 output_functor f;
Chris@16 736 f(output, countBelow - verticalCount, countBelow, prevPoint, 2, HIGH);
Chris@16 737 f(output, countBelow - verticalCount, countBelow, vertex.first, 2, LOW);
Chris@16 738 }
Chris@16 739 currentCount = countBelow - verticalCount;
Chris@16 740 while(lowIter != scanData_.end() &&
Chris@16 741 lowIter->evalAtX(x_) == vertex.first.y()) {
Chris@16 742 for(unsigned int i = lowIter->rise + 1; i < 3; ++i) {
Chris@16 743 countAt[i] = lowIter->count;
Chris@16 744 }
Chris@16 745 Point lp(lowIter->x, lowIter->y);
Chris@16 746 if(lp != vertex.first) {
Chris@16 747 output_functor f;
Chris@16 748 f(output, currentCount, lowIter->count, vertex.first, lowIter->rise, LOW);
Chris@16 749 }
Chris@16 750 currentCount = lowIter->count;
Chris@16 751 iterator nextIter = lowIter;
Chris@16 752 ++nextIter;
Chris@16 753 //std::cout << "erase\n";
Chris@16 754 scanData_.erase(lowIter);
Chris@16 755 if(nextIter != scanData_.end())
Chris@16 756 findCross_(nextIter);
Chris@16 757 lowIter = nextIter;
Chris@16 758 }
Chris@16 759 verticalCount += vertex.second[3];
Chris@16 760 prevPoint = vertex.first;
Chris@16 761 //std::cout << "new vertical count: " << verticalCount[0] << " " << verticalCount[1] << "\n";
Chris@16 762 prevIter = lowIter;
Chris@16 763 //count represents the current state at this point
Chris@16 764 //std::cout << vertex.second << "\n";
Chris@16 765 //std::cout << countAt << "\n";
Chris@16 766 //std::cout << "ADD\n";
Chris@16 767 vertex.second += countAt;
Chris@16 768 //std::cout << vertex.second << "\n";
Chris@16 769
Chris@16 770 //add elements to the scanline
Chris@16 771 for(int i = 0; i < 3; ++i) {
Chris@16 772 if(vertex.second[i] != countBelow) {
Chris@16 773 //std::cout << "insert: " << vertex.first.x() << " " << vertex.first.y() << " " << i-1 <<
Chris@16 774 // " " << vertex.second[i][0] << " " << vertex.second[i][1] << "\n";
Chris@16 775 iterator insertIter = scanData_.insert(scanData_.end(),
Chris@16 776 Scan45ElementT<CountType>(vertex.first.x(),
Chris@16 777 vertex.first.y(),
Chris@16 778 i - 1, vertex.second[i]));
Chris@16 779 findCross_(insertIter);
Chris@16 780 output_functor f;
Chris@16 781 f(output, countBelow, vertex.second[i], vertex.first, i - 1, HIGH);
Chris@16 782 }
Chris@16 783 countBelow = vertex.second[i];
Chris@16 784 }
Chris@16 785 }
Chris@16 786 //std::cout << "end processEvent\n";
Chris@16 787 return inputBegin;
Chris@16 788 }
Chris@16 789
Chris@16 790 //iter1 is horizontal
Chris@16 791 inline void scheduleCross0_(iterator iter1, iterator iter2) {
Chris@16 792 //std::cout << "0, ";
Chris@16 793 Unit y1 = iter1->evalAtX(x_);
Chris@16 794 Unit y2 = iter2->evalAtX(x_);
Chris@16 795 LongUnit delta = local_abs(LongUnit(y1) - LongUnit(y2));
Chris@16 796 if(delta + static_cast<LongUnit>(x_) <= (std::numeric_limits<Unit>::max)())
Chris@16 797 crossQueue_.insert(crossQueue_.end(), Point(x_ + static_cast<Unit>(delta), y1));
Chris@16 798 //std::cout << Point(x_ + delta, y1);
Chris@16 799 }
Chris@16 800
Chris@16 801 //neither iter is horizontal
Chris@16 802 inline void scheduleCross1_(iterator iter1, iterator iter2) {
Chris@16 803 //std::cout << "1, ";
Chris@16 804 Unit y1 = iter1->evalAtX(x_);
Chris@16 805 Unit y2 = iter2->evalAtX(x_);
Chris@16 806 //std::cout << y1 << " " << y2 << ": ";
Chris@16 807 //note that half the delta cannot exceed the positive inter range
Chris@16 808 LongUnit delta = y1;
Chris@16 809 delta -= y2;
Chris@16 810 Unit UnitMax = (std::numeric_limits<Unit>::max)();
Chris@16 811 if((delta & 1) == 1) {
Chris@16 812 //delta is odd, division by 2 will result in integer trunctaion
Chris@16 813 if(delta == 1) {
Chris@16 814 //the cross point is not on the integer grid and cannot be represented
Chris@16 815 //we must throw an exception
Chris@16 816 std::string msg = "GTL 45 Boolean error, precision insufficient to represent edge intersection coordinate value.";
Chris@16 817 throw(msg);
Chris@16 818 } else {
Chris@16 819 //note that result of this subtraction is always positive because itr1 is above itr2 in scanline
Chris@16 820 LongUnit halfDelta2 = (LongUnit)((((LongUnit)y1) - y2)/2);
Chris@16 821 //note that halfDelta2 has been truncated
Chris@16 822 if(halfDelta2 + x_ <= UnitMax && halfDelta2 + y2 <= UnitMax) {
Chris@16 823 crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta2), y2+static_cast<Unit>(halfDelta2)));
Chris@16 824 crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta2), y2+static_cast<Unit>(halfDelta2)+1));
Chris@16 825 }
Chris@16 826 }
Chris@16 827 } else {
Chris@16 828 LongUnit halfDelta = (LongUnit)((((LongUnit)y1) - y2)/2);
Chris@16 829 if(halfDelta + x_ <= UnitMax && halfDelta + y2 <= UnitMax)
Chris@16 830 crossQueue_.insert(crossQueue_.end(), Point(x_+static_cast<Unit>(halfDelta), y2+static_cast<Unit>(halfDelta)));
Chris@16 831 //std::cout << Point(x_+halfDelta, y2+halfDelta);
Chris@16 832 }
Chris@16 833 }
Chris@16 834
Chris@16 835 inline void findCross_(iterator iter) {
Chris@16 836 //std::cout << "find cross ";
Chris@16 837 iterator iteratorBelow = iter;
Chris@16 838 iterator iteratorAbove = iter;
Chris@16 839 if(iter != scanData_.begin() && iter->rise < 1) {
Chris@16 840 --iteratorBelow;
Chris@16 841 if(iter->rise == 0){
Chris@16 842 if(iteratorBelow->rise == 1) {
Chris@16 843 scheduleCross0_(iter, iteratorBelow);
Chris@16 844 }
Chris@16 845 } else {
Chris@16 846 //iter->rise == -1
Chris@16 847 if(iteratorBelow->rise == 1) {
Chris@16 848 scheduleCross1_(iter, iteratorBelow);
Chris@16 849 } else if(iteratorBelow->rise == 0) {
Chris@16 850 scheduleCross0_(iteratorBelow, iter);
Chris@16 851 }
Chris@16 852 }
Chris@16 853 }
Chris@16 854 ++iteratorAbove;
Chris@16 855 if(iteratorAbove != scanData_.end() && iter->rise > -1) {
Chris@16 856 if(iter->rise == 0) {
Chris@16 857 if(iteratorAbove->rise == -1) {
Chris@16 858 scheduleCross0_(iter, iteratorAbove);
Chris@16 859 }
Chris@16 860 } else {
Chris@16 861 //iter->rise == 1
Chris@16 862 if(iteratorAbove->rise == -1) {
Chris@16 863 scheduleCross1_(iteratorAbove, iter);
Chris@16 864 } else if(iteratorAbove->rise == 0) {
Chris@16 865 scheduleCross0_(iteratorAbove, iter);
Chris@16 866 }
Chris@16 867 }
Chris@16 868 }
Chris@16 869 //std::cout << "\n";
Chris@16 870 }
Chris@16 871
Chris@16 872 inline iterator lookUp_(Unit y){
Chris@16 873 //if just before then we need to look from 1 not -1
Chris@16 874 return scanData_.lower_bound(Scan45ElementT<CountType>(x_, y, -1+2*justBefore_));
Chris@16 875 }
Chris@16 876 };
Chris@16 877
Chris@16 878 //template <typename CountType>
Chris@16 879 //static inline void print45Data(const std::set<Scan45ElementT<CountType>,
Chris@16 880 // lessScan45Element<CountType> >& data) {
Chris@16 881 // typename std::set<Scan45ElementT<CountType>, lessScan45Element<CountType> >::const_iterator iter;
Chris@16 882 // for(iter = data.begin(); iter != data.end(); ++iter) {
Chris@16 883 // std::cout << iter->x << " " << iter->y << " " << iter->rise << "\n";
Chris@16 884 // }
Chris@16 885 //}
Chris@16 886
Chris@16 887 template <typename streamtype>
Chris@16 888 static inline bool testScan45Data(streamtype& stdcout) {
Chris@16 889 Unit x = 0;
Chris@16 890 int justBefore = false;
Chris@16 891 lessScan45Element<Count2> lessElm(&x, &justBefore);
Chris@16 892 std::set<Scan45ElementT<Count2>, lessScan45Element<Count2> > testData(lessElm);
Chris@16 893 //Unit size = testData.size();
Chris@16 894 typedef std::set<Scan45ElementT<Count2>, lessScan45Element<Count2> > Scan45Data;
Chris@16 895 typename Scan45Data::iterator itr10 = testData.insert(testData.end(), Scan45Element(0, 10, 1));
Chris@16 896 typename Scan45Data::iterator itr20 = testData.insert(testData.end(), Scan45Element(0, 20, 1));
Chris@16 897 typename Scan45Data::iterator itr30 = testData.insert(testData.end(), Scan45Element(0, 30, -1));
Chris@16 898 typename Scan45Data::iterator itr40 = testData.insert(testData.end(), Scan45Element(0, 40, -1));
Chris@16 899 typename Scan45Data::iterator itrA = testData.lower_bound(Scan45Element(0, 29, -1));
Chris@16 900 typename Scan45Data::iterator itr1 = testData.lower_bound(Scan45Element(0, 10, -1));
Chris@16 901 x = 4;
Chris@16 902 //now at 14 24 26 36
Chris@16 903 typename Scan45Data::iterator itrB = testData.lower_bound(Scan45Element(4, 29, -1));
Chris@16 904 typename Scan45Data::iterator itr2 = testData.lower_bound(Scan45Element(4, 14, -1));
Chris@16 905 if(itr1 != itr2) stdcout << "test1 failed\n";
Chris@16 906 if(itrA == itrB) stdcout << "test2 failed\n";
Chris@16 907 //remove crossing elements
Chris@16 908 testData.erase(itr20);
Chris@16 909 testData.erase(itr30);
Chris@16 910 x = 5;
Chris@16 911 itr20 = testData.insert(testData.end(), Scan45Element(0, 20, 1));
Chris@16 912 itr30 = testData.insert(testData.end(), Scan45Element(0, 30, -1));
Chris@16 913 //now at 15 25 25 35
Chris@16 914 typename Scan45Data::iterator itr = testData.begin();
Chris@16 915 if(itr != itr10) stdcout << "test3 failed\n";
Chris@16 916 ++itr;
Chris@16 917 if(itr != itr30) stdcout << "test4 failed\n";
Chris@16 918 ++itr;
Chris@16 919 if(itr != itr20) stdcout << "test5 failed\n";
Chris@16 920 ++itr;
Chris@16 921 if(itr != itr40) stdcout << "test6 failed\n";
Chris@16 922 stdcout << "done testing Scan45Data\n";
Chris@16 923 return true;
Chris@16 924 }
Chris@16 925
Chris@16 926 template <typename stream_type>
Chris@16 927 static inline bool testScan45Rect(stream_type& stdcout) {
Chris@16 928 stdcout << "testing Scan45Rect\n";
Chris@16 929 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 930 std::vector<Vertex45 > result;
Chris@16 931 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 932 std::vector<Scan45Vertex> vertices;
Chris@16 933 //is a Rectnagle(0, 0, 10, 10);
Chris@16 934 Count2 count(1, 0);
Chris@16 935 Count2 ncount(-1, 0);
Chris@16 936 vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 937 vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 938 vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 939 vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 940 stdcout << "scanning\n";
Chris@16 941 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 942 stdcout << "done scanning\n";
Chris@16 943 // result size == 8
Chris@16 944 // result == 0 0 0 1
Chris@16 945 // result == 0 0 2 1
Chris@16 946 // result == 0 10 2 -1
Chris@16 947 // result == 0 10 0 -1
Chris@16 948 // result == 10 0 0 -1
Chris@16 949 // result == 10 0 2 -1
Chris@16 950 // result == 10 10 2 1
Chris@16 951 // result == 10 10 0 1
Chris@16 952 std::vector<Vertex45> reference;
Chris@16 953 reference.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 954 reference.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 955 reference.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 956 reference.push_back(Vertex45(Point(0, 10), 0, -1));
Chris@16 957 reference.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 958 reference.push_back(Vertex45(Point(10, 0), 2, -1));
Chris@16 959 reference.push_back(Vertex45(Point(10, 10), 2, 1));
Chris@16 960 reference.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 961 if(result != reference) {
Chris@16 962 stdcout << "result size == " << result.size() << "\n";
Chris@16 963 for(std::size_t i = 0; i < result.size(); ++i) {
Chris@16 964 //std::cout << "result == " << result[i]<< "\n";
Chris@16 965 }
Chris@16 966 stdcout << "reference size == " << reference.size() << "\n";
Chris@16 967 for(std::size_t i = 0; i < reference.size(); ++i) {
Chris@16 968 //std::cout << "reference == " << reference[i]<< "\n";
Chris@16 969 }
Chris@16 970 return false;
Chris@16 971 }
Chris@16 972 stdcout << "done testing Scan45Rect\n";
Chris@16 973 return true;
Chris@16 974 }
Chris@16 975
Chris@16 976 template <typename stream_type>
Chris@16 977 static inline bool testScan45P1(stream_type& stdcout) {
Chris@16 978 stdcout << "testing Scan45P1\n";
Chris@16 979 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 980 std::vector<Vertex45 > result;
Chris@16 981 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 982 std::vector<Scan45Vertex> vertices;
Chris@16 983 //is a Rectnagle(0, 0, 10, 10);
Chris@16 984 Count2 count(1, 0);
Chris@16 985 Count2 ncount(-1, 0);
Chris@16 986 vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
Chris@16 987 vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), Count2(0, 0), ncount, ncount)));
Chris@16 988 vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), Count2(0, 0), ncount, ncount)));
Chris@16 989 vertices.push_back(Scan45Vertex(Point(10,20), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
Chris@16 990 stdcout << "scanning\n";
Chris@16 991 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 992 stdcout << "done scanning\n";
Chris@16 993 // result size == 8
Chris@16 994 // result == 0 0 1 1
Chris@16 995 // result == 0 0 2 1
Chris@16 996 // result == 0 10 2 -1
Chris@16 997 // result == 0 10 1 -1
Chris@16 998 // result == 10 10 1 -1
Chris@16 999 // result == 10 10 2 -1
Chris@16 1000 // result == 10 20 2 1
Chris@16 1001 // result == 10 20 1 1
Chris@16 1002 std::vector<Vertex45> reference;
Chris@16 1003 reference.push_back(Vertex45(Point(0, 0), 1, 1));
Chris@16 1004 reference.push_back(Vertex45(Point(0, 0), 2, 1));
Chris@16 1005 reference.push_back(Vertex45(Point(0, 10), 2, -1));
Chris@16 1006 reference.push_back(Vertex45(Point(0, 10), 1, -1));
Chris@16 1007 reference.push_back(Vertex45(Point(10, 10), 1, -1));
Chris@16 1008 reference.push_back(Vertex45(Point(10, 10), 2, -1));
Chris@16 1009 reference.push_back(Vertex45(Point(10, 20), 2, 1));
Chris@16 1010 reference.push_back(Vertex45(Point(10, 20), 1, 1));
Chris@16 1011 if(result != reference) {
Chris@16 1012 stdcout << "result size == " << result.size() << "\n";
Chris@16 1013 for(std::size_t i = 0; i < result.size(); ++i) {
Chris@16 1014 //std::cout << "result == " << result[i]<< "\n";
Chris@16 1015 }
Chris@16 1016 stdcout << "reference size == " << reference.size() << "\n";
Chris@16 1017 for(std::size_t i = 0; i < reference.size(); ++i) {
Chris@16 1018 //std::cout << "reference == " << reference[i]<< "\n";
Chris@16 1019 }
Chris@16 1020 return false;
Chris@16 1021 }
Chris@16 1022 stdcout << "done testing Scan45P1\n";
Chris@16 1023 return true;
Chris@16 1024 }
Chris@16 1025
Chris@16 1026 template <typename stream_type>
Chris@16 1027 static inline bool testScan45P2(stream_type& stdcout) {
Chris@16 1028 stdcout << "testing Scan45P2\n";
Chris@16 1029 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 1030 std::vector<Vertex45 > result;
Chris@16 1031 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 1032 std::vector<Scan45Vertex> vertices;
Chris@16 1033 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1034 Count2 count(1, 0);
Chris@16 1035 Count2 ncount(-1, 0);
Chris@16 1036 vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1037 vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, count, Count2(0, 0))));
Chris@16 1038 vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), ncount, count, Count2(0, 0))));
Chris@16 1039 vertices.push_back(Scan45Vertex(Point(20,10), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1040 stdcout << "scanning\n";
Chris@16 1041 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1042 stdcout << "done scanning\n";
Chris@16 1043 // result size == 8
Chris@16 1044 // result == 0 0 0 1
Chris@16 1045 // result == 0 0 1 -1
Chris@16 1046 // result == 10 0 0 -1
Chris@16 1047 // result == 10 0 1 1
Chris@16 1048 // result == 10 10 1 1
Chris@16 1049 // result == 10 10 0 -1
Chris@16 1050 // result == 20 10 1 -1
Chris@16 1051 // result == 20 10 0 1
Chris@16 1052 std::vector<Vertex45> reference;
Chris@16 1053 reference.push_back(Vertex45(Point(0, 0), 0, 1));
Chris@16 1054 reference.push_back(Vertex45(Point(0, 0), 1, -1));
Chris@16 1055 reference.push_back(Vertex45(Point(10, 0), 0, -1));
Chris@16 1056 reference.push_back(Vertex45(Point(10, 0), 1, 1));
Chris@16 1057 reference.push_back(Vertex45(Point(10, 10), 1, 1));
Chris@16 1058 reference.push_back(Vertex45(Point(10, 10), 0, -1));
Chris@16 1059 reference.push_back(Vertex45(Point(20, 10), 1, -1));
Chris@16 1060 reference.push_back(Vertex45(Point(20, 10), 0, 1));
Chris@16 1061 if(result != reference) {
Chris@16 1062 stdcout << "result size == " << result.size() << "\n";
Chris@16 1063 for(std::size_t i = 0; i < result.size(); ++i) {
Chris@16 1064 //stdcout << "result == " << result[i]<< "\n";
Chris@16 1065 }
Chris@16 1066 stdcout << "reference size == " << reference.size() << "\n";
Chris@16 1067 for(std::size_t i = 0; i < reference.size(); ++i) {
Chris@16 1068 //stdcout << "reference == " << reference[i]<< "\n";
Chris@16 1069 }
Chris@16 1070 return false;
Chris@16 1071 }
Chris@16 1072 stdcout << "done testing Scan45P2\n";
Chris@16 1073 return true;
Chris@16 1074 }
Chris@16 1075
Chris@16 1076 template <typename streamtype>
Chris@16 1077 static inline bool testScan45And(streamtype& stdcout) {
Chris@16 1078 stdcout << "testing Scan45And\n";
Chris@16 1079 Scan45<Count2, boolean_op_45_output_functor<1> > scan45;
Chris@16 1080 std::vector<Vertex45 > result;
Chris@16 1081 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 1082 std::vector<Scan45Vertex> vertices;
Chris@16 1083 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1084 Count2 count(1, 0);
Chris@16 1085 Count2 ncount(-1, 0);
Chris@16 1086 vertices.push_back(Scan45Vertex(Point(0,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1087 vertices.push_back(Scan45Vertex(Point(0,10), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1088 vertices.push_back(Scan45Vertex(Point(10,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1089 vertices.push_back(Scan45Vertex(Point(10,10), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1090 count = Count2(0, 1);
Chris@16 1091 ncount = count.invert();
Chris@16 1092 vertices.push_back(Scan45Vertex(Point(2,2), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1093 vertices.push_back(Scan45Vertex(Point(2,12), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1094 vertices.push_back(Scan45Vertex(Point(12,2), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1095 vertices.push_back(Scan45Vertex(Point(12,12), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1096 sortScan45Vector(vertices);
Chris@16 1097 stdcout << "scanning\n";
Chris@16 1098 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1099 stdcout << "done scanning\n";
Chris@16 1100 //result size == 8
Chris@16 1101 //result == 2 2 0 1
Chris@16 1102 //result == 2 2 2 1
Chris@16 1103 //result == 2 10 2 -1
Chris@16 1104 //result == 2 10 0 -1
Chris@16 1105 //result == 10 2 0 -1
Chris@16 1106 //result == 10 2 2 -1
Chris@16 1107 //result == 10 10 2 1
Chris@16 1108 //result == 10 10 0 1
Chris@16 1109 std::vector<Vertex45> reference;
Chris@16 1110 reference.push_back(Vertex45(Point(2, 2), 0, 1));
Chris@16 1111 reference.push_back(Vertex45(Point(2, 2), 2, 1));
Chris@16 1112 reference.push_back(Vertex45(Point(2, 10), 2, -1));
Chris@16 1113 reference.push_back(Vertex45(Point(2, 10), 0, -1));
Chris@16 1114 reference.push_back(Vertex45(Point(10, 2), 0, -1));
Chris@16 1115 reference.push_back(Vertex45(Point(10, 2), 2, -1));
Chris@16 1116 reference.push_back(Vertex45(Point(10, 10), 2, 1));
Chris@16 1117 reference.push_back(Vertex45(Point(10, 10), 0, 1));
Chris@16 1118 if(result != reference) {
Chris@16 1119 stdcout << "result size == " << result.size() << "\n";
Chris@16 1120 for(std::size_t i = 0; i < result.size(); ++i) {
Chris@16 1121 //stdcout << "result == " << result[i]<< "\n";
Chris@16 1122 }
Chris@16 1123 stdcout << "reference size == " << reference.size() << "\n";
Chris@16 1124 for(std::size_t i = 0; i < reference.size(); ++i) {
Chris@16 1125 //stdcout << "reference == " << reference[i]<< "\n";
Chris@16 1126 }
Chris@16 1127 return false;
Chris@16 1128 }
Chris@16 1129 stdcout << "done testing Scan45And\n";
Chris@16 1130 return true;
Chris@16 1131 }
Chris@16 1132
Chris@16 1133 template <typename stream_type>
Chris@16 1134 static inline bool testScan45Star1(stream_type& stdcout) {
Chris@16 1135 stdcout << "testing Scan45Star1\n";
Chris@16 1136 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 1137 std::vector<Vertex45 > result;
Chris@16 1138 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 1139 std::vector<Scan45Vertex> vertices;
Chris@16 1140 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1141 Count2 count(1, 0);
Chris@16 1142 Count2 ncount(-1, 0);
Chris@16 1143 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
Chris@16 1144 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
Chris@16 1145 vertices.push_back(Scan45Vertex(Point(8,16), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
Chris@16 1146 count = Count2(0, 1);
Chris@16 1147 ncount = count.invert();
Chris@16 1148 vertices.push_back(Scan45Vertex(Point(12,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
Chris@16 1149 vertices.push_back(Scan45Vertex(Point(4,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
Chris@16 1150 vertices.push_back(Scan45Vertex(Point(4,16), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
Chris@16 1151 sortScan45Vector(vertices);
Chris@16 1152 stdcout << "scanning\n";
Chris@16 1153 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1154 stdcout << "done scanning\n";
Chris@16 1155 // result size == 24
Chris@16 1156 // result == 0 8 -1 1
Chris@16 1157 // result == 0 8 1 -1
Chris@16 1158 // result == 4 0 1 1
Chris@16 1159 // result == 4 0 2 1
Chris@16 1160 // result == 4 4 2 -1
Chris@16 1161 // result == 4 4 -1 -1
Chris@16 1162 // result == 4 12 1 1
Chris@16 1163 // result == 4 12 2 1
Chris@16 1164 // result == 4 16 2 -1
Chris@16 1165 // result == 4 16 -1 -1
Chris@16 1166 // result == 6 2 1 -1
Chris@16 1167 // result == 6 14 -1 1
Chris@16 1168 // result == 6 2 -1 1
Chris@16 1169 // result == 6 14 1 -1
Chris@16 1170 // result == 8 0 -1 -1
Chris@16 1171 // result == 8 0 2 -1
Chris@16 1172 // result == 8 4 2 1
Chris@16 1173 // result == 8 4 1 1
Chris@16 1174 // result == 8 12 -1 -1
Chris@16 1175 // result == 8 12 2 -1
Chris@16 1176 // result == 8 16 2 1
Chris@16 1177 // result == 8 16 1 1
Chris@16 1178 // result == 12 8 1 -1
Chris@16 1179 // result == 12 8 -1 1
Chris@16 1180 if(result.size() != 24) {
Chris@16 1181 //stdcout << "result size == " << result.size() << "\n";
Chris@16 1182 //stdcout << "reference size == " << 24 << "\n";
Chris@16 1183 return false;
Chris@16 1184 }
Chris@16 1185 stdcout << "done testing Scan45Star1\n";
Chris@16 1186 return true;
Chris@16 1187 }
Chris@16 1188
Chris@16 1189 template <typename stream_type>
Chris@16 1190 static inline bool testScan45Star2(stream_type& stdcout) {
Chris@16 1191 stdcout << "testing Scan45Star2\n";
Chris@16 1192 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 1193 std::vector<Vertex45 > result;
Chris@16 1194 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 1195 std::vector<Scan45Vertex> vertices;
Chris@16 1196 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1197 Count2 count(1, 0);
Chris@16 1198 Count2 ncount(-1, 0);
Chris@16 1199 vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1200 vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1201 vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1202 count = Count2(0, 1);
Chris@16 1203 ncount = count.invert();
Chris@16 1204 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1205 vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1206 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1207 sortScan45Vector(vertices);
Chris@16 1208 stdcout << "scanning\n";
Chris@16 1209 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1210 stdcout << "done scanning\n";
Chris@16 1211 // result size == 24
Chris@16 1212 // result == 0 4 0 1
Chris@16 1213 // result == 0 4 1 -1
Chris@16 1214 // result == 0 8 -1 1
Chris@16 1215 // result == 0 8 0 -1
Chris@16 1216 // result == 2 6 1 1
Chris@16 1217 // result == 2 6 -1 -1
Chris@16 1218 // result == 4 4 0 -1
Chris@16 1219 // result == 4 8 0 1
Chris@16 1220 // result == 4 4 -1 1
Chris@16 1221 // result == 4 8 1 -1
Chris@16 1222 // result == 8 0 -1 -1
Chris@16 1223 // result == 8 0 1 1
Chris@16 1224 // result == 8 12 1 1
Chris@16 1225 // result == 8 12 -1 -1
Chris@16 1226 // result == 12 4 1 -1
Chris@16 1227 // result == 12 8 -1 1
Chris@16 1228 // result == 12 4 0 1
Chris@16 1229 // result == 12 8 0 -1
Chris@16 1230 // result == 14 6 -1 -1
Chris@16 1231 // result == 14 6 1 1
Chris@16 1232 // result == 16 4 0 -1
Chris@16 1233 // result == 16 4 -1 1
Chris@16 1234 // result == 16 8 1 -1
Chris@16 1235 // result == 16 8 0 1
Chris@16 1236 if(result.size() != 24) {
Chris@16 1237 //std::cout << "result size == " << result.size() << "\n";
Chris@16 1238 //std::cout << "reference size == " << 24 << "\n";
Chris@16 1239 return false;
Chris@16 1240 }
Chris@16 1241 stdcout << "done testing Scan45Star2\n";
Chris@16 1242 return true;
Chris@16 1243 }
Chris@16 1244
Chris@16 1245 template <typename stream_type>
Chris@16 1246 static inline bool testScan45Star3(stream_type& stdcout) {
Chris@16 1247 stdcout << "testing Scan45Star3\n";
Chris@16 1248 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 1249 std::vector<Vertex45 > result;
Chris@16 1250 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 1251 std::vector<Scan45Vertex> vertices;
Chris@16 1252 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1253 Count2 count(1, 0);
Chris@16 1254 Count2 ncount(-1, 0);
Chris@16 1255 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
Chris@16 1256 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
Chris@16 1257 vertices.push_back(Scan45Vertex(Point(8,16), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
Chris@16 1258
Chris@16 1259 vertices.push_back(Scan45Vertex(Point(6,0), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1260 vertices.push_back(Scan45Vertex(Point(6,14), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1261 vertices.push_back(Scan45Vertex(Point(12,0), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1262 vertices.push_back(Scan45Vertex(Point(12,14), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1263 count = Count2(0, 1);
Chris@16 1264 ncount = count.invert();
Chris@16 1265 vertices.push_back(Scan45Vertex(Point(12,8), Scan45Count(count, Count2(0, 0), ncount, Count2(0, 0))));
Chris@16 1266 vertices.push_back(Scan45Vertex(Point(4,0), Scan45Count(Count2(0, 0), Count2(0, 0), count, count)));
Chris@16 1267 vertices.push_back(Scan45Vertex(Point(4,16), Scan45Count(ncount, Count2(0, 0), Count2(0, 0), ncount)));
Chris@16 1268 sortScan45Vector(vertices);
Chris@16 1269 stdcout << "scanning\n";
Chris@16 1270 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1271 stdcout << "done scanning\n";
Chris@16 1272 // result size == 28
Chris@16 1273 // result == 0 8 -1 1
Chris@16 1274 // result == 0 8 1 -1
Chris@16 1275 // result == 4 0 1 1
Chris@16 1276 // result == 4 0 2 1
Chris@16 1277 // result == 4 4 2 -1
Chris@16 1278 // result == 4 4 -1 -1
Chris@16 1279 // result == 4 12 1 1
Chris@16 1280 // result == 4 12 2 1
Chris@16 1281 // result == 4 16 2 -1
Chris@16 1282 // result == 4 16 -1 -1
Chris@16 1283 // result == 6 2 1 -1
Chris@16 1284 // result == 6 14 -1 1
Chris@16 1285 // result == 6 0 0 1
Chris@16 1286 // result == 6 0 2 1
Chris@16 1287 // result == 6 2 2 -1
Chris@16 1288 // result == 6 14 1 -1
Chris@16 1289 // result == 8 0 0 -1
Chris@16 1290 // result == 8 0 0 1
Chris@16 1291 // result == 8 14 0 -1
Chris@16 1292 // result == 8 14 2 -1
Chris@16 1293 // result == 8 16 2 1
Chris@16 1294 // result == 8 16 1 1
Chris@16 1295 // result == 12 0 0 -1
Chris@16 1296 // result == 12 0 2 -1
Chris@16 1297 // result == 12 8 2 1
Chris@16 1298 // result == 12 8 2 -1
Chris@16 1299 // result == 12 14 2 1
Chris@16 1300 // result == 12 14 0 1
Chris@16 1301 if(result.size() != 28) {
Chris@16 1302 //std::cout << "result size == " << result.size() << "\n";
Chris@16 1303 //std::cout << "reference size == " << 28 << "\n";
Chris@16 1304 return false;
Chris@16 1305 }
Chris@16 1306
Chris@16 1307 stdcout << "done testing Scan45Star3\n";
Chris@16 1308 return true;
Chris@16 1309 }
Chris@16 1310
Chris@16 1311
Chris@16 1312 template <typename stream_type>
Chris@16 1313 static inline bool testScan45Star4(stream_type& stdcout) {
Chris@16 1314 stdcout << "testing Scan45Star4\n";
Chris@16 1315 Scan45<Count2, boolean_op_45_output_functor<0> > scan45;
Chris@16 1316 std::vector<Vertex45 > result;
Chris@16 1317 typedef std::pair<Point, Scan45Count> Scan45Vertex;
Chris@16 1318 std::vector<Scan45Vertex> vertices;
Chris@16 1319 //is a Rectnagle(0, 0, 10, 10);
Chris@16 1320 Count2 count(1, 0);
Chris@16 1321 Count2 ncount(-1, 0);
Chris@16 1322 vertices.push_back(Scan45Vertex(Point(0,4), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1323 vertices.push_back(Scan45Vertex(Point(16,4), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1324 vertices.push_back(Scan45Vertex(Point(8,12), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1325
Chris@16 1326 vertices.push_back(Scan45Vertex(Point(0,6), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1327 vertices.push_back(Scan45Vertex(Point(0,12), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1328 vertices.push_back(Scan45Vertex(Point(16,6), Scan45Count(Count2(0, 0), ncount, Count2(0, 0), ncount)));
Chris@16 1329 vertices.push_back(Scan45Vertex(Point(16,12), Scan45Count(Count2(0, 0), count, Count2(0, 0), count)));
Chris@16 1330 count = Count2(0, 1);
Chris@16 1331 ncount = count.invert();
Chris@16 1332 vertices.push_back(Scan45Vertex(Point(0,8), Scan45Count(count, ncount, Count2(0, 0), Count2(0, 0))));
Chris@16 1333 vertices.push_back(Scan45Vertex(Point(16,8), Scan45Count(Count2(0, 0), count, ncount, Count2(0, 0))));
Chris@16 1334 vertices.push_back(Scan45Vertex(Point(8,0), Scan45Count(ncount, Count2(0, 0), count, Count2(0, 0))));
Chris@16 1335 sortScan45Vector(vertices);
Chris@16 1336 stdcout << "scanning\n";
Chris@16 1337 scan45.scan(result, vertices.begin(), vertices.end());
Chris@16 1338 stdcout << "done scanning\n";
Chris@16 1339 // result size == 28
Chris@16 1340 // result == 0 4 0 1
Chris@16 1341 // result == 0 4 1 -1
Chris@16 1342 // result == 0 6 0 1
Chris@16 1343 // result == 0 6 2 1
Chris@16 1344 // result == 0 8 2 -1
Chris@16 1345 // result == 0 8 2 1
Chris@16 1346 // result == 0 12 2 -1
Chris@16 1347 // result == 0 12 0 -1
Chris@16 1348 // result == 2 6 1 1
Chris@16 1349 // result == 2 6 0 -1
Chris@16 1350 // result == 4 4 0 -1
Chris@16 1351 // result == 4 4 -1 1
Chris@16 1352 // result == 8 12 0 1
Chris@16 1353 // result == 8 0 -1 -1
Chris@16 1354 // result == 8 0 1 1
Chris@16 1355 // result == 8 12 0 -1
Chris@16 1356 // result == 12 4 1 -1
Chris@16 1357 // result == 12 4 0 1
Chris@16 1358 // result == 14 6 -1 -1
Chris@16 1359 // result == 14 6 0 1
Chris@16 1360 // result == 16 4 0 -1
Chris@16 1361 // result == 16 4 -1 1
Chris@16 1362 // result == 16 6 0 -1
Chris@16 1363 // result == 16 6 2 -1
Chris@16 1364 // result == 16 8 2 1
Chris@16 1365 // result == 16 8 2 -1
Chris@16 1366 // result == 16 12 2 1
Chris@16 1367 // result == 16 12 0 1
Chris@16 1368 if(result.size() != 28) {
Chris@16 1369 //stdcout << "result size == " << result.size() << "\n";
Chris@16 1370 //stdcout << "reference size == " << 28 << "\n";
Chris@16 1371 return false;
Chris@16 1372 }
Chris@16 1373
Chris@16 1374 stdcout << "done testing Scan45Star4\n";
Chris@16 1375 return true;
Chris@16 1376 }
Chris@16 1377
Chris@16 1378 template <typename stream_type>
Chris@16 1379 static inline bool testScan45(stream_type& stdcout) {
Chris@16 1380 if(!testScan45Rect(stdcout)) return false;
Chris@16 1381 if(!testScan45P1(stdcout)) return false;
Chris@16 1382 if(!testScan45P2(stdcout)) return false;
Chris@16 1383 if(!testScan45And(stdcout)) return false;
Chris@16 1384 if(!testScan45Star1(stdcout)) return false;
Chris@16 1385 if(!testScan45Star2(stdcout)) return false;
Chris@16 1386 if(!testScan45Star3(stdcout)) return false;
Chris@16 1387 if(!testScan45Star4(stdcout)) return false;
Chris@16 1388 return true;
Chris@16 1389 }
Chris@16 1390
Chris@16 1391 };
Chris@16 1392
Chris@16 1393 }
Chris@16 1394
Chris@16 1395 }
Chris@16 1396 #endif