polygon_45_formation.hpp 88 KB

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