polygon_arbitrary_formation.hpp 132 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907
  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_ARBITRARY_FORMATION_HPP
  8. #define BOOST_POLYGON_POLYGON_ARBITRARY_FORMATION_HPP
  9. namespace boost { namespace polygon{
  10. template <typename T, typename T2>
  11. struct PolyLineArbitraryByConcept {};
  12. template <typename T>
  13. class poly_line_arbitrary_polygon_data;
  14. template <typename T>
  15. class poly_line_arbitrary_hole_data;
  16. template <typename Unit>
  17. struct scanline_base {
  18. typedef point_data<Unit> Point;
  19. typedef std::pair<Point, Point> half_edge;
  20. class less_point {
  21. public:
  22. typedef Point first_argument_type;
  23. typedef Point second_argument_type;
  24. typedef bool result_type;
  25. inline less_point() {}
  26. inline bool operator () (const Point& pt1, const Point& pt2) const {
  27. if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true;
  28. if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) {
  29. if(pt1.get(VERTICAL) < pt2.get(VERTICAL)) return true;
  30. }
  31. return false;
  32. }
  33. };
  34. static inline bool between(Point pt, Point pt1, Point pt2) {
  35. less_point lp;
  36. if(lp(pt1, pt2))
  37. return lp(pt, pt2) && lp(pt1, pt);
  38. return lp(pt, pt1) && lp(pt2, pt);
  39. }
  40. template <typename area_type>
  41. static inline Unit compute_intercept(const area_type& dy2,
  42. const area_type& dx1,
  43. const area_type& dx2) {
  44. //intercept = dy2 * dx1 / dx2
  45. //return (Unit)(((area_type)dy2 * (area_type)dx1) / (area_type)dx2);
  46. area_type dx1_q = dx1 / dx2;
  47. area_type dx1_r = dx1 % dx2;
  48. return dx1_q * dy2 + (dy2 * dx1_r)/dx2;
  49. }
  50. template <typename area_type>
  51. static inline bool equal_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
  52. typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
  53. unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
  54. unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
  55. int dx1_sign = dx1 < 0 ? -1 : 1;
  56. int dx2_sign = dx2 < 0 ? -1 : 1;
  57. int dy1_sign = dy1 < 0 ? -1 : 1;
  58. int dy2_sign = dy2 < 0 ? -1 : 1;
  59. int cross_1_sign = dx2_sign * dy1_sign;
  60. int cross_2_sign = dx1_sign * dy2_sign;
  61. return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0);
  62. }
  63. template <typename T>
  64. static inline bool equal_slope_hp(const T& dx1, const T& dy1, const T& dx2, const T& dy2) {
  65. return dx1 * dy2 == dx2 * dy1;
  66. }
  67. static inline bool equal_slope(const Unit& x, const Unit& y,
  68. const Point& pt1, const Point& pt2) {
  69. const Point* pts[2] = {&pt1, &pt2};
  70. typedef typename coordinate_traits<Unit>::manhattan_area_type at;
  71. at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
  72. at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
  73. at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
  74. at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
  75. return equal_slope(dx1, dy1, dx2, dy2);
  76. }
  77. template <typename area_type>
  78. static inline bool less_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
  79. //reflext x and y slopes to right hand side half plane
  80. if(dx1 < 0) {
  81. dy1 *= -1;
  82. dx1 *= -1;
  83. } else if(dx1 == 0) {
  84. //if the first slope is vertical the first cannot be less
  85. return false;
  86. }
  87. if(dx2 < 0) {
  88. dy2 *= -1;
  89. dx2 *= -1;
  90. } else if(dx2 == 0) {
  91. //if the second slope is vertical the first is always less unless it is also vertical, in which case they are equal
  92. return dx1 != 0;
  93. }
  94. typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
  95. unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
  96. unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
  97. int dx1_sign = dx1 < 0 ? -1 : 1;
  98. int dx2_sign = dx2 < 0 ? -1 : 1;
  99. int dy1_sign = dy1 < 0 ? -1 : 1;
  100. int dy2_sign = dy2 < 0 ? -1 : 1;
  101. int cross_1_sign = dx2_sign * dy1_sign;
  102. int cross_2_sign = dx1_sign * dy2_sign;
  103. if(cross_1_sign < cross_2_sign) return true;
  104. if(cross_2_sign < cross_1_sign) return false;
  105. if(cross_1_sign == -1) return cross_2 < cross_1;
  106. return cross_1 < cross_2;
  107. }
  108. static inline bool less_slope(const Unit& x, const Unit& y,
  109. const Point& pt1, const Point& pt2) {
  110. const Point* pts[2] = {&pt1, &pt2};
  111. //compute y value on edge from pt_ to pts[1] at the x value of pts[0]
  112. typedef typename coordinate_traits<Unit>::manhattan_area_type at;
  113. at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
  114. at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
  115. at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
  116. at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
  117. return less_slope(dx1, dy1, dx2, dy2);
  118. }
  119. //return -1 below, 0 on and 1 above line
  120. static inline int on_above_or_below(Point pt, const half_edge& he) {
  121. if(pt == he.first || pt == he.second) return 0;
  122. if(equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second)) return 0;
  123. bool less_result = less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second);
  124. int retval = less_result ? -1 : 1;
  125. less_point lp;
  126. if(lp(he.second, he.first)) retval *= -1;
  127. if(!between(pt, he.first, he.second)) retval *= -1;
  128. return retval;
  129. }
  130. //returns true is the segment intersects the integer grid square with lower
  131. //left corner at point
  132. static inline bool intersects_grid(Point pt, const half_edge& he) {
  133. if(pt == he.second) return true;
  134. if(pt == he.first) return true;
  135. rectangle_data<Unit> rect1;
  136. set_points(rect1, he.first, he.second);
  137. if(contains(rect1, pt, true)) {
  138. if(is_vertical(he) || is_horizontal(he)) return true;
  139. } else {
  140. return false; //can't intersect a grid not within bounding box
  141. }
  142. Unit x = pt.get(HORIZONTAL);
  143. Unit y = pt.get(VERTICAL);
  144. if(equal_slope(x, y, he.first, he.second) &&
  145. between(pt, he.first, he.second)) return true;
  146. Point pt01(pt.get(HORIZONTAL), pt.get(VERTICAL) + 1);
  147. Point pt10(pt.get(HORIZONTAL) + 1, pt.get(VERTICAL));
  148. Point pt11(pt.get(HORIZONTAL) + 1, pt.get(VERTICAL) + 1);
  149. // if(pt01 == he.first) return true;
  150. // if(pt10 == he.first) return true;
  151. // if(pt11 == he.first) return true;
  152. // if(pt01 == he.second) return true;
  153. // if(pt10 == he.second) return true;
  154. // if(pt11 == he.second) return true;
  155. //check non-integer intersections
  156. half_edge widget1(pt, pt11);
  157. //intersects but not just at pt11
  158. if(intersects(widget1, he) && on_above_or_below(pt11, he)) return true;
  159. half_edge widget2(pt01, pt10);
  160. //intersects but not just at pt01 or 10
  161. if(intersects(widget2, he) && on_above_or_below(pt01, he) && on_above_or_below(pt10, he)) return true;
  162. return false;
  163. }
  164. static inline Unit evalAtXforYlazy(Unit xIn, Point pt, Point other_pt) {
  165. long double
  166. evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx,
  167. evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0;
  168. //y = (x - x1)dy/dx + y1
  169. //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y
  170. //assert pt.x != other_pt.x
  171. if(pt.y() == other_pt.y())
  172. return pt.y();
  173. evalAtXforYxIn = xIn;
  174. evalAtXforYx1 = pt.get(HORIZONTAL);
  175. evalAtXforYy1 = pt.get(VERTICAL);
  176. evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1;
  177. evalAtXforY0 = 0;
  178. if(evalAtXforYdx1 == evalAtXforY0) return (Unit)evalAtXforYy1;
  179. evalAtXforYx2 = other_pt.get(HORIZONTAL);
  180. evalAtXforYy2 = other_pt.get(VERTICAL);
  181. evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1;
  182. evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1;
  183. evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1);
  184. return (Unit)evalAtXforYret;
  185. }
  186. static inline typename high_precision_type<Unit>::type evalAtXforY(Unit xIn, Point pt, Point other_pt) {
  187. typename high_precision_type<Unit>::type
  188. evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx,
  189. evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0;
  190. //y = (x - x1)dy/dx + y1
  191. //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y
  192. //assert pt.x != other_pt.x
  193. typedef typename high_precision_type<Unit>::type high_precision;
  194. if(pt.y() == other_pt.y())
  195. return (high_precision)pt.y();
  196. evalAtXforYxIn = (high_precision)xIn;
  197. evalAtXforYx1 = pt.get(HORIZONTAL);
  198. evalAtXforYy1 = pt.get(VERTICAL);
  199. evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1;
  200. evalAtXforY0 = high_precision(0);
  201. if(evalAtXforYdx1 == evalAtXforY0) return evalAtXforYret = evalAtXforYy1;
  202. evalAtXforYx2 = (high_precision)other_pt.get(HORIZONTAL);
  203. evalAtXforYy2 = (high_precision)other_pt.get(VERTICAL);
  204. evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1;
  205. evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1;
  206. evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1);
  207. return evalAtXforYret;
  208. }
  209. struct evalAtXforYPack {
  210. typename high_precision_type<Unit>::type
  211. evalAtXforYret, evalAtXforYxIn, evalAtXforYx1, evalAtXforYy1, evalAtXforYdx1, evalAtXforYdx,
  212. evalAtXforYdy, evalAtXforYx2, evalAtXforYy2, evalAtXforY0;
  213. inline const typename high_precision_type<Unit>::type& evalAtXforY(Unit xIn, Point pt, Point other_pt) {
  214. //y = (x - x1)dy/dx + y1
  215. //y = (xIn - pt.x)*(other_pt.y-pt.y)/(other_pt.x-pt.x) + pt.y
  216. //assert pt.x != other_pt.x
  217. typedef typename high_precision_type<Unit>::type high_precision;
  218. if(pt.y() == other_pt.y()) {
  219. evalAtXforYret = (high_precision)pt.y();
  220. return evalAtXforYret;
  221. }
  222. evalAtXforYxIn = (high_precision)xIn;
  223. evalAtXforYx1 = pt.get(HORIZONTAL);
  224. evalAtXforYy1 = pt.get(VERTICAL);
  225. evalAtXforYdx1 = evalAtXforYxIn - evalAtXforYx1;
  226. evalAtXforY0 = high_precision(0);
  227. if(evalAtXforYdx1 == evalAtXforY0) return evalAtXforYret = evalAtXforYy1;
  228. evalAtXforYx2 = (high_precision)other_pt.get(HORIZONTAL);
  229. evalAtXforYy2 = (high_precision)other_pt.get(VERTICAL);
  230. evalAtXforYdx = evalAtXforYx2 - evalAtXforYx1;
  231. evalAtXforYdy = evalAtXforYy2 - evalAtXforYy1;
  232. evalAtXforYret = ((evalAtXforYdx1) * evalAtXforYdy / evalAtXforYdx + evalAtXforYy1);
  233. return evalAtXforYret;
  234. }
  235. };
  236. static inline bool is_vertical(const half_edge& he) {
  237. return he.first.get(HORIZONTAL) == he.second.get(HORIZONTAL);
  238. }
  239. static inline bool is_horizontal(const half_edge& he) {
  240. return he.first.get(VERTICAL) == he.second.get(VERTICAL);
  241. }
  242. static inline bool is_45_degree(const half_edge& he) {
  243. return euclidean_distance(he.first, he.second, HORIZONTAL) == euclidean_distance(he.first, he.second, VERTICAL);
  244. }
  245. //scanline comparator functor
  246. class less_half_edge {
  247. private:
  248. Unit *x_; //x value at which to apply comparison
  249. int *justBefore_;
  250. evalAtXforYPack * pack_;
  251. public:
  252. typedef half_edge first_argument_type;
  253. typedef half_edge second_argument_type;
  254. typedef bool result_type;
  255. inline less_half_edge() : x_(0), justBefore_(0), pack_(0) {}
  256. inline less_half_edge(Unit *x, int *justBefore, evalAtXforYPack * packIn) : x_(x), justBefore_(justBefore), pack_(packIn) {}
  257. inline less_half_edge(const less_half_edge& that) : x_(that.x_), justBefore_(that.justBefore_),
  258. pack_(that.pack_){}
  259. inline less_half_edge& operator=(const less_half_edge& that) {
  260. x_ = that.x_;
  261. justBefore_ = that.justBefore_;
  262. pack_ = that.pack_;
  263. return *this; }
  264. inline bool operator () (const half_edge& elm1, const half_edge& elm2) const {
  265. if((std::max)(elm1.first.y(), elm1.second.y()) < (std::min)(elm2.first.y(), elm2.second.y()))
  266. return true;
  267. if((std::min)(elm1.first.y(), elm1.second.y()) > (std::max)(elm2.first.y(), elm2.second.y()))
  268. return false;
  269. //check if either x of elem1 is equal to x_
  270. Unit localx = *x_;
  271. Unit elm1y = 0;
  272. bool elm1_at_x = false;
  273. if(localx == elm1.first.get(HORIZONTAL)) {
  274. elm1_at_x = true;
  275. elm1y = elm1.first.get(VERTICAL);
  276. } else if(localx == elm1.second.get(HORIZONTAL)) {
  277. elm1_at_x = true;
  278. elm1y = elm1.second.get(VERTICAL);
  279. }
  280. Unit elm2y = 0;
  281. bool elm2_at_x = false;
  282. if(localx == elm2.first.get(HORIZONTAL)) {
  283. elm2_at_x = true;
  284. elm2y = elm2.first.get(VERTICAL);
  285. } else if(localx == elm2.second.get(HORIZONTAL)) {
  286. elm2_at_x = true;
  287. elm2y = elm2.second.get(VERTICAL);
  288. }
  289. bool retval = false;
  290. if(!(elm1_at_x && elm2_at_x)) {
  291. //at least one of the segments doesn't have an end point a the current x
  292. //-1 below, 1 above
  293. int pt1_oab = on_above_or_below(elm1.first, half_edge(elm2.first, elm2.second));
  294. int pt2_oab = on_above_or_below(elm1.second, half_edge(elm2.first, elm2.second));
  295. if(pt1_oab == pt2_oab) {
  296. if(pt1_oab == -1)
  297. retval = true; //pt1 is below elm2 so elm1 is below elm2
  298. } else {
  299. //the segments can't cross so elm2 is on whatever side of elm1 that one of its ends is
  300. int pt3_oab = on_above_or_below(elm2.first, half_edge(elm1.first, elm1.second));
  301. if(pt3_oab == 1)
  302. retval = true; //elm1's point is above elm1
  303. }
  304. } else {
  305. if(elm1y < elm2y) {
  306. retval = true;
  307. } else if(elm1y == elm2y) {
  308. if(elm1 == elm2)
  309. return false;
  310. retval = less_slope(elm1.second.get(HORIZONTAL) - elm1.first.get(HORIZONTAL),
  311. elm1.second.get(VERTICAL) - elm1.first.get(VERTICAL),
  312. elm2.second.get(HORIZONTAL) - elm2.first.get(HORIZONTAL),
  313. elm2.second.get(VERTICAL) - elm2.first.get(VERTICAL));
  314. retval = ((*justBefore_) != 0) ^ retval;
  315. }
  316. }
  317. return retval;
  318. }
  319. };
  320. template <typename unsigned_product_type>
  321. static inline void unsigned_add(unsigned_product_type& result, int& result_sign, unsigned_product_type a, int a_sign, unsigned_product_type b, int b_sign) {
  322. int switcher = 0;
  323. if(a_sign < 0) switcher += 1;
  324. if(b_sign < 0) switcher += 2;
  325. if(a < b) switcher += 4;
  326. switch (switcher) {
  327. case 0: //both positive
  328. result = a + b;
  329. result_sign = 1;
  330. break;
  331. case 1: //a is negative
  332. result = a - b;
  333. result_sign = -1;
  334. break;
  335. case 2: //b is negative
  336. result = a - b;
  337. result_sign = 1;
  338. break;
  339. case 3: //both negative
  340. result = a + b;
  341. result_sign = -1;
  342. break;
  343. case 4: //both positive
  344. result = a + b;
  345. result_sign = 1;
  346. break;
  347. case 5: //a is negative
  348. result = b - a;
  349. result_sign = 1;
  350. break;
  351. case 6: //b is negative
  352. result = b - a;
  353. result_sign = -1;
  354. break;
  355. case 7: //both negative
  356. result = b + a;
  357. result_sign = -1;
  358. break;
  359. };
  360. }
  361. struct compute_intersection_pack {
  362. typedef typename high_precision_type<Unit>::type high_precision;
  363. high_precision y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y;
  364. static inline bool compute_lazy_intersection(Point& intersection, const half_edge& he1, const half_edge& he2,
  365. bool projected = false, bool round_closest = false) {
  366. long double y_high, dx1, dy1, dx2, dy2, x11, x21, y11, y21, x_num, y_num, x_den, y_den, x, y;
  367. typedef rectangle_data<Unit> Rectangle;
  368. Rectangle rect1, rect2;
  369. set_points(rect1, he1.first, he1.second);
  370. set_points(rect2, he2.first, he2.second);
  371. if(!projected && !::boost::polygon::intersects(rect1, rect2, true)) return false;
  372. if(is_vertical(he1)) {
  373. if(is_vertical(he2)) return false;
  374. y_high = evalAtXforYlazy(he1.first.get(HORIZONTAL), he2.first, he2.second);
  375. Unit y_local = (Unit)y_high;
  376. if(y_high < y_local) --y_local;
  377. if(projected || contains(rect1.get(VERTICAL), y_local, true)) {
  378. intersection = Point(he1.first.get(HORIZONTAL), y_local);
  379. return true;
  380. } else {
  381. return false;
  382. }
  383. } else if(is_vertical(he2)) {
  384. y_high = evalAtXforYlazy(he2.first.get(HORIZONTAL), he1.first, he1.second);
  385. Unit y_local = (Unit)y_high;
  386. if(y_high < y_local) --y_local;
  387. if(projected || contains(rect2.get(VERTICAL), y_local, true)) {
  388. intersection = Point(he2.first.get(HORIZONTAL), y_local);
  389. return true;
  390. } else {
  391. return false;
  392. }
  393. }
  394. //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point
  395. dy2 = (he2.second.get(VERTICAL)) -
  396. (he2.first.get(VERTICAL));
  397. dy1 = (he1.second.get(VERTICAL)) -
  398. (he1.first.get(VERTICAL));
  399. dx2 = (he2.second.get(HORIZONTAL)) -
  400. (he2.first.get(HORIZONTAL));
  401. dx1 = (he1.second.get(HORIZONTAL)) -
  402. (he1.first.get(HORIZONTAL));
  403. if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false;
  404. //the line segments have different slopes
  405. //we can assume that the line segments are not vertical because such an intersection is handled elsewhere
  406. x11 = (he1.first.get(HORIZONTAL));
  407. x21 = (he2.first.get(HORIZONTAL));
  408. y11 = (he1.first.get(VERTICAL));
  409. y21 = (he2.first.get(VERTICAL));
  410. //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1);
  411. //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1);
  412. x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2);
  413. x_den = (dy1 * dx2 - dy2 * dx1);
  414. y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2);
  415. y_den = (dx1 * dy2 - dx2 * dy1);
  416. x = x_num / x_den;
  417. y = y_num / y_den;
  418. //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << "\n";
  419. //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << "\n";
  420. //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
  421. //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
  422. if(round_closest) {
  423. x = x + 0.5;
  424. y = y + 0.5;
  425. }
  426. Unit x_unit = (Unit)(x);
  427. Unit y_unit = (Unit)(y);
  428. //truncate downward if it went up due to negative number
  429. if(x < x_unit) --x_unit;
  430. if(y < y_unit) --y_unit;
  431. if(is_horizontal(he1))
  432. y_unit = he1.first.y();
  433. if(is_horizontal(he2))
  434. y_unit = he2.first.y();
  435. //if(x != exp_x || y != exp_y)
  436. // std::cout << exp_x << " " << exp_y << " " << x << " " << y << "\n";
  437. //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
  438. //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second);
  439. //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << "\n";
  440. Point result(x_unit, y_unit);
  441. if(!projected && !contains(rect1, result, true)) return false;
  442. if(!projected && !contains(rect2, result, true)) return false;
  443. if(projected) {
  444. rectangle_data<long double> inf_rect(-(long double)(std::numeric_limits<Unit>::max)(),
  445. -(long double) (std::numeric_limits<Unit>::max)(),
  446. (long double)(std::numeric_limits<Unit>::max)(),
  447. (long double) (std::numeric_limits<Unit>::max)() );
  448. if(contains(inf_rect, point_data<long double>(x, y), true)) {
  449. intersection = result;
  450. return true;
  451. } else
  452. return false;
  453. }
  454. intersection = result;
  455. return true;
  456. }
  457. inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2,
  458. bool projected = false, bool round_closest = false) {
  459. if(!projected && !intersects(he1, he2))
  460. return false;
  461. bool lazy_success = compute_lazy_intersection(intersection, he1, he2, projected);
  462. if(!projected) {
  463. if(lazy_success) {
  464. if(intersects_grid(intersection, he1) &&
  465. intersects_grid(intersection, he2))
  466. return true;
  467. }
  468. } else {
  469. return lazy_success;
  470. }
  471. return compute_exact_intersection(intersection, he1, he2, projected, round_closest);
  472. }
  473. inline bool compute_exact_intersection(Point& intersection, const half_edge& he1, const half_edge& he2,
  474. bool projected = false, bool round_closest = false) {
  475. if(!projected && !intersects(he1, he2))
  476. return false;
  477. typedef rectangle_data<Unit> Rectangle;
  478. Rectangle rect1, rect2;
  479. set_points(rect1, he1.first, he1.second);
  480. set_points(rect2, he2.first, he2.second);
  481. if(!::boost::polygon::intersects(rect1, rect2, true)) return false;
  482. if(is_vertical(he1)) {
  483. if(is_vertical(he2)) return false;
  484. y_high = evalAtXforY(he1.first.get(HORIZONTAL), he2.first, he2.second);
  485. Unit y = convert_high_precision_type<Unit>(y_high);
  486. if(y_high < (high_precision)y) --y;
  487. if(contains(rect1.get(VERTICAL), y, true)) {
  488. intersection = Point(he1.first.get(HORIZONTAL), y);
  489. return true;
  490. } else {
  491. return false;
  492. }
  493. } else if(is_vertical(he2)) {
  494. y_high = evalAtXforY(he2.first.get(HORIZONTAL), he1.first, he1.second);
  495. Unit y = convert_high_precision_type<Unit>(y_high);
  496. if(y_high < (high_precision)y) --y;
  497. if(contains(rect2.get(VERTICAL), y, true)) {
  498. intersection = Point(he2.first.get(HORIZONTAL), y);
  499. return true;
  500. } else {
  501. return false;
  502. }
  503. }
  504. //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point
  505. dy2 = (high_precision)(he2.second.get(VERTICAL)) -
  506. (high_precision)(he2.first.get(VERTICAL));
  507. dy1 = (high_precision)(he1.second.get(VERTICAL)) -
  508. (high_precision)(he1.first.get(VERTICAL));
  509. dx2 = (high_precision)(he2.second.get(HORIZONTAL)) -
  510. (high_precision)(he2.first.get(HORIZONTAL));
  511. dx1 = (high_precision)(he1.second.get(HORIZONTAL)) -
  512. (high_precision)(he1.first.get(HORIZONTAL));
  513. if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false;
  514. //the line segments have different slopes
  515. //we can assume that the line segments are not vertical because such an intersection is handled elsewhere
  516. x11 = (high_precision)(he1.first.get(HORIZONTAL));
  517. x21 = (high_precision)(he2.first.get(HORIZONTAL));
  518. y11 = (high_precision)(he1.first.get(VERTICAL));
  519. y21 = (high_precision)(he2.first.get(VERTICAL));
  520. //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1);
  521. //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1);
  522. x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2);
  523. x_den = (dy1 * dx2 - dy2 * dx1);
  524. y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2);
  525. y_den = (dx1 * dy2 - dx2 * dy1);
  526. x = x_num / x_den;
  527. y = y_num / y_den;
  528. //std::cout << x << " " << y << "\n";
  529. //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << "\n";
  530. //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << "\n";
  531. //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
  532. //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
  533. if(round_closest) {
  534. x = x + (high_precision)0.5;
  535. y = y + (high_precision)0.5;
  536. }
  537. Unit x_unit = convert_high_precision_type<Unit>(x);
  538. Unit y_unit = convert_high_precision_type<Unit>(y);
  539. //truncate downward if it went up due to negative number
  540. if(x < (high_precision)x_unit) --x_unit;
  541. if(y < (high_precision)y_unit) --y_unit;
  542. if(is_horizontal(he1))
  543. y_unit = he1.first.y();
  544. if(is_horizontal(he2))
  545. y_unit = he2.first.y();
  546. //if(x != exp_x || y != exp_y)
  547. // std::cout << exp_x << " " << exp_y << " " << x << " " << y << "\n";
  548. //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
  549. //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second);
  550. //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << "\n";
  551. Point result(x_unit, y_unit);
  552. if(!contains(rect1, result, true)) return false;
  553. if(!contains(rect2, result, true)) return false;
  554. if(projected) {
  555. high_precision b1 = (high_precision) (std::numeric_limits<Unit>::min)();
  556. high_precision b2 = (high_precision) (std::numeric_limits<Unit>::max)();
  557. if(x > b2 || y > b2 || x < b1 || y < b1)
  558. return false;
  559. }
  560. intersection = result;
  561. return true;
  562. }
  563. };
  564. static inline bool compute_intersection(Point& intersection, const half_edge& he1, const half_edge& he2) {
  565. typedef typename high_precision_type<Unit>::type high_precision;
  566. typedef rectangle_data<Unit> Rectangle;
  567. Rectangle rect1, rect2;
  568. set_points(rect1, he1.first, he1.second);
  569. set_points(rect2, he2.first, he2.second);
  570. if(!::boost::polygon::intersects(rect1, rect2, true)) return false;
  571. if(is_vertical(he1)) {
  572. if(is_vertical(he2)) return false;
  573. high_precision y_high = evalAtXforY(he1.first.get(HORIZONTAL), he2.first, he2.second);
  574. Unit y = convert_high_precision_type<Unit>(y_high);
  575. if(y_high < (high_precision)y) --y;
  576. if(contains(rect1.get(VERTICAL), y, true)) {
  577. intersection = Point(he1.first.get(HORIZONTAL), y);
  578. return true;
  579. } else {
  580. return false;
  581. }
  582. } else if(is_vertical(he2)) {
  583. high_precision y_high = evalAtXforY(he2.first.get(HORIZONTAL), he1.first, he1.second);
  584. Unit y = convert_high_precision_type<Unit>(y_high);
  585. if(y_high < (high_precision)y) --y;
  586. if(contains(rect2.get(VERTICAL), y, true)) {
  587. intersection = Point(he2.first.get(HORIZONTAL), y);
  588. return true;
  589. } else {
  590. return false;
  591. }
  592. }
  593. //the bounding boxes of the two line segments intersect, so we check closer to find the intersection point
  594. high_precision dy2 = (high_precision)(he2.second.get(VERTICAL)) -
  595. (high_precision)(he2.first.get(VERTICAL));
  596. high_precision dy1 = (high_precision)(he1.second.get(VERTICAL)) -
  597. (high_precision)(he1.first.get(VERTICAL));
  598. high_precision dx2 = (high_precision)(he2.second.get(HORIZONTAL)) -
  599. (high_precision)(he2.first.get(HORIZONTAL));
  600. high_precision dx1 = (high_precision)(he1.second.get(HORIZONTAL)) -
  601. (high_precision)(he1.first.get(HORIZONTAL));
  602. if(equal_slope_hp(dx1, dy1, dx2, dy2)) return false;
  603. //the line segments have different slopes
  604. //we can assume that the line segments are not vertical because such an intersection is handled elsewhere
  605. high_precision x11 = (high_precision)(he1.first.get(HORIZONTAL));
  606. high_precision x21 = (high_precision)(he2.first.get(HORIZONTAL));
  607. high_precision y11 = (high_precision)(he1.first.get(VERTICAL));
  608. high_precision y21 = (high_precision)(he2.first.get(VERTICAL));
  609. //Unit exp_x = ((at)x11 * (at)dy1 * (at)dx2 - (at)x21 * (at)dy2 * (at)dx1 + (at)y21 * (at)dx1 * (at)dx2 - (at)y11 * (at)dx1 * (at)dx2) / ((at)dy1 * (at)dx2 - (at)dy2 * (at)dx1);
  610. //Unit exp_y = ((at)y11 * (at)dx1 * (at)dy2 - (at)y21 * (at)dx2 * (at)dy1 + (at)x21 * (at)dy1 * (at)dy2 - (at)x11 * (at)dy1 * (at)dy2) / ((at)dx1 * (at)dy2 - (at)dx2 * (at)dy1);
  611. high_precision x_num = (x11 * dy1 * dx2 - x21 * dy2 * dx1 + y21 * dx1 * dx2 - y11 * dx1 * dx2);
  612. high_precision x_den = (dy1 * dx2 - dy2 * dx1);
  613. high_precision y_num = (y11 * dx1 * dy2 - y21 * dx2 * dy1 + x21 * dy1 * dy2 - x11 * dy1 * dy2);
  614. high_precision y_den = (dx1 * dy2 - dx2 * dy1);
  615. high_precision x = x_num / x_den;
  616. high_precision y = y_num / y_den;
  617. //std::cout << "cross1 " << dy1 << " " << dx2 << " " << dy1 * dx2 << "\n";
  618. //std::cout << "cross2 " << dy2 << " " << dx1 << " " << dy2 * dx1 << "\n";
  619. //Unit exp_x = compute_x_intercept<at>(x11, x21, y11, y21, dy1, dy2, dx1, dx2);
  620. //Unit exp_y = compute_x_intercept<at>(y11, y21, x11, x21, dx1, dx2, dy1, dy2);
  621. Unit x_unit = convert_high_precision_type<Unit>(x);
  622. Unit y_unit = convert_high_precision_type<Unit>(y);
  623. //truncate downward if it went up due to negative number
  624. if(x < (high_precision)x_unit) --x_unit;
  625. if(y < (high_precision)y_unit) --y_unit;
  626. if(is_horizontal(he1))
  627. y_unit = he1.first.y();
  628. if(is_horizontal(he2))
  629. y_unit = he2.first.y();
  630. //if(x != exp_x || y != exp_y)
  631. // std::cout << exp_x << " " << exp_y << " " << x << " " << y << "\n";
  632. //Unit y1 = evalAtXforY(exp_x, he1.first, he1.second);
  633. //Unit y2 = evalAtXforY(exp_x, he2.first, he2.second);
  634. //std::cout << exp_x << " " << exp_y << " " << y1 << " " << y2 << "\n";
  635. Point result(x_unit, y_unit);
  636. if(!contains(rect1, result, true)) return false;
  637. if(!contains(rect2, result, true)) return false;
  638. intersection = result;
  639. return true;
  640. }
  641. static inline bool intersects(const half_edge& he1, const half_edge& he2) {
  642. typedef rectangle_data<Unit> Rectangle;
  643. Rectangle rect1, rect2;
  644. set_points(rect1, he1.first, he1.second);
  645. set_points(rect2, he2.first, he2.second);
  646. if(::boost::polygon::intersects(rect1, rect2, false)) {
  647. if(he1.first == he2.first) {
  648. if(he1.second != he2.second && equal_slope(he1.first.get(HORIZONTAL), he1.first.get(VERTICAL),
  649. he1.second, he2.second)) {
  650. return true;
  651. } else {
  652. return false;
  653. }
  654. }
  655. if(he1.first == he2.second) {
  656. if(he1.second != he2.first && equal_slope(he1.first.get(HORIZONTAL), he1.first.get(VERTICAL),
  657. he1.second, he2.first)) {
  658. return true;
  659. } else {
  660. return false;
  661. }
  662. }
  663. if(he1.second == he2.first) {
  664. if(he1.first != he2.second && equal_slope(he1.second.get(HORIZONTAL), he1.second.get(VERTICAL),
  665. he1.first, he2.second)) {
  666. return true;
  667. } else {
  668. return false;
  669. }
  670. }
  671. if(he1.second == he2.second) {
  672. if(he1.first != he2.first && equal_slope(he1.second.get(HORIZONTAL), he1.second.get(VERTICAL),
  673. he1.first, he2.first)) {
  674. return true;
  675. } else {
  676. return false;
  677. }
  678. }
  679. int oab1 = on_above_or_below(he1.first, he2);
  680. if(oab1 == 0 && between(he1.first, he2.first, he2.second)) return true;
  681. int oab2 = on_above_or_below(he1.second, he2);
  682. if(oab2 == 0 && between(he1.second, he2.first, he2.second)) return true;
  683. if(oab1 == oab2 && oab1 != 0) return false; //both points of he1 are on same side of he2
  684. int oab3 = on_above_or_below(he2.first, he1);
  685. if(oab3 == 0 && between(he2.first, he1.first, he1.second)) return true;
  686. int oab4 = on_above_or_below(he2.second, he1);
  687. if(oab4 == 0 && between(he2.second, he1.first, he1.second)) return true;
  688. if(oab3 == oab4) return false; //both points of he2 are on same side of he1
  689. return true; //they must cross
  690. }
  691. if(is_vertical(he1) && is_vertical(he2) && he1.first.get(HORIZONTAL) == he2.first.get(HORIZONTAL))
  692. return ::boost::polygon::intersects(rect1.get(VERTICAL), rect2.get(VERTICAL), false) &&
  693. rect1.get(VERTICAL) != rect2.get(VERTICAL);
  694. if(is_horizontal(he1) && is_horizontal(he2) && he1.first.get(VERTICAL) == he2.first.get(VERTICAL))
  695. return ::boost::polygon::intersects(rect1.get(HORIZONTAL), rect2.get(HORIZONTAL), false) &&
  696. rect1.get(HORIZONTAL) != rect2.get(HORIZONTAL);
  697. return false;
  698. }
  699. class vertex_half_edge {
  700. public:
  701. typedef typename high_precision_type<Unit>::type high_precision;
  702. Point pt;
  703. Point other_pt; // 1, 0 or -1
  704. int count; //dxdydTheta
  705. inline vertex_half_edge() : pt(), other_pt(), count() {}
  706. inline vertex_half_edge(const Point& point, const Point& other_point, int countIn) : pt(point), other_pt(other_point), count(countIn) {}
  707. inline vertex_half_edge(const vertex_half_edge& vertex) : pt(vertex.pt), other_pt(vertex.other_pt), count(vertex.count) {}
  708. inline vertex_half_edge& operator=(const vertex_half_edge& vertex){
  709. pt = vertex.pt; other_pt = vertex.other_pt; count = vertex.count; return *this; }
  710. inline bool operator==(const vertex_half_edge& vertex) const {
  711. return pt == vertex.pt && other_pt == vertex.other_pt && count == vertex.count; }
  712. inline bool operator!=(const vertex_half_edge& vertex) const { return !((*this) == vertex); }
  713. inline bool operator<(const vertex_half_edge& vertex) const {
  714. if(pt.get(HORIZONTAL) < vertex.pt.get(HORIZONTAL)) return true;
  715. if(pt.get(HORIZONTAL) == vertex.pt.get(HORIZONTAL)) {
  716. if(pt.get(VERTICAL) < vertex.pt.get(VERTICAL)) return true;
  717. if(pt.get(VERTICAL) == vertex.pt.get(VERTICAL)) { return less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL),
  718. other_pt, vertex.other_pt);
  719. }
  720. }
  721. return false;
  722. }
  723. inline bool operator>(const vertex_half_edge& vertex) const { return vertex < (*this); }
  724. inline bool operator<=(const vertex_half_edge& vertex) const { return !((*this) > vertex); }
  725. inline bool operator>=(const vertex_half_edge& vertex) const { return !((*this) < vertex); }
  726. inline high_precision evalAtX(Unit xIn) const { return evalAtXforYlazy(xIn, pt, other_pt); }
  727. inline bool is_vertical() const {
  728. return pt.get(HORIZONTAL) == other_pt.get(HORIZONTAL);
  729. }
  730. inline bool is_begin() const {
  731. return pt.get(HORIZONTAL) < other_pt.get(HORIZONTAL) ||
  732. (pt.get(HORIZONTAL) == other_pt.get(HORIZONTAL) &&
  733. (pt.get(VERTICAL) < other_pt.get(VERTICAL)));
  734. }
  735. };
  736. //when scanning Vertex45 for polygon formation we need a scanline comparator functor
  737. class less_vertex_half_edge {
  738. private:
  739. Unit *x_; //x value at which to apply comparison
  740. int *justBefore_;
  741. public:
  742. typedef vertex_half_edge first_argument_type;
  743. typedef vertex_half_edge second_argument_type;
  744. typedef bool result_type;
  745. inline less_vertex_half_edge() : x_(0), justBefore_(0) {}
  746. inline less_vertex_half_edge(Unit *x, int *justBefore) : x_(x), justBefore_(justBefore) {}
  747. inline less_vertex_half_edge(const less_vertex_half_edge& that) : x_(that.x_), justBefore_(that.justBefore_) {}
  748. inline less_vertex_half_edge& operator=(const less_vertex_half_edge& that) { x_ = that.x_; justBefore_ = that.justBefore_; return *this; }
  749. inline bool operator () (const vertex_half_edge& elm1, const vertex_half_edge& elm2) const {
  750. if((std::max)(elm1.pt.y(), elm1.other_pt.y()) < (std::min)(elm2.pt.y(), elm2.other_pt.y()))
  751. return true;
  752. if((std::min)(elm1.pt.y(), elm1.other_pt.y()) > (std::max)(elm2.pt.y(), elm2.other_pt.y()))
  753. return false;
  754. //check if either x of elem1 is equal to x_
  755. Unit localx = *x_;
  756. Unit elm1y = 0;
  757. bool elm1_at_x = false;
  758. if(localx == elm1.pt.get(HORIZONTAL)) {
  759. elm1_at_x = true;
  760. elm1y = elm1.pt.get(VERTICAL);
  761. } else if(localx == elm1.other_pt.get(HORIZONTAL)) {
  762. elm1_at_x = true;
  763. elm1y = elm1.other_pt.get(VERTICAL);
  764. }
  765. Unit elm2y = 0;
  766. bool elm2_at_x = false;
  767. if(localx == elm2.pt.get(HORIZONTAL)) {
  768. elm2_at_x = true;
  769. elm2y = elm2.pt.get(VERTICAL);
  770. } else if(localx == elm2.other_pt.get(HORIZONTAL)) {
  771. elm2_at_x = true;
  772. elm2y = elm2.other_pt.get(VERTICAL);
  773. }
  774. bool retval = false;
  775. if(!(elm1_at_x && elm2_at_x)) {
  776. //at least one of the segments doesn't have an end point a the current x
  777. //-1 below, 1 above
  778. int pt1_oab = on_above_or_below(elm1.pt, half_edge(elm2.pt, elm2.other_pt));
  779. int pt2_oab = on_above_or_below(elm1.other_pt, half_edge(elm2.pt, elm2.other_pt));
  780. if(pt1_oab == pt2_oab) {
  781. if(pt1_oab == -1)
  782. retval = true; //pt1 is below elm2 so elm1 is below elm2
  783. } else {
  784. //the segments can't cross so elm2 is on whatever side of elm1 that one of its ends is
  785. int pt3_oab = on_above_or_below(elm2.pt, half_edge(elm1.pt, elm1.other_pt));
  786. if(pt3_oab == 1)
  787. retval = true; //elm1's point is above elm1
  788. }
  789. } else {
  790. if(elm1y < elm2y) {
  791. retval = true;
  792. } else if(elm1y == elm2y) {
  793. if(elm1.pt == elm2.pt && elm1.other_pt == elm2.other_pt)
  794. return false;
  795. retval = less_slope(elm1.other_pt.get(HORIZONTAL) - elm1.pt.get(HORIZONTAL),
  796. elm1.other_pt.get(VERTICAL) - elm1.pt.get(VERTICAL),
  797. elm2.other_pt.get(HORIZONTAL) - elm2.pt.get(HORIZONTAL),
  798. elm2.other_pt.get(VERTICAL) - elm2.pt.get(VERTICAL));
  799. retval = ((*justBefore_) != 0) ^ retval;
  800. }
  801. }
  802. return retval;
  803. }
  804. };
  805. };
  806. template <typename Unit>
  807. class polygon_arbitrary_formation : public scanline_base<Unit> {
  808. public:
  809. typedef typename scanline_base<Unit>::Point Point;
  810. typedef typename scanline_base<Unit>::half_edge half_edge;
  811. typedef typename scanline_base<Unit>::vertex_half_edge vertex_half_edge;
  812. typedef typename scanline_base<Unit>::less_vertex_half_edge less_vertex_half_edge;
  813. class poly_line_arbitrary {
  814. public:
  815. typedef typename std::list<Point>::const_iterator iterator;
  816. // default constructor of point does not initialize x and y
  817. inline poly_line_arbitrary() : points() {} //do nothing default constructor
  818. // initialize a polygon from x,y values, it is assumed that the first is an x
  819. // and that the input is a well behaved polygon
  820. template<class iT>
  821. inline poly_line_arbitrary& set(iT inputBegin, iT inputEnd) {
  822. points.clear(); //just in case there was some old data there
  823. while(inputBegin != inputEnd) {
  824. points.insert(points.end(), *inputBegin);
  825. ++inputBegin;
  826. }
  827. return *this;
  828. }
  829. // copy constructor (since we have dynamic memory)
  830. inline poly_line_arbitrary(const poly_line_arbitrary& that) : points(that.points) {}
  831. // assignment operator (since we have dynamic memory do a deep copy)
  832. inline poly_line_arbitrary& operator=(const poly_line_arbitrary& that) {
  833. points = that.points;
  834. return *this;
  835. }
  836. // get begin iterator, returns a pointer to a const Unit
  837. inline iterator begin() const { return points.begin(); }
  838. // get end iterator, returns a pointer to a const Unit
  839. inline iterator end() const { return points.end(); }
  840. inline std::size_t size() const { return points.size(); }
  841. //public data member
  842. std::list<Point> points;
  843. };
  844. class active_tail_arbitrary {
  845. protected:
  846. //data
  847. poly_line_arbitrary* tailp_;
  848. active_tail_arbitrary *otherTailp_;
  849. std::list<active_tail_arbitrary*> holesList_;
  850. bool head_;
  851. public:
  852. /**
  853. * @brief iterator over coordinates of the figure
  854. */
  855. typedef typename poly_line_arbitrary::iterator iterator;
  856. /**
  857. * @brief iterator over holes contained within the figure
  858. */
  859. typedef typename std::list<active_tail_arbitrary*>::const_iterator iteratorHoles;
  860. //default constructor
  861. inline active_tail_arbitrary() : tailp_(), otherTailp_(), holesList_(), head_() {}
  862. //constructor
  863. inline active_tail_arbitrary(const vertex_half_edge& vertex, active_tail_arbitrary* otherTailp = 0) : tailp_(), otherTailp_(), holesList_(), head_() {
  864. tailp_ = new poly_line_arbitrary;
  865. tailp_->points.push_back(vertex.pt);
  866. //bool headArray[4] = {false, true, true, true};
  867. bool inverted = vertex.count == -1;
  868. head_ = (!vertex.is_vertical) ^ inverted;
  869. otherTailp_ = otherTailp;
  870. }
  871. inline active_tail_arbitrary(Point point, active_tail_arbitrary* otherTailp, bool head = true) :
  872. tailp_(), otherTailp_(), holesList_(), head_() {
  873. tailp_ = new poly_line_arbitrary;
  874. tailp_->points.push_back(point);
  875. head_ = head;
  876. otherTailp_ = otherTailp;
  877. }
  878. inline active_tail_arbitrary(active_tail_arbitrary* otherTailp) :
  879. tailp_(), otherTailp_(), holesList_(), head_() {
  880. tailp_ = otherTailp->tailp_;
  881. otherTailp_ = otherTailp;
  882. }
  883. //copy constructor
  884. inline active_tail_arbitrary(const active_tail_arbitrary& that) :
  885. tailp_(), otherTailp_(), holesList_(), head_() { (*this) = that; }
  886. //destructor
  887. inline ~active_tail_arbitrary() {
  888. destroyContents();
  889. }
  890. //assignment operator
  891. inline active_tail_arbitrary& operator=(const active_tail_arbitrary& that) {
  892. tailp_ = new poly_line_arbitrary(*(that.tailp_));
  893. head_ = that.head_;
  894. otherTailp_ = that.otherTailp_;
  895. holesList_ = that.holesList_;
  896. return *this;
  897. }
  898. //equivalence operator
  899. inline bool operator==(const active_tail_arbitrary& b) const {
  900. return tailp_ == b.tailp_ && head_ == b.head_;
  901. }
  902. /**
  903. * @brief get the pointer to the polyline that this is an active tail of
  904. */
  905. inline poly_line_arbitrary* getTail() const { return tailp_; }
  906. /**
  907. * @brief get the pointer to the polyline at the other end of the chain
  908. */
  909. inline poly_line_arbitrary* getOtherTail() const { return otherTailp_->tailp_; }
  910. /**
  911. * @brief get the pointer to the activetail at the other end of the chain
  912. */
  913. inline active_tail_arbitrary* getOtherActiveTail() const { return otherTailp_; }
  914. /**
  915. * @brief test if another active tail is the other end of the chain
  916. */
  917. inline bool isOtherTail(const active_tail_arbitrary& b) const { return &b == otherTailp_; }
  918. /**
  919. * @brief update this end of chain pointer to new polyline
  920. */
  921. inline active_tail_arbitrary& updateTail(poly_line_arbitrary* newTail) { tailp_ = newTail; return *this; }
  922. inline bool join(active_tail_arbitrary* tail) {
  923. if(tail == otherTailp_) {
  924. //std::cout << "joining to other tail!\n";
  925. return false;
  926. }
  927. if(tail->head_ == head_) {
  928. //std::cout << "joining head to head!\n";
  929. return false;
  930. }
  931. if(!tailp_) {
  932. //std::cout << "joining empty tail!\n";
  933. return false;
  934. }
  935. if(!(otherTailp_->head_)) {
  936. otherTailp_->copyHoles(*tail);
  937. otherTailp_->copyHoles(*this);
  938. } else {
  939. tail->otherTailp_->copyHoles(*this);
  940. tail->otherTailp_->copyHoles(*tail);
  941. }
  942. poly_line_arbitrary* tail1 = tailp_;
  943. poly_line_arbitrary* tail2 = tail->tailp_;
  944. if(head_) std::swap(tail1, tail2);
  945. typename std::list<point_data<Unit> >::reverse_iterator riter = tail1->points.rbegin();
  946. typename std::list<point_data<Unit> >::iterator iter = tail2->points.begin();
  947. if(*riter == *iter) {
  948. tail1->points.pop_back(); //remove duplicate point
  949. }
  950. tail1->points.splice(tail1->points.end(), tail2->points);
  951. delete tail2;
  952. otherTailp_->tailp_ = tail1;
  953. tail->otherTailp_->tailp_ = tail1;
  954. otherTailp_->otherTailp_ = tail->otherTailp_;
  955. tail->otherTailp_->otherTailp_ = otherTailp_;
  956. tailp_ = 0;
  957. tail->tailp_ = 0;
  958. tail->otherTailp_ = 0;
  959. otherTailp_ = 0;
  960. return true;
  961. }
  962. /**
  963. * @brief associate a hole to this active tail by the specified policy
  964. */
  965. inline active_tail_arbitrary* addHole(active_tail_arbitrary* hole) {
  966. holesList_.push_back(hole);
  967. copyHoles(*hole);
  968. copyHoles(*(hole->otherTailp_));
  969. return this;
  970. }
  971. /**
  972. * @brief get the list of holes
  973. */
  974. inline const std::list<active_tail_arbitrary*>& getHoles() const { return holesList_; }
  975. /**
  976. * @brief copy holes from that to this
  977. */
  978. inline void copyHoles(active_tail_arbitrary& that) { holesList_.splice(holesList_.end(), that.holesList_); }
  979. /**
  980. * @brief find out if solid to right
  981. */
  982. inline bool solidToRight() const { return !head_; }
  983. inline bool solidToLeft() const { return head_; }
  984. /**
  985. * @brief get vertex
  986. */
  987. inline Point getPoint() const {
  988. if(head_) return tailp_->points.front();
  989. return tailp_->points.back();
  990. }
  991. /**
  992. * @brief add a coordinate to the polygon at this active tail end, properly handle degenerate edges by removing redundant coordinate
  993. */
  994. inline void pushPoint(Point point) {
  995. if(head_) {
  996. //if(tailp_->points.size() < 2) {
  997. // tailp_->points.push_front(point);
  998. // return;
  999. //}
  1000. typename std::list<Point>::iterator iter = tailp_->points.begin();
  1001. if(iter == tailp_->points.end()) {
  1002. tailp_->points.push_front(point);
  1003. return;
  1004. }
  1005. ++iter;
  1006. if(iter == tailp_->points.end()) {
  1007. tailp_->points.push_front(point);
  1008. return;
  1009. }
  1010. --iter;
  1011. if(*iter != point) {
  1012. tailp_->points.push_front(point);
  1013. }
  1014. return;
  1015. }
  1016. //if(tailp_->points.size() < 2) {
  1017. // tailp_->points.push_back(point);
  1018. // return;
  1019. //}
  1020. typename std::list<Point>::reverse_iterator iter = tailp_->points.rbegin();
  1021. if(iter == tailp_->points.rend()) {
  1022. tailp_->points.push_back(point);
  1023. return;
  1024. }
  1025. ++iter;
  1026. if(iter == tailp_->points.rend()) {
  1027. tailp_->points.push_back(point);
  1028. return;
  1029. }
  1030. --iter;
  1031. if(*iter != point) {
  1032. tailp_->points.push_back(point);
  1033. }
  1034. }
  1035. /**
  1036. * @brief joins the two chains that the two active tail tails are ends of
  1037. * checks for closure of figure and writes out polygons appropriately
  1038. * returns a handle to a hole if one is closed
  1039. */
  1040. template <class cT>
  1041. static inline active_tail_arbitrary* joinChains(Point point, active_tail_arbitrary* at1, active_tail_arbitrary* at2, bool solid,
  1042. cT& output) {
  1043. if(at1->otherTailp_ == at2) {
  1044. //if(at2->otherTailp_ != at1) std::cout << "half closed error\n";
  1045. //we are closing a figure
  1046. at1->pushPoint(point);
  1047. at2->pushPoint(point);
  1048. if(solid) {
  1049. //we are closing a solid figure, write to output
  1050. //std::cout << "test1\n";
  1051. at1->copyHoles(*(at1->otherTailp_));
  1052. typename PolyLineArbitraryByConcept<Unit, typename geometry_concept<typename cT::value_type>::type>::type polyData(at1);
  1053. //poly_line_arbitrary_polygon_data polyData(at1);
  1054. //std::cout << "test2\n";
  1055. //std::cout << poly << "\n";
  1056. //std::cout << "test3\n";
  1057. typedef typename cT::value_type result_type;
  1058. output.push_back(result_type());
  1059. assign(output.back(), polyData);
  1060. //std::cout << "test4\n";
  1061. //std::cout << "delete " << at1->otherTailp_ << "\n";
  1062. //at1->print();
  1063. //at1->otherTailp_->print();
  1064. delete at1->otherTailp_;
  1065. //at1->print();
  1066. //at1->otherTailp_->print();
  1067. //std::cout << "test5\n";
  1068. //std::cout << "delete " << at1 << "\n";
  1069. delete at1;
  1070. //std::cout << "test6\n";
  1071. return 0;
  1072. } else {
  1073. //we are closing a hole, return the tail end active tail of the figure
  1074. return at1;
  1075. }
  1076. }
  1077. //we are not closing a figure
  1078. at1->pushPoint(point);
  1079. at1->join(at2);
  1080. delete at1;
  1081. delete at2;
  1082. return 0;
  1083. }
  1084. inline void destroyContents() {
  1085. if(otherTailp_) {
  1086. //std::cout << "delete p " << tailp_ << "\n";
  1087. if(tailp_) delete tailp_;
  1088. tailp_ = 0;
  1089. otherTailp_->otherTailp_ = 0;
  1090. otherTailp_->tailp_ = 0;
  1091. otherTailp_ = 0;
  1092. }
  1093. for(typename std::list<active_tail_arbitrary*>::iterator itr = holesList_.begin(); itr != holesList_.end(); ++itr) {
  1094. //std::cout << "delete p " << (*itr) << "\n";
  1095. if(*itr) {
  1096. if((*itr)->otherTailp_) {
  1097. delete (*itr)->otherTailp_;
  1098. (*itr)->otherTailp_ = 0;
  1099. }
  1100. delete (*itr);
  1101. }
  1102. (*itr) = 0;
  1103. }
  1104. holesList_.clear();
  1105. }
  1106. inline void print() {
  1107. //std::cout << this << " " << tailp_ << " " << otherTailp_ << " " << holesList_.size() << " " << head_ << "\n";
  1108. }
  1109. static inline std::pair<active_tail_arbitrary*, active_tail_arbitrary*> createActiveTailsAsPair(Point point, bool solid,
  1110. active_tail_arbitrary* phole, bool fractureHoles) {
  1111. active_tail_arbitrary* at1 = 0;
  1112. active_tail_arbitrary* at2 = 0;
  1113. if(phole && fractureHoles) {
  1114. //std::cout << "adding hole\n";
  1115. at1 = phole;
  1116. //assert solid == false, we should be creating a corner with solid below and to the left if there was a hole
  1117. at2 = at1->getOtherActiveTail();
  1118. at2->pushPoint(point);
  1119. at1->pushPoint(point);
  1120. } else {
  1121. at1 = new active_tail_arbitrary(point, at2, solid);
  1122. at2 = new active_tail_arbitrary(at1);
  1123. at1->otherTailp_ = at2;
  1124. at2->head_ = !solid;
  1125. if(phole)
  1126. at2->addHole(phole); //assert fractureHoles == false
  1127. }
  1128. return std::pair<active_tail_arbitrary*, active_tail_arbitrary*>(at1, at2);
  1129. }
  1130. };
  1131. typedef std::vector<std::pair<Point, int> > vertex_arbitrary_count;
  1132. class less_half_edge_count {
  1133. private:
  1134. Point pt_;
  1135. public:
  1136. typedef vertex_half_edge first_argument_type;
  1137. typedef vertex_half_edge second_argument_type;
  1138. typedef bool result_type;
  1139. inline less_half_edge_count() : pt_() {}
  1140. inline less_half_edge_count(Point point) : pt_(point) {}
  1141. inline bool operator () (const std::pair<Point, int>& elm1, const std::pair<Point, int>& elm2) const {
  1142. return scanline_base<Unit>::less_slope(pt_.get(HORIZONTAL), pt_.get(VERTICAL), elm1.first, elm2.first);
  1143. }
  1144. };
  1145. static inline void sort_vertex_arbitrary_count(vertex_arbitrary_count& count, const Point& pt) {
  1146. less_half_edge_count lfec(pt);
  1147. polygon_sort(count.begin(), count.end(), lfec);
  1148. }
  1149. typedef std::vector<std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> > incoming_count;
  1150. class less_incoming_count {
  1151. private:
  1152. Point pt_;
  1153. public:
  1154. typedef std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> first_argument_type;
  1155. typedef std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> second_argument_type;
  1156. typedef bool result_type;
  1157. inline less_incoming_count() : pt_() {}
  1158. inline less_incoming_count(Point point) : pt_(point) {}
  1159. inline bool operator () (const std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>& elm1,
  1160. const std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>& elm2) const {
  1161. Unit dx1 = elm1.first.first.first.get(HORIZONTAL) - elm1.first.first.second.get(HORIZONTAL);
  1162. Unit dx2 = elm2.first.first.first.get(HORIZONTAL) - elm2.first.first.second.get(HORIZONTAL);
  1163. Unit dy1 = elm1.first.first.first.get(VERTICAL) - elm1.first.first.second.get(VERTICAL);
  1164. Unit dy2 = elm2.first.first.first.get(VERTICAL) - elm2.first.first.second.get(VERTICAL);
  1165. return scanline_base<Unit>::less_slope(dx1, dy1, dx2, dy2);
  1166. }
  1167. };
  1168. static inline void sort_incoming_count(incoming_count& count, const Point& pt) {
  1169. less_incoming_count lfec(pt);
  1170. polygon_sort(count.begin(), count.end(), lfec);
  1171. }
  1172. static inline void compact_vertex_arbitrary_count(const Point& pt, vertex_arbitrary_count &count) {
  1173. if(count.empty()) return;
  1174. vertex_arbitrary_count tmp;
  1175. tmp.reserve(count.size());
  1176. tmp.push_back(count[0]);
  1177. //merge duplicates
  1178. for(std::size_t i = 1; i < count.size(); ++i) {
  1179. if(!equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), tmp[i-1].first, count[i].first)) {
  1180. tmp.push_back(count[i]);
  1181. } else {
  1182. tmp.back().second += count[i].second;
  1183. }
  1184. }
  1185. count.clear();
  1186. count.swap(tmp);
  1187. }
  1188. // inline std::ostream& operator<< (std::ostream& o, const vertex_arbitrary_count& c) {
  1189. // for(unsinged int i = 0; i < c.size(); ++i) {
  1190. // o << c[i].first << " " << c[i].second << " ";
  1191. // }
  1192. // return o;
  1193. // }
  1194. class vertex_arbitrary_compact {
  1195. public:
  1196. Point pt;
  1197. vertex_arbitrary_count count;
  1198. inline vertex_arbitrary_compact() : pt(), count() {}
  1199. inline vertex_arbitrary_compact(const Point& point, const Point& other_point, int countIn) : pt(point), count() {
  1200. count.push_back(std::pair<Point, int>(other_point, countIn));
  1201. }
  1202. inline vertex_arbitrary_compact(const vertex_half_edge& vertex) : pt(vertex.pt), count() {
  1203. count.push_back(std::pair<Point, int>(vertex.other_pt, vertex.count));
  1204. }
  1205. inline vertex_arbitrary_compact(const vertex_arbitrary_compact& vertex) : pt(vertex.pt), count(vertex.count) {}
  1206. inline vertex_arbitrary_compact& operator=(const vertex_arbitrary_compact& vertex){
  1207. pt = vertex.pt; count = vertex.count; return *this; }
  1208. inline bool operator==(const vertex_arbitrary_compact& vertex) const {
  1209. return pt == vertex.pt && count == vertex.count; }
  1210. inline bool operator!=(const vertex_arbitrary_compact& vertex) const { return !((*this) == vertex); }
  1211. inline bool operator<(const vertex_arbitrary_compact& vertex) const {
  1212. if(pt.get(HORIZONTAL) < vertex.pt.get(HORIZONTAL)) return true;
  1213. if(pt.get(HORIZONTAL) == vertex.pt.get(HORIZONTAL)) {
  1214. return pt.get(VERTICAL) < vertex.pt.get(VERTICAL);
  1215. }
  1216. return false;
  1217. }
  1218. inline bool operator>(const vertex_arbitrary_compact& vertex) const { return vertex < (*this); }
  1219. inline bool operator<=(const vertex_arbitrary_compact& vertex) const { return !((*this) > vertex); }
  1220. inline bool operator>=(const vertex_arbitrary_compact& vertex) const { return !((*this) < vertex); }
  1221. inline bool have_vertex_half_edge(int index) const { return count[index]; }
  1222. inline vertex_half_edge operator[](int index) const { return vertex_half_edge(pt, count[index]); }
  1223. };
  1224. // inline std::ostream& operator<< (std::ostream& o, const vertex_arbitrary_compact& c) {
  1225. // o << c.pt << ", " << c.count;
  1226. // return o;
  1227. // }
  1228. protected:
  1229. //definitions
  1230. typedef std::map<vertex_half_edge, active_tail_arbitrary*, less_vertex_half_edge> scanline_data;
  1231. typedef typename scanline_data::iterator iterator;
  1232. typedef typename scanline_data::const_iterator const_iterator;
  1233. //data
  1234. scanline_data scanData_;
  1235. Unit x_;
  1236. int justBefore_;
  1237. int fractureHoles_;
  1238. public:
  1239. inline polygon_arbitrary_formation() :
  1240. scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) {
  1241. less_vertex_half_edge lessElm(&x_, &justBefore_);
  1242. scanData_ = scanline_data(lessElm);
  1243. }
  1244. inline polygon_arbitrary_formation(bool fractureHoles) :
  1245. scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(fractureHoles) {
  1246. less_vertex_half_edge lessElm(&x_, &justBefore_);
  1247. scanData_ = scanline_data(lessElm);
  1248. }
  1249. inline polygon_arbitrary_formation(const polygon_arbitrary_formation& that) :
  1250. scanData_(), x_((std::numeric_limits<Unit>::min)()), justBefore_(false), fractureHoles_(0) { (*this) = that; }
  1251. inline polygon_arbitrary_formation& operator=(const polygon_arbitrary_formation& that) {
  1252. x_ = that.x_;
  1253. justBefore_ = that.justBefore_;
  1254. fractureHoles_ = that.fractureHoles_;
  1255. less_vertex_half_edge lessElm(&x_, &justBefore_);
  1256. scanData_ = scanline_data(lessElm);
  1257. for(const_iterator itr = that.scanData_.begin(); itr != that.scanData_.end(); ++itr){
  1258. scanData_.insert(scanData_.end(), *itr);
  1259. }
  1260. return *this;
  1261. }
  1262. //cT is an output container of Polygon45 or Polygon45WithHoles
  1263. //iT is an iterator over vertex_half_edge elements
  1264. //inputBegin - inputEnd is a range of sorted iT that represents
  1265. //one or more scanline stops worth of data
  1266. template <class cT, class iT>
  1267. void scan(cT& output, iT inputBegin, iT inputEnd) {
  1268. //std::cout << "1\n";
  1269. while(inputBegin != inputEnd) {
  1270. //std::cout << "2\n";
  1271. x_ = (*inputBegin).pt.get(HORIZONTAL);
  1272. //std::cout << "SCAN FORMATION " << x_ << "\n";
  1273. //std::cout << "x_ = " << x_ << "\n";
  1274. //std::cout << "scan line size: " << scanData_.size() << "\n";
  1275. inputBegin = processEvent_(output, inputBegin, inputEnd);
  1276. }
  1277. //std::cout << "scan line size: " << scanData_.size() << "\n";
  1278. }
  1279. protected:
  1280. //functions
  1281. template <class cT, class cT2>
  1282. inline std::pair<std::pair<Point, int>, active_tail_arbitrary*> processPoint_(cT& output, cT2& elements, Point point,
  1283. incoming_count& counts_from_scanline, vertex_arbitrary_count& incoming_count) {
  1284. //std::cout << "\nAT POINT: " << point << "\n";
  1285. //join any closing solid corners
  1286. std::vector<int> counts;
  1287. std::vector<int> incoming;
  1288. std::vector<active_tail_arbitrary*> tails;
  1289. counts.reserve(counts_from_scanline.size());
  1290. tails.reserve(counts_from_scanline.size());
  1291. incoming.reserve(incoming_count.size());
  1292. for(std::size_t i = 0; i < counts_from_scanline.size(); ++i) {
  1293. counts.push_back(counts_from_scanline[i].first.second);
  1294. tails.push_back(counts_from_scanline[i].second);
  1295. }
  1296. for(std::size_t i = 0; i < incoming_count.size(); ++i) {
  1297. incoming.push_back(incoming_count[i].second);
  1298. if(incoming_count[i].first < point) {
  1299. incoming.back() = 0;
  1300. }
  1301. }
  1302. active_tail_arbitrary* returnValue = 0;
  1303. std::pair<Point, int> returnCount(Point(0, 0), 0);
  1304. int i_size_less_1 = (int)(incoming.size()) -1;
  1305. int c_size_less_1 = (int)(counts.size()) -1;
  1306. int i_size = incoming.size();
  1307. int c_size = counts.size();
  1308. bool have_vertical_tail_from_below = false;
  1309. if(c_size &&
  1310. scanline_base<Unit>::is_vertical(counts_from_scanline.back().first.first)) {
  1311. have_vertical_tail_from_below = true;
  1312. }
  1313. //assert size = size_less_1 + 1
  1314. //std::cout << tails.size() << " " << incoming.size() << " " << counts_from_scanline.size() << " " << incoming_count.size() << "\n";
  1315. // for(std::size_t i = 0; i < counts.size(); ++i) {
  1316. // std::cout << counts_from_scanline[i].first.first.first.get(HORIZONTAL) << ",";
  1317. // std::cout << counts_from_scanline[i].first.first.first.get(VERTICAL) << " ";
  1318. // std::cout << counts_from_scanline[i].first.first.second.get(HORIZONTAL) << ",";
  1319. // std::cout << counts_from_scanline[i].first.first.second.get(VERTICAL) << ":";
  1320. // std::cout << counts_from_scanline[i].first.second << " ";
  1321. // } std::cout << "\n";
  1322. // print(incoming_count);
  1323. {
  1324. for(int i = 0; i < c_size_less_1; ++i) {
  1325. //std::cout << i << "\n";
  1326. if(counts[i] == -1) {
  1327. //std::cout << "fixed i\n";
  1328. for(int j = i + 1; j < c_size; ++j) {
  1329. //std::cout << j << "\n";
  1330. if(counts[j]) {
  1331. if(counts[j] == 1) {
  1332. //std::cout << "case1: " << i << " " << j << "\n";
  1333. //if a figure is closed it will be written out by this function to output
  1334. active_tail_arbitrary::joinChains(point, tails[i], tails[j], true, output);
  1335. counts[i] = 0;
  1336. counts[j] = 0;
  1337. tails[i] = 0;
  1338. tails[j] = 0;
  1339. }
  1340. break;
  1341. }
  1342. }
  1343. }
  1344. }
  1345. }
  1346. //find any pairs of incoming edges that need to create pair for leading solid
  1347. //std::cout << "checking case2\n";
  1348. {
  1349. for(int i = 0; i < i_size_less_1; ++i) {
  1350. //std::cout << i << "\n";
  1351. if(incoming[i] == 1) {
  1352. //std::cout << "fixed i\n";
  1353. for(int j = i + 1; j < i_size; ++j) {
  1354. //std::cout << j << "\n";
  1355. if(incoming[j]) {
  1356. //std::cout << incoming[j] << "\n";
  1357. if(incoming[j] == -1) {
  1358. //std::cout << "case2: " << i << " " << j << "\n";
  1359. //std::cout << "creating active tail pair\n";
  1360. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
  1361. active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, fractureHoles_ != 0);
  1362. //tailPair.first->print();
  1363. //tailPair.second->print();
  1364. if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  1365. //vertical active tail becomes return value
  1366. returnValue = tailPair.first;
  1367. returnCount.first = point;
  1368. returnCount.second = 1;
  1369. } else {
  1370. //std::cout << "new element " << j-1 << " " << -1 << "\n";
  1371. //std::cout << point << " " << incoming_count[j].first << "\n";
  1372. elements.push_back(std::pair<vertex_half_edge,
  1373. active_tail_arbitrary*>(vertex_half_edge(point,
  1374. incoming_count[j].first, -1), tailPair.first));
  1375. }
  1376. //std::cout << "new element " << i-1 << " " << 1 << "\n";
  1377. //std::cout << point << " " << incoming_count[i].first << "\n";
  1378. elements.push_back(std::pair<vertex_half_edge,
  1379. active_tail_arbitrary*>(vertex_half_edge(point,
  1380. incoming_count[i].first, 1), tailPair.second));
  1381. incoming[i] = 0;
  1382. incoming[j] = 0;
  1383. }
  1384. break;
  1385. }
  1386. }
  1387. }
  1388. }
  1389. }
  1390. //find any active tail that needs to pass through to an incoming edge
  1391. //we expect to find no more than two pass through
  1392. //find pass through with solid on top
  1393. {
  1394. //std::cout << "checking case 3\n";
  1395. for(int i = 0; i < c_size; ++i) {
  1396. //std::cout << i << "\n";
  1397. if(counts[i] != 0) {
  1398. if(counts[i] == 1) {
  1399. //std::cout << "fixed i\n";
  1400. for(int j = i_size_less_1; j >= 0; --j) {
  1401. if(incoming[j] != 0) {
  1402. if(incoming[j] == 1) {
  1403. //std::cout << "case3: " << i << " " << j << "\n";
  1404. //tails[i]->print();
  1405. //pass through solid on top
  1406. tails[i]->pushPoint(point);
  1407. //std::cout << "after push\n";
  1408. if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  1409. returnValue = tails[i];
  1410. returnCount.first = point;
  1411. returnCount.second = -1;
  1412. } else {
  1413. elements.push_back(std::pair<vertex_half_edge,
  1414. active_tail_arbitrary*>(vertex_half_edge(point,
  1415. incoming_count[j].first, incoming[j]), tails[i]));
  1416. }
  1417. tails[i] = 0;
  1418. counts[i] = 0;
  1419. incoming[j] = 0;
  1420. }
  1421. break;
  1422. }
  1423. }
  1424. }
  1425. break;
  1426. }
  1427. }
  1428. }
  1429. //std::cout << "checking case 4\n";
  1430. //find pass through with solid on bottom
  1431. {
  1432. for(int i = c_size_less_1; i >= 0; --i) {
  1433. //std::cout << "i = " << i << " with count " << counts[i] << "\n";
  1434. if(counts[i] != 0) {
  1435. if(counts[i] == -1) {
  1436. for(int j = 0; j < i_size; ++j) {
  1437. if(incoming[j] != 0) {
  1438. if(incoming[j] == -1) {
  1439. //std::cout << "case4: " << i << " " << j << "\n";
  1440. //pass through solid on bottom
  1441. tails[i]->pushPoint(point);
  1442. if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  1443. returnValue = tails[i];
  1444. returnCount.first = point;
  1445. returnCount.second = 1;
  1446. } else {
  1447. //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
  1448. //std::cout << point << " " << incoming_count[j].first << "\n";
  1449. elements.push_back(std::pair<vertex_half_edge,
  1450. active_tail_arbitrary*>(vertex_half_edge(point,
  1451. incoming_count[j].first, incoming[j]), tails[i]));
  1452. }
  1453. tails[i] = 0;
  1454. counts[i] = 0;
  1455. incoming[j] = 0;
  1456. }
  1457. break;
  1458. }
  1459. }
  1460. }
  1461. break;
  1462. }
  1463. }
  1464. }
  1465. //find the end of a hole or the beginning of a hole
  1466. //find end of a hole
  1467. {
  1468. for(int i = 0; i < c_size_less_1; ++i) {
  1469. if(counts[i] != 0) {
  1470. for(int j = i+1; j < c_size; ++j) {
  1471. if(counts[j] != 0) {
  1472. //std::cout << "case5: " << i << " " << j << "\n";
  1473. //we are ending a hole and may potentially close a figure and have to handle the hole
  1474. returnValue = active_tail_arbitrary::joinChains(point, tails[i], tails[j], false, output);
  1475. if(returnValue) returnCount.first = point;
  1476. //std::cout << returnValue << "\n";
  1477. tails[i] = 0;
  1478. tails[j] = 0;
  1479. counts[i] = 0;
  1480. counts[j] = 0;
  1481. break;
  1482. }
  1483. }
  1484. break;
  1485. }
  1486. }
  1487. }
  1488. //find beginning of a hole
  1489. {
  1490. for(int i = 0; i < i_size_less_1; ++i) {
  1491. if(incoming[i] != 0) {
  1492. for(int j = i+1; j < i_size; ++j) {
  1493. if(incoming[j] != 0) {
  1494. //std::cout << "case6: " << i << " " << j << "\n";
  1495. //we are beginning a empty space
  1496. active_tail_arbitrary* holep = 0;
  1497. //if(c_size && counts[c_size_less_1] == 0 &&
  1498. // counts_from_scanline[c_size_less_1].first.first.first.get(HORIZONTAL) == point.get(HORIZONTAL))
  1499. if(have_vertical_tail_from_below) {
  1500. holep = tails[c_size_less_1];
  1501. tails[c_size_less_1] = 0;
  1502. have_vertical_tail_from_below = false;
  1503. }
  1504. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
  1505. active_tail_arbitrary::createActiveTailsAsPair(point, false, holep, fractureHoles_ != 0);
  1506. if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  1507. //std::cout << "vertical element " << point << "\n";
  1508. returnValue = tailPair.first;
  1509. returnCount.first = point;
  1510. //returnCount = incoming_count[j];
  1511. returnCount.second = -1;
  1512. } else {
  1513. //std::cout << "new element " << j-1 << " " << incoming[j] << "\n";
  1514. //std::cout << point << " " << incoming_count[j].first << "\n";
  1515. elements.push_back(std::pair<vertex_half_edge,
  1516. active_tail_arbitrary*>(vertex_half_edge(point,
  1517. incoming_count[j].first, incoming[j]), tailPair.first));
  1518. }
  1519. //std::cout << "new element " << i-1 << " " << incoming[i] << "\n";
  1520. //std::cout << point << " " << incoming_count[i].first << "\n";
  1521. elements.push_back(std::pair<vertex_half_edge,
  1522. active_tail_arbitrary*>(vertex_half_edge(point,
  1523. incoming_count[i].first, incoming[i]), tailPair.second));
  1524. incoming[i] = 0;
  1525. incoming[j] = 0;
  1526. break;
  1527. }
  1528. }
  1529. break;
  1530. }
  1531. }
  1532. }
  1533. if(have_vertical_tail_from_below) {
  1534. if(tails.back()) {
  1535. tails.back()->pushPoint(point);
  1536. returnValue = tails.back();
  1537. returnCount.first = point;
  1538. returnCount.second = counts.back();
  1539. }
  1540. }
  1541. //assert that tails, counts and incoming are all null
  1542. return std::pair<std::pair<Point, int>, active_tail_arbitrary*>(returnCount, returnValue);
  1543. }
  1544. static inline void print(const vertex_arbitrary_count& count) {
  1545. for(unsigned i = 0; i < count.size(); ++i) {
  1546. //std::cout << count[i].first.get(HORIZONTAL) << ",";
  1547. //std::cout << count[i].first.get(VERTICAL) << ":";
  1548. //std::cout << count[i].second << " ";
  1549. } //std::cout << "\n";
  1550. }
  1551. static inline void print(const scanline_data& data) {
  1552. for(typename scanline_data::const_iterator itr = data.begin(); itr != data.end(); ++itr){
  1553. //std::cout << itr->first.pt << ", " << itr->first.other_pt << "; ";
  1554. } //std::cout << "\n";
  1555. }
  1556. template <class cT, class iT>
  1557. inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
  1558. typedef typename high_precision_type<Unit>::type high_precision;
  1559. //std::cout << "processEvent_\n";
  1560. justBefore_ = true;
  1561. //collect up all elements from the tree that are at the y
  1562. //values of events in the input queue
  1563. //create vector of new elements to add into tree
  1564. active_tail_arbitrary* verticalTail = 0;
  1565. std::pair<Point, int> verticalCount(Point(0, 0), 0);
  1566. iT currentIter = inputBegin;
  1567. std::vector<iterator> elementIters;
  1568. std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> > elements;
  1569. while(currentIter != inputEnd && currentIter->pt.get(HORIZONTAL) == x_) {
  1570. //std::cout << "loop\n";
  1571. Unit currentY = (*currentIter).pt.get(VERTICAL);
  1572. //std::cout << "current Y " << currentY << "\n";
  1573. //std::cout << "scanline size " << scanData_.size() << "\n";
  1574. //print(scanData_);
  1575. iterator iter = lookUp_(currentY);
  1576. //std::cout << "found element in scanline " << (iter != scanData_.end()) << "\n";
  1577. //int counts[4] = {0, 0, 0, 0};
  1578. incoming_count counts_from_scanline;
  1579. //std::cout << "finding elements in tree\n";
  1580. //if(iter != scanData_.end())
  1581. // std::cout << "first iter y is " << iter->first.evalAtX(x_) << "\n";
  1582. while(iter != scanData_.end() &&
  1583. ((iter->first.pt.x() == x_ && iter->first.pt.y() == currentY) ||
  1584. (iter->first.other_pt.x() == x_ && iter->first.other_pt.y() == currentY))) {
  1585. //iter->first.evalAtX(x_) == (high_precision)currentY) {
  1586. //std::cout << "loop2\n";
  1587. elementIters.push_back(iter);
  1588. counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>
  1589. (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(iter->first.pt,
  1590. iter->first.other_pt),
  1591. iter->first.count),
  1592. iter->second));
  1593. ++iter;
  1594. }
  1595. Point currentPoint(x_, currentY);
  1596. //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << "\n";
  1597. sort_incoming_count(counts_from_scanline, currentPoint);
  1598. vertex_arbitrary_count incoming;
  1599. //std::cout << "aggregating\n";
  1600. do {
  1601. //std::cout << "loop3\n";
  1602. const vertex_half_edge& elem = *currentIter;
  1603. incoming.push_back(std::pair<Point, int>(elem.other_pt, elem.count));
  1604. ++currentIter;
  1605. } while(currentIter != inputEnd && currentIter->pt.get(VERTICAL) == currentY &&
  1606. currentIter->pt.get(HORIZONTAL) == x_);
  1607. //print(incoming);
  1608. sort_vertex_arbitrary_count(incoming, currentPoint);
  1609. //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << "\n";
  1610. //print(incoming);
  1611. //std::cout << "incoming counts from input size " << incoming.size() << "\n";
  1612. //compact_vertex_arbitrary_count(currentPoint, incoming);
  1613. vertex_arbitrary_count tmp;
  1614. tmp.reserve(incoming.size());
  1615. for(std::size_t i = 0; i < incoming.size(); ++i) {
  1616. if(currentPoint < incoming[i].first) {
  1617. tmp.push_back(incoming[i]);
  1618. }
  1619. }
  1620. incoming.swap(tmp);
  1621. //std::cout << "incoming counts from input size " << incoming.size() << "\n";
  1622. //now counts_from_scanline has the data from the left and
  1623. //incoming has the data from the right at this point
  1624. //cancel out any end points
  1625. if(verticalTail) {
  1626. //std::cout << "adding vertical tail to counts from scanline\n";
  1627. //std::cout << -verticalCount.second << "\n";
  1628. counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>
  1629. (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(verticalCount.first,
  1630. currentPoint),
  1631. -verticalCount.second),
  1632. verticalTail));
  1633. }
  1634. if(!incoming.empty() && incoming.back().first.get(HORIZONTAL) == x_) {
  1635. //std::cout << "inverted vertical event\n";
  1636. incoming.back().second *= -1;
  1637. }
  1638. //std::cout << "calling processPoint_\n";
  1639. std::pair<std::pair<Point, int>, active_tail_arbitrary*> result = processPoint_(output, elements, Point(x_, currentY), counts_from_scanline, incoming);
  1640. verticalCount = result.first;
  1641. verticalTail = result.second;
  1642. //if(verticalTail) {
  1643. // std::cout << "have vertical tail\n";
  1644. // std::cout << verticalCount.second << "\n";
  1645. //}
  1646. if(verticalTail && !(verticalCount.second)) {
  1647. //we got a hole out of the point we just processed
  1648. //iter is still at the next y element above the current y value in the tree
  1649. //std::cout << "checking whether ot handle hole\n";
  1650. if(currentIter == inputEnd ||
  1651. currentIter->pt.get(HORIZONTAL) != x_ ||
  1652. scanline_base<Unit>::on_above_or_below(currentIter->pt, half_edge(iter->first.pt, iter->first.other_pt)) != -1) {
  1653. //(high_precision)(currentIter->pt.get(VERTICAL)) >= iter->first.evalAtX(x_)) {
  1654. //std::cout << "handle hole here\n";
  1655. if(fractureHoles_) {
  1656. //std::cout << "fracture hole here\n";
  1657. //we need to handle the hole now and not at the next input vertex
  1658. active_tail_arbitrary* at = iter->second;
  1659. high_precision precise_y = iter->first.evalAtX(x_);
  1660. Unit fracture_y = convert_high_precision_type<Unit>(precise_y);
  1661. if(precise_y < fracture_y) --fracture_y;
  1662. Point point(x_, fracture_y);
  1663. verticalTail->getOtherActiveTail()->pushPoint(point);
  1664. iter->second = verticalTail->getOtherActiveTail();
  1665. at->pushPoint(point);
  1666. verticalTail->join(at);
  1667. delete at;
  1668. delete verticalTail;
  1669. verticalTail = 0;
  1670. } else {
  1671. //std::cout << "push hole onto list\n";
  1672. iter->second->addHole(verticalTail);
  1673. verticalTail = 0;
  1674. }
  1675. }
  1676. }
  1677. }
  1678. //std::cout << "erasing\n";
  1679. //erase all elements from the tree
  1680. for(typename std::vector<iterator>::iterator iter = elementIters.begin();
  1681. iter != elementIters.end(); ++iter) {
  1682. //std::cout << "erasing loop\n";
  1683. scanData_.erase(*iter);
  1684. }
  1685. //switch comparison tie breaking policy
  1686. justBefore_ = false;
  1687. //add new elements into tree
  1688. //std::cout << "inserting\n";
  1689. for(typename std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> >::iterator iter = elements.begin();
  1690. iter != elements.end(); ++iter) {
  1691. //std::cout << "inserting loop\n";
  1692. scanData_.insert(scanData_.end(), *iter);
  1693. }
  1694. //std::cout << "end processEvent\n";
  1695. return currentIter;
  1696. }
  1697. inline iterator lookUp_(Unit y){
  1698. //if just before then we need to look from 1 not -1
  1699. //std::cout << "just before " << justBefore_ << "\n";
  1700. return scanData_.lower_bound(vertex_half_edge(Point(x_, y), Point(x_, y+1), 0));
  1701. }
  1702. public: //test functions
  1703. template <typename stream_type>
  1704. static inline bool testPolygonArbitraryFormationRect(stream_type& stdcout) {
  1705. stdcout << "testing polygon formation\n";
  1706. polygon_arbitrary_formation pf(true);
  1707. std::vector<polygon_data<Unit> > polys;
  1708. std::vector<vertex_half_edge> data;
  1709. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1));
  1710. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  1711. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  1712. data.push_back(vertex_half_edge(Point(0, 10), Point(10, 10), -1));
  1713. data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1));
  1714. data.push_back(vertex_half_edge(Point(10, 0), Point(10, 10), -1));
  1715. data.push_back(vertex_half_edge(Point(10, 10), Point(10, 0), 1));
  1716. data.push_back(vertex_half_edge(Point(10, 10), Point(0, 10), 1));
  1717. polygon_sort(data.begin(), data.end());
  1718. pf.scan(polys, data.begin(), data.end());
  1719. stdcout << "result size: " << polys.size() << "\n";
  1720. for(std::size_t i = 0; i < polys.size(); ++i) {
  1721. stdcout << polys[i] << "\n";
  1722. }
  1723. stdcout << "done testing polygon formation\n";
  1724. return true;
  1725. }
  1726. template <typename stream_type>
  1727. static inline bool testPolygonArbitraryFormationP1(stream_type& stdcout) {
  1728. stdcout << "testing polygon formation P1\n";
  1729. polygon_arbitrary_formation pf(true);
  1730. std::vector<polygon_data<Unit> > polys;
  1731. std::vector<vertex_half_edge> data;
  1732. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 10), 1));
  1733. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  1734. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  1735. data.push_back(vertex_half_edge(Point(0, 10), Point(10, 20), -1));
  1736. data.push_back(vertex_half_edge(Point(10, 10), Point(0, 0), -1));
  1737. data.push_back(vertex_half_edge(Point(10, 10), Point(10, 20), -1));
  1738. data.push_back(vertex_half_edge(Point(10, 20), Point(10, 10), 1));
  1739. data.push_back(vertex_half_edge(Point(10, 20), Point(0, 10), 1));
  1740. polygon_sort(data.begin(), data.end());
  1741. pf.scan(polys, data.begin(), data.end());
  1742. stdcout << "result size: " << polys.size() << "\n";
  1743. for(std::size_t i = 0; i < polys.size(); ++i) {
  1744. stdcout << polys[i] << "\n";
  1745. }
  1746. stdcout << "done testing polygon formation\n";
  1747. return true;
  1748. }
  1749. template <typename stream_type>
  1750. static inline bool testPolygonArbitraryFormationP2(stream_type& stdcout) {
  1751. stdcout << "testing polygon formation P2\n";
  1752. polygon_arbitrary_formation pf(true);
  1753. std::vector<polygon_data<Unit> > polys;
  1754. std::vector<vertex_half_edge> data;
  1755. data.push_back(vertex_half_edge(Point(-3, 1), Point(2, -4), 1));
  1756. data.push_back(vertex_half_edge(Point(-3, 1), Point(-2, 2), -1));
  1757. data.push_back(vertex_half_edge(Point(-2, 2), Point(2, 4), -1));
  1758. data.push_back(vertex_half_edge(Point(-2, 2), Point(-3, 1), 1));
  1759. data.push_back(vertex_half_edge(Point(2, -4), Point(-3, 1), -1));
  1760. data.push_back(vertex_half_edge(Point(2, -4), Point(2, 4), -1));
  1761. data.push_back(vertex_half_edge(Point(2, 4), Point(-2, 2), 1));
  1762. data.push_back(vertex_half_edge(Point(2, 4), Point(2, -4), 1));
  1763. polygon_sort(data.begin(), data.end());
  1764. pf.scan(polys, data.begin(), data.end());
  1765. stdcout << "result size: " << polys.size() << "\n";
  1766. for(std::size_t i = 0; i < polys.size(); ++i) {
  1767. stdcout << polys[i] << "\n";
  1768. }
  1769. stdcout << "done testing polygon formation\n";
  1770. return true;
  1771. }
  1772. template <typename stream_type>
  1773. static inline bool testPolygonArbitraryFormationPolys(stream_type& stdcout) {
  1774. stdcout << "testing polygon formation polys\n";
  1775. polygon_arbitrary_formation pf(false);
  1776. std::vector<polygon_with_holes_data<Unit> > polys;
  1777. polygon_arbitrary_formation pf2(true);
  1778. std::vector<polygon_with_holes_data<Unit> > polys2;
  1779. std::vector<vertex_half_edge> data;
  1780. data.push_back(vertex_half_edge(Point(0, 0), Point(100, 1), 1));
  1781. data.push_back(vertex_half_edge(Point(0, 0), Point(1, 100), -1));
  1782. data.push_back(vertex_half_edge(Point(1, 100), Point(0, 0), 1));
  1783. data.push_back(vertex_half_edge(Point(1, 100), Point(101, 101), -1));
  1784. data.push_back(vertex_half_edge(Point(100, 1), Point(0, 0), -1));
  1785. data.push_back(vertex_half_edge(Point(100, 1), Point(101, 101), 1));
  1786. data.push_back(vertex_half_edge(Point(101, 101), Point(100, 1), -1));
  1787. data.push_back(vertex_half_edge(Point(101, 101), Point(1, 100), 1));
  1788. data.push_back(vertex_half_edge(Point(2, 2), Point(10, 2), -1));
  1789. data.push_back(vertex_half_edge(Point(2, 2), Point(2, 10), -1));
  1790. data.push_back(vertex_half_edge(Point(2, 10), Point(2, 2), 1));
  1791. data.push_back(vertex_half_edge(Point(2, 10), Point(10, 10), 1));
  1792. data.push_back(vertex_half_edge(Point(10, 2), Point(2, 2), 1));
  1793. data.push_back(vertex_half_edge(Point(10, 2), Point(10, 10), 1));
  1794. data.push_back(vertex_half_edge(Point(10, 10), Point(10, 2), -1));
  1795. data.push_back(vertex_half_edge(Point(10, 10), Point(2, 10), -1));
  1796. data.push_back(vertex_half_edge(Point(2, 12), Point(10, 12), -1));
  1797. data.push_back(vertex_half_edge(Point(2, 12), Point(2, 22), -1));
  1798. data.push_back(vertex_half_edge(Point(2, 22), Point(2, 12), 1));
  1799. data.push_back(vertex_half_edge(Point(2, 22), Point(10, 22), 1));
  1800. data.push_back(vertex_half_edge(Point(10, 12), Point(2, 12), 1));
  1801. data.push_back(vertex_half_edge(Point(10, 12), Point(10, 22), 1));
  1802. data.push_back(vertex_half_edge(Point(10, 22), Point(10, 12), -1));
  1803. data.push_back(vertex_half_edge(Point(10, 22), Point(2, 22), -1));
  1804. polygon_sort(data.begin(), data.end());
  1805. pf.scan(polys, data.begin(), data.end());
  1806. stdcout << "result size: " << polys.size() << "\n";
  1807. for(std::size_t i = 0; i < polys.size(); ++i) {
  1808. stdcout << polys[i] << "\n";
  1809. }
  1810. pf2.scan(polys2, data.begin(), data.end());
  1811. stdcout << "result size: " << polys2.size() << "\n";
  1812. for(std::size_t i = 0; i < polys2.size(); ++i) {
  1813. stdcout << polys2[i] << "\n";
  1814. }
  1815. stdcout << "done testing polygon formation\n";
  1816. return true;
  1817. }
  1818. template <typename stream_type>
  1819. static inline bool testPolygonArbitraryFormationSelfTouch1(stream_type& stdcout) {
  1820. stdcout << "testing polygon formation self touch 1\n";
  1821. polygon_arbitrary_formation pf(true);
  1822. std::vector<polygon_data<Unit> > polys;
  1823. std::vector<vertex_half_edge> data;
  1824. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1));
  1825. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  1826. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  1827. data.push_back(vertex_half_edge(Point(0, 10), Point(5, 10), -1));
  1828. data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1));
  1829. data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1));
  1830. data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1));
  1831. data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1));
  1832. data.push_back(vertex_half_edge(Point(5, 10), Point(5, 5), 1));
  1833. data.push_back(vertex_half_edge(Point(5, 10), Point(0, 10), 1));
  1834. data.push_back(vertex_half_edge(Point(5, 2), Point(5, 5), -1));
  1835. data.push_back(vertex_half_edge(Point(5, 2), Point(7, 2), -1));
  1836. data.push_back(vertex_half_edge(Point(5, 5), Point(5, 10), -1));
  1837. data.push_back(vertex_half_edge(Point(5, 5), Point(5, 2), 1));
  1838. data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1));
  1839. data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1));
  1840. data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1));
  1841. data.push_back(vertex_half_edge(Point(7, 2), Point(5, 2), 1));
  1842. polygon_sort(data.begin(), data.end());
  1843. pf.scan(polys, data.begin(), data.end());
  1844. stdcout << "result size: " << polys.size() << "\n";
  1845. for(std::size_t i = 0; i < polys.size(); ++i) {
  1846. stdcout << polys[i] << "\n";
  1847. }
  1848. stdcout << "done testing polygon formation\n";
  1849. return true;
  1850. }
  1851. template <typename stream_type>
  1852. static inline bool testPolygonArbitraryFormationSelfTouch2(stream_type& stdcout) {
  1853. stdcout << "testing polygon formation self touch 2\n";
  1854. polygon_arbitrary_formation pf(true);
  1855. std::vector<polygon_data<Unit> > polys;
  1856. std::vector<vertex_half_edge> data;
  1857. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1));
  1858. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  1859. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  1860. data.push_back(vertex_half_edge(Point(0, 10), Point(5, 10), -1));
  1861. data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1));
  1862. data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1));
  1863. data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1));
  1864. data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1));
  1865. data.push_back(vertex_half_edge(Point(5, 10), Point(4, 1), -1));
  1866. data.push_back(vertex_half_edge(Point(5, 10), Point(0, 10), 1));
  1867. data.push_back(vertex_half_edge(Point(4, 1), Point(5, 10), 1));
  1868. data.push_back(vertex_half_edge(Point(4, 1), Point(7, 2), -1));
  1869. data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1));
  1870. data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1));
  1871. data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1));
  1872. data.push_back(vertex_half_edge(Point(7, 2), Point(4, 1), 1));
  1873. polygon_sort(data.begin(), data.end());
  1874. pf.scan(polys, data.begin(), data.end());
  1875. stdcout << "result size: " << polys.size() << "\n";
  1876. for(std::size_t i = 0; i < polys.size(); ++i) {
  1877. stdcout << polys[i] << "\n";
  1878. }
  1879. stdcout << "done testing polygon formation\n";
  1880. return true;
  1881. }
  1882. template <typename stream_type>
  1883. static inline bool testPolygonArbitraryFormationSelfTouch3(stream_type& stdcout) {
  1884. stdcout << "testing polygon formation self touch 3\n";
  1885. polygon_arbitrary_formation pf(true);
  1886. std::vector<polygon_data<Unit> > polys;
  1887. std::vector<vertex_half_edge> data;
  1888. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1));
  1889. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  1890. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  1891. data.push_back(vertex_half_edge(Point(0, 10), Point(6, 10), -1));
  1892. data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1));
  1893. data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1));
  1894. data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1));
  1895. data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1));
  1896. data.push_back(vertex_half_edge(Point(6, 10), Point(4, 1), -1));
  1897. data.push_back(vertex_half_edge(Point(6, 10), Point(0, 10), 1));
  1898. data.push_back(vertex_half_edge(Point(4, 1), Point(6, 10), 1));
  1899. data.push_back(vertex_half_edge(Point(4, 1), Point(7, 2), -1));
  1900. data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1));
  1901. data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1));
  1902. data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1));
  1903. data.push_back(vertex_half_edge(Point(7, 2), Point(4, 1), 1));
  1904. polygon_sort(data.begin(), data.end());
  1905. pf.scan(polys, data.begin(), data.end());
  1906. stdcout << "result size: " << polys.size() << "\n";
  1907. for(std::size_t i = 0; i < polys.size(); ++i) {
  1908. stdcout << polys[i] << "\n";
  1909. }
  1910. stdcout << "done testing polygon formation\n";
  1911. return true;
  1912. }
  1913. template <typename stream_type>
  1914. static inline bool testPolygonArbitraryFormationColinear(stream_type& stdcout) {
  1915. stdcout << "testing polygon formation colinear 3\n";
  1916. stdcout << "Polygon Set Data { <-3 2, -2 2>:1 <-3 2, -1 4>:-1 <-2 2, 0 2>:1 <-1 4, 0 2>:-1 } \n";
  1917. polygon_arbitrary_formation pf(true);
  1918. std::vector<polygon_data<Unit> > polys;
  1919. std::vector<vertex_half_edge> data;
  1920. data.push_back(vertex_half_edge(Point(-3, 2), Point(-2, 2), 1));
  1921. data.push_back(vertex_half_edge(Point(-2, 2), Point(-3, 2), -1));
  1922. data.push_back(vertex_half_edge(Point(-3, 2), Point(-1, 4), -1));
  1923. data.push_back(vertex_half_edge(Point(-1, 4), Point(-3, 2), 1));
  1924. data.push_back(vertex_half_edge(Point(-2, 2), Point(0, 2), 1));
  1925. data.push_back(vertex_half_edge(Point(0, 2), Point(-2, 2), -1));
  1926. data.push_back(vertex_half_edge(Point(-1, 4), Point(0, 2), -1));
  1927. data.push_back(vertex_half_edge(Point(0, 2), Point(-1, 4), 1));
  1928. polygon_sort(data.begin(), data.end());
  1929. pf.scan(polys, data.begin(), data.end());
  1930. stdcout << "result size: " << polys.size() << "\n";
  1931. for(std::size_t i = 0; i < polys.size(); ++i) {
  1932. stdcout << polys[i] << "\n";
  1933. }
  1934. stdcout << "done testing polygon formation\n";
  1935. return true;
  1936. }
  1937. template <typename stream_type>
  1938. static inline bool testSegmentIntersection(stream_type& stdcout) {
  1939. stdcout << "testing segment intersection\n";
  1940. half_edge he1, he2;
  1941. he1.first = Point(0, 0);
  1942. he1.second = Point(10, 10);
  1943. he2.first = Point(0, 0);
  1944. he2.second = Point(10, 20);
  1945. Point result;
  1946. bool b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1947. if(!b || result != Point(0, 0)) return false;
  1948. he1.first = Point(0, 10);
  1949. b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1950. if(!b || result != Point(5, 10)) return false;
  1951. he1.first = Point(0, 11);
  1952. b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1953. if(!b || result != Point(5, 10)) return false;
  1954. he1.first = Point(0, 0);
  1955. he1.second = Point(1, 9);
  1956. he2.first = Point(0, 9);
  1957. he2.second = Point(1, 0);
  1958. b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1959. if(!b || result != Point(0, 4)) return false;
  1960. he1.first = Point(0, -10);
  1961. he1.second = Point(1, -1);
  1962. he2.first = Point(0, -1);
  1963. he2.second = Point(1, -10);
  1964. b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1965. if(!b || result != Point(0, -5)) return false;
  1966. he1.first = Point((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::max)()-1);
  1967. he1.second = Point((std::numeric_limits<int>::min)(), (std::numeric_limits<int>::max)());
  1968. //he1.second = Point(0, (std::numeric_limits<int>::max)());
  1969. he2.first = Point((std::numeric_limits<int>::max)()-1, (std::numeric_limits<int>::max)());
  1970. he2.second = Point((std::numeric_limits<int>::max)(), (std::numeric_limits<int>::min)());
  1971. //he2.second = Point((std::numeric_limits<int>::max)(), 0);
  1972. b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1973. //b is false because of overflow error
  1974. he1.first = Point(1000, 2000);
  1975. he1.second = Point(1010, 2010);
  1976. he2.first = Point(1000, 2000);
  1977. he2.second = Point(1010, 2020);
  1978. b = scanline_base<Unit>::compute_intersection(result, he1, he2);
  1979. if(!b || result != Point(1000, 2000)) return false;
  1980. return b;
  1981. }
  1982. };
  1983. template <typename Unit>
  1984. class poly_line_arbitrary_hole_data {
  1985. private:
  1986. typedef typename polygon_arbitrary_formation<Unit>::active_tail_arbitrary active_tail_arbitrary;
  1987. active_tail_arbitrary* p_;
  1988. public:
  1989. typedef point_data<Unit> Point;
  1990. typedef Point point_type;
  1991. typedef Unit coordinate_type;
  1992. typedef typename active_tail_arbitrary::iterator iterator_type;
  1993. //typedef iterator_points_to_compact<iterator_type, Point> compact_iterator_type;
  1994. typedef iterator_type iterator;
  1995. inline poly_line_arbitrary_hole_data() : p_(0) {}
  1996. inline poly_line_arbitrary_hole_data(active_tail_arbitrary* p) : p_(p) {}
  1997. //use default copy and assign
  1998. inline iterator begin() const { return p_->getTail()->begin(); }
  1999. inline iterator end() const { return p_->getTail()->end(); }
  2000. inline std::size_t size() const { return 0; }
  2001. };
  2002. template <typename Unit>
  2003. class poly_line_arbitrary_polygon_data {
  2004. private:
  2005. typedef typename polygon_arbitrary_formation<Unit>::active_tail_arbitrary active_tail_arbitrary;
  2006. active_tail_arbitrary* p_;
  2007. public:
  2008. typedef point_data<Unit> Point;
  2009. typedef Point point_type;
  2010. typedef Unit coordinate_type;
  2011. typedef typename active_tail_arbitrary::iterator iterator_type;
  2012. //typedef iterator_points_to_compact<iterator_type, Point> compact_iterator_type;
  2013. typedef typename coordinate_traits<Unit>::coordinate_distance area_type;
  2014. class iterator_holes_type {
  2015. private:
  2016. typedef poly_line_arbitrary_hole_data<Unit> holeType;
  2017. mutable holeType hole_;
  2018. typename active_tail_arbitrary::iteratorHoles itr_;
  2019. public:
  2020. typedef std::forward_iterator_tag iterator_category;
  2021. typedef holeType value_type;
  2022. typedef std::ptrdiff_t difference_type;
  2023. typedef const holeType* pointer; //immutable
  2024. typedef const holeType& reference; //immutable
  2025. inline iterator_holes_type() : hole_(), itr_() {}
  2026. inline iterator_holes_type(typename active_tail_arbitrary::iteratorHoles itr) : hole_(), itr_(itr) {}
  2027. inline iterator_holes_type(const iterator_holes_type& that) : hole_(that.hole_), itr_(that.itr_) {}
  2028. inline iterator_holes_type& operator=(const iterator_holes_type& that) {
  2029. itr_ = that.itr_;
  2030. return *this;
  2031. }
  2032. inline bool operator==(const iterator_holes_type& that) { return itr_ == that.itr_; }
  2033. inline bool operator!=(const iterator_holes_type& that) { return itr_ != that.itr_; }
  2034. inline iterator_holes_type& operator++() {
  2035. ++itr_;
  2036. return *this;
  2037. }
  2038. inline const iterator_holes_type operator++(int) {
  2039. iterator_holes_type tmp = *this;
  2040. ++(*this);
  2041. return tmp;
  2042. }
  2043. inline reference operator*() {
  2044. hole_ = holeType(*itr_);
  2045. return hole_;
  2046. }
  2047. };
  2048. typedef poly_line_arbitrary_hole_data<Unit> hole_type;
  2049. inline poly_line_arbitrary_polygon_data() : p_(0) {}
  2050. inline poly_line_arbitrary_polygon_data(active_tail_arbitrary* p) : p_(p) {}
  2051. //use default copy and assign
  2052. inline iterator_type begin() const { return p_->getTail()->begin(); }
  2053. inline iterator_type end() const { return p_->getTail()->end(); }
  2054. //inline compact_iterator_type begin_compact() const { return p_->getTail()->begin(); }
  2055. //inline compact_iterator_type end_compact() const { return p_->getTail()->end(); }
  2056. inline iterator_holes_type begin_holes() const { return iterator_holes_type(p_->getHoles().begin()); }
  2057. inline iterator_holes_type end_holes() const { return iterator_holes_type(p_->getHoles().end()); }
  2058. inline active_tail_arbitrary* yield() { return p_; }
  2059. //stub out these four required functions that will not be used but are needed for the interface
  2060. inline std::size_t size_holes() const { return 0; }
  2061. inline std::size_t size() const { return 0; }
  2062. };
  2063. template <typename Unit>
  2064. class trapezoid_arbitrary_formation : public polygon_arbitrary_formation<Unit> {
  2065. private:
  2066. typedef typename scanline_base<Unit>::Point Point;
  2067. typedef typename scanline_base<Unit>::half_edge half_edge;
  2068. typedef typename scanline_base<Unit>::vertex_half_edge vertex_half_edge;
  2069. typedef typename scanline_base<Unit>::less_vertex_half_edge less_vertex_half_edge;
  2070. typedef typename polygon_arbitrary_formation<Unit>::poly_line_arbitrary poly_line_arbitrary;
  2071. typedef typename polygon_arbitrary_formation<Unit>::active_tail_arbitrary active_tail_arbitrary;
  2072. typedef std::vector<std::pair<Point, int> > vertex_arbitrary_count;
  2073. typedef typename polygon_arbitrary_formation<Unit>::less_half_edge_count less_half_edge_count;
  2074. typedef std::vector<std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*> > incoming_count;
  2075. typedef typename polygon_arbitrary_formation<Unit>::less_incoming_count less_incoming_count;
  2076. typedef typename polygon_arbitrary_formation<Unit>::vertex_arbitrary_compact vertex_arbitrary_compact;
  2077. private:
  2078. //definitions
  2079. typedef std::map<vertex_half_edge, active_tail_arbitrary*, less_vertex_half_edge> scanline_data;
  2080. typedef typename scanline_data::iterator iterator;
  2081. typedef typename scanline_data::const_iterator const_iterator;
  2082. //data
  2083. public:
  2084. inline trapezoid_arbitrary_formation() : polygon_arbitrary_formation<Unit>() {}
  2085. inline trapezoid_arbitrary_formation(const trapezoid_arbitrary_formation& that) : polygon_arbitrary_formation<Unit>(that) {}
  2086. inline trapezoid_arbitrary_formation& operator=(const trapezoid_arbitrary_formation& that) {
  2087. * static_cast<polygon_arbitrary_formation<Unit>*>(this) = * static_cast<polygon_arbitrary_formation<Unit>*>(&that);
  2088. return *this;
  2089. }
  2090. //cT is an output container of Polygon45 or Polygon45WithHoles
  2091. //iT is an iterator over vertex_half_edge elements
  2092. //inputBegin - inputEnd is a range of sorted iT that represents
  2093. //one or more scanline stops worth of data
  2094. template <class cT, class iT>
  2095. void scan(cT& output, iT inputBegin, iT inputEnd) {
  2096. //std::cout << "1\n";
  2097. while(inputBegin != inputEnd) {
  2098. //std::cout << "2\n";
  2099. polygon_arbitrary_formation<Unit>::x_ = (*inputBegin).pt.get(HORIZONTAL);
  2100. //std::cout << "SCAN FORMATION " << x_ << "\n";
  2101. //std::cout << "x_ = " << x_ << "\n";
  2102. //std::cout << "scan line size: " << scanData_.size() << "\n";
  2103. inputBegin = processEvent_(output, inputBegin, inputEnd);
  2104. }
  2105. //std::cout << "scan line size: " << scanData_.size() << "\n";
  2106. }
  2107. private:
  2108. //functions
  2109. inline void getVerticalPair_(std::pair<active_tail_arbitrary*,
  2110. active_tail_arbitrary*>& verticalPair,
  2111. iterator previter) {
  2112. active_tail_arbitrary* iterTail = (*previter).second;
  2113. Point prevPoint(polygon_arbitrary_formation<Unit>::x_,
  2114. convert_high_precision_type<Unit>(previter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_)));
  2115. iterTail->pushPoint(prevPoint);
  2116. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
  2117. active_tail_arbitrary::createActiveTailsAsPair(prevPoint, true, 0, false);
  2118. verticalPair.first = iterTail;
  2119. verticalPair.second = tailPair.first;
  2120. (*previter).second = tailPair.second;
  2121. }
  2122. template <class cT, class cT2>
  2123. inline std::pair<std::pair<Point, int>, active_tail_arbitrary*>
  2124. processPoint_(cT& output, cT2& elements,
  2125. std::pair<active_tail_arbitrary*, active_tail_arbitrary*>& verticalPair,
  2126. iterator previter, Point point, incoming_count& counts_from_scanline,
  2127. vertex_arbitrary_count& incoming_count) {
  2128. //std::cout << "\nAT POINT: " << point << "\n";
  2129. //join any closing solid corners
  2130. std::vector<int> counts;
  2131. std::vector<int> incoming;
  2132. std::vector<active_tail_arbitrary*> tails;
  2133. counts.reserve(counts_from_scanline.size());
  2134. tails.reserve(counts_from_scanline.size());
  2135. incoming.reserve(incoming_count.size());
  2136. for(std::size_t i = 0; i < counts_from_scanline.size(); ++i) {
  2137. counts.push_back(counts_from_scanline[i].first.second);
  2138. tails.push_back(counts_from_scanline[i].second);
  2139. }
  2140. for(std::size_t i = 0; i < incoming_count.size(); ++i) {
  2141. incoming.push_back(incoming_count[i].second);
  2142. if(incoming_count[i].first < point) {
  2143. incoming.back() = 0;
  2144. }
  2145. }
  2146. active_tail_arbitrary* returnValue = 0;
  2147. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> verticalPairOut;
  2148. verticalPairOut.first = 0;
  2149. verticalPairOut.second = 0;
  2150. std::pair<Point, int> returnCount(Point(0, 0), 0);
  2151. int i_size_less_1 = (int)(incoming.size()) -1;
  2152. int c_size_less_1 = (int)(counts.size()) -1;
  2153. int i_size = incoming.size();
  2154. int c_size = counts.size();
  2155. bool have_vertical_tail_from_below = false;
  2156. if(c_size &&
  2157. scanline_base<Unit>::is_vertical(counts_from_scanline.back().first.first)) {
  2158. have_vertical_tail_from_below = true;
  2159. }
  2160. //assert size = size_less_1 + 1
  2161. //std::cout << tails.size() << " " << incoming.size() << " " << counts_from_scanline.size() << " " << incoming_count.size() << "\n";
  2162. // for(std::size_t i = 0; i < counts.size(); ++i) {
  2163. // std::cout << counts_from_scanline[i].first.first.first.get(HORIZONTAL) << ",";
  2164. // std::cout << counts_from_scanline[i].first.first.first.get(VERTICAL) << " ";
  2165. // std::cout << counts_from_scanline[i].first.first.second.get(HORIZONTAL) << ",";
  2166. // std::cout << counts_from_scanline[i].first.first.second.get(VERTICAL) << ":";
  2167. // std::cout << counts_from_scanline[i].first.second << " ";
  2168. // } std::cout << "\n";
  2169. // print(incoming_count);
  2170. {
  2171. for(int i = 0; i < c_size_less_1; ++i) {
  2172. //std::cout << i << "\n";
  2173. if(counts[i] == -1) {
  2174. //std::cout << "fixed i\n";
  2175. for(int j = i + 1; j < c_size; ++j) {
  2176. //std::cout << j << "\n";
  2177. if(counts[j]) {
  2178. if(counts[j] == 1) {
  2179. //std::cout << "case1: " << i << " " << j << "\n";
  2180. //if a figure is closed it will be written out by this function to output
  2181. active_tail_arbitrary::joinChains(point, tails[i], tails[j], true, output);
  2182. counts[i] = 0;
  2183. counts[j] = 0;
  2184. tails[i] = 0;
  2185. tails[j] = 0;
  2186. }
  2187. break;
  2188. }
  2189. }
  2190. }
  2191. }
  2192. }
  2193. //find any pairs of incoming edges that need to create pair for leading solid
  2194. //std::cout << "checking case2\n";
  2195. {
  2196. for(int i = 0; i < i_size_less_1; ++i) {
  2197. //std::cout << i << "\n";
  2198. if(incoming[i] == 1) {
  2199. //std::cout << "fixed i\n";
  2200. for(int j = i + 1; j < i_size; ++j) {
  2201. //std::cout << j << "\n";
  2202. if(incoming[j]) {
  2203. //std::cout << incoming[j] << "\n";
  2204. if(incoming[j] == -1) {
  2205. //std::cout << "case2: " << i << " " << j << "\n";
  2206. //std::cout << "creating active tail pair\n";
  2207. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
  2208. active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, polygon_arbitrary_formation<Unit>::fractureHoles_ != 0);
  2209. //tailPair.first->print();
  2210. //tailPair.second->print();
  2211. if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  2212. //vertical active tail becomes return value
  2213. returnValue = tailPair.first;
  2214. returnCount.first = point;
  2215. returnCount.second = 1;
  2216. } else {
  2217. //std::cout << "new element " << j-1 << " " << -1 << "\n";
  2218. //std::cout << point << " " << incoming_count[j].first << "\n";
  2219. elements.push_back(std::pair<vertex_half_edge,
  2220. active_tail_arbitrary*>(vertex_half_edge(point,
  2221. incoming_count[j].first, -1), tailPair.first));
  2222. }
  2223. //std::cout << "new element " << i-1 << " " << 1 << "\n";
  2224. //std::cout << point << " " << incoming_count[i].first << "\n";
  2225. elements.push_back(std::pair<vertex_half_edge,
  2226. active_tail_arbitrary*>(vertex_half_edge(point,
  2227. incoming_count[i].first, 1), tailPair.second));
  2228. incoming[i] = 0;
  2229. incoming[j] = 0;
  2230. }
  2231. break;
  2232. }
  2233. }
  2234. }
  2235. }
  2236. }
  2237. //find any active tail that needs to pass through to an incoming edge
  2238. //we expect to find no more than two pass through
  2239. //find pass through with solid on top
  2240. {
  2241. //std::cout << "checking case 3\n";
  2242. for(int i = 0; i < c_size; ++i) {
  2243. //std::cout << i << "\n";
  2244. if(counts[i] != 0) {
  2245. if(counts[i] == 1) {
  2246. //std::cout << "fixed i\n";
  2247. for(int j = i_size_less_1; j >= 0; --j) {
  2248. if(incoming[j] != 0) {
  2249. if(incoming[j] == 1) {
  2250. //std::cout << "case3: " << i << " " << j << "\n";
  2251. //tails[i]->print();
  2252. //pass through solid on top
  2253. tails[i]->pushPoint(point);
  2254. //std::cout << "after push\n";
  2255. if(j == i_size_less_1 && incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  2256. returnValue = tails[i];
  2257. returnCount.first = point;
  2258. returnCount.second = -1;
  2259. } else {
  2260. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
  2261. active_tail_arbitrary::createActiveTailsAsPair(point, true, 0, false);
  2262. verticalPairOut.first = tails[i];
  2263. verticalPairOut.second = tailPair.first;
  2264. elements.push_back(std::pair<vertex_half_edge,
  2265. active_tail_arbitrary*>(vertex_half_edge(point,
  2266. incoming_count[j].first, incoming[j]), tailPair.second));
  2267. }
  2268. tails[i] = 0;
  2269. counts[i] = 0;
  2270. incoming[j] = 0;
  2271. }
  2272. break;
  2273. }
  2274. }
  2275. }
  2276. break;
  2277. }
  2278. }
  2279. }
  2280. //std::cout << "checking case 4\n";
  2281. //find pass through with solid on bottom
  2282. {
  2283. for(int i = c_size_less_1; i >= 0; --i) {
  2284. //std::cout << "i = " << i << " with count " << counts[i] << "\n";
  2285. if(counts[i] != 0) {
  2286. if(counts[i] == -1) {
  2287. for(int j = 0; j < i_size; ++j) {
  2288. if(incoming[j] != 0) {
  2289. if(incoming[j] == -1) {
  2290. //std::cout << "case4: " << i << " " << j << "\n";
  2291. //pass through solid on bottom
  2292. //if count from scanline is vertical
  2293. if(i == c_size_less_1 &&
  2294. counts_from_scanline[i].first.first.first.get(HORIZONTAL) ==
  2295. point.get(HORIZONTAL)) {
  2296. //if incoming count is vertical
  2297. if(j == i_size_less_1 &&
  2298. incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  2299. returnValue = tails[i];
  2300. returnCount.first = point;
  2301. returnCount.second = 1;
  2302. } else {
  2303. tails[i]->pushPoint(point);
  2304. elements.push_back(std::pair<vertex_half_edge,
  2305. active_tail_arbitrary*>(vertex_half_edge(point,
  2306. incoming_count[j].first, incoming[j]), tails[i]));
  2307. }
  2308. } else if(j == i_size_less_1 &&
  2309. incoming_count[j].first.get(HORIZONTAL) ==
  2310. point.get(HORIZONTAL)) {
  2311. if(verticalPair.first == 0) {
  2312. getVerticalPair_(verticalPair, previter);
  2313. }
  2314. active_tail_arbitrary::joinChains(point, tails[i], verticalPair.first, true, output);
  2315. returnValue = verticalPair.second;
  2316. returnCount.first = point;
  2317. returnCount.second = 1;
  2318. } else {
  2319. //neither is vertical
  2320. if(verticalPair.first == 0) {
  2321. getVerticalPair_(verticalPair, previter);
  2322. }
  2323. active_tail_arbitrary::joinChains(point, tails[i], verticalPair.first, true, output);
  2324. verticalPair.second->pushPoint(point);
  2325. elements.push_back(std::pair<vertex_half_edge,
  2326. active_tail_arbitrary*>(vertex_half_edge(point,
  2327. incoming_count[j].first, incoming[j]), verticalPair.second));
  2328. }
  2329. tails[i] = 0;
  2330. counts[i] = 0;
  2331. incoming[j] = 0;
  2332. }
  2333. break;
  2334. }
  2335. }
  2336. }
  2337. break;
  2338. }
  2339. }
  2340. }
  2341. //find the end of a hole or the beginning of a hole
  2342. //find end of a hole
  2343. {
  2344. for(int i = 0; i < c_size_less_1; ++i) {
  2345. if(counts[i] != 0) {
  2346. for(int j = i+1; j < c_size; ++j) {
  2347. if(counts[j] != 0) {
  2348. //std::cout << "case5: " << i << " " << j << "\n";
  2349. //we are ending a hole and may potentially close a figure and have to handle the hole
  2350. tails[i]->pushPoint(point);
  2351. verticalPairOut.first = tails[i];
  2352. if(j == c_size_less_1 &&
  2353. counts_from_scanline[j].first.first.first.get(HORIZONTAL) ==
  2354. point.get(HORIZONTAL)) {
  2355. verticalPairOut.second = tails[j];
  2356. } else {
  2357. //need to close a trapezoid below
  2358. if(verticalPair.first == 0) {
  2359. getVerticalPair_(verticalPair, previter);
  2360. }
  2361. active_tail_arbitrary::joinChains(point, tails[j], verticalPair.first, true, output);
  2362. verticalPairOut.second = verticalPair.second;
  2363. }
  2364. tails[i] = 0;
  2365. tails[j] = 0;
  2366. counts[i] = 0;
  2367. counts[j] = 0;
  2368. break;
  2369. }
  2370. }
  2371. break;
  2372. }
  2373. }
  2374. }
  2375. //find beginning of a hole
  2376. {
  2377. for(int i = 0; i < i_size_less_1; ++i) {
  2378. if(incoming[i] != 0) {
  2379. for(int j = i+1; j < i_size; ++j) {
  2380. if(incoming[j] != 0) {
  2381. //std::cout << "case6: " << i << " " << j << "\n";
  2382. //we are beginning a empty space
  2383. if(verticalPair.first == 0) {
  2384. getVerticalPair_(verticalPair, previter);
  2385. }
  2386. verticalPair.second->pushPoint(point);
  2387. if(j == i_size_less_1 &&
  2388. incoming_count[j].first.get(HORIZONTAL) == point.get(HORIZONTAL)) {
  2389. returnValue = verticalPair.first;
  2390. returnCount.first = point;
  2391. returnCount.second = -1;
  2392. } else {
  2393. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> tailPair =
  2394. active_tail_arbitrary::createActiveTailsAsPair(point, false, 0, false);
  2395. elements.push_back(std::pair<vertex_half_edge,
  2396. active_tail_arbitrary*>(vertex_half_edge(point,
  2397. incoming_count[j].first, incoming[j]), tailPair.second));
  2398. verticalPairOut.second = tailPair.first;
  2399. verticalPairOut.first = verticalPair.first;
  2400. }
  2401. elements.push_back(std::pair<vertex_half_edge,
  2402. active_tail_arbitrary*>(vertex_half_edge(point,
  2403. incoming_count[i].first, incoming[i]), verticalPair.second));
  2404. incoming[i] = 0;
  2405. incoming[j] = 0;
  2406. break;
  2407. }
  2408. }
  2409. break;
  2410. }
  2411. }
  2412. }
  2413. if(have_vertical_tail_from_below) {
  2414. if(tails.back()) {
  2415. tails.back()->pushPoint(point);
  2416. returnValue = tails.back();
  2417. returnCount.first = point;
  2418. returnCount.second = counts.back();
  2419. }
  2420. }
  2421. verticalPair = verticalPairOut;
  2422. //assert that tails, counts and incoming are all null
  2423. return std::pair<std::pair<Point, int>, active_tail_arbitrary*>(returnCount, returnValue);
  2424. }
  2425. static inline void print(const vertex_arbitrary_count& count) {
  2426. for(unsigned i = 0; i < count.size(); ++i) {
  2427. //std::cout << count[i].first.get(HORIZONTAL) << ",";
  2428. //std::cout << count[i].first.get(VERTICAL) << ":";
  2429. //std::cout << count[i].second << " ";
  2430. } //std::cout << "\n";
  2431. }
  2432. static inline void print(const scanline_data& data) {
  2433. for(typename scanline_data::const_iterator itr = data.begin(); itr != data.end(); ++itr){
  2434. //std::cout << itr->first.pt << ", " << itr->first.other_pt << "; ";
  2435. } //std::cout << "\n";
  2436. }
  2437. template <class cT, class iT>
  2438. inline iT processEvent_(cT& output, iT inputBegin, iT inputEnd) {
  2439. //typedef typename high_precision_type<Unit>::type high_precision;
  2440. //std::cout << "processEvent_\n";
  2441. polygon_arbitrary_formation<Unit>::justBefore_ = true;
  2442. //collect up all elements from the tree that are at the y
  2443. //values of events in the input queue
  2444. //create vector of new elements to add into tree
  2445. active_tail_arbitrary* verticalTail = 0;
  2446. std::pair<active_tail_arbitrary*, active_tail_arbitrary*> verticalPair;
  2447. std::pair<Point, int> verticalCount(Point(0, 0), 0);
  2448. iT currentIter = inputBegin;
  2449. std::vector<iterator> elementIters;
  2450. std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> > elements;
  2451. while(currentIter != inputEnd && currentIter->pt.get(HORIZONTAL) == polygon_arbitrary_formation<Unit>::x_) {
  2452. //std::cout << "loop\n";
  2453. Unit currentY = (*currentIter).pt.get(VERTICAL);
  2454. //std::cout << "current Y " << currentY << "\n";
  2455. //std::cout << "scanline size " << scanData_.size() << "\n";
  2456. //print(scanData_);
  2457. iterator iter = this->lookUp_(currentY);
  2458. //std::cout << "found element in scanline " << (iter != scanData_.end()) << "\n";
  2459. //int counts[4] = {0, 0, 0, 0};
  2460. incoming_count counts_from_scanline;
  2461. //std::cout << "finding elements in tree\n";
  2462. //if(iter != scanData_.end())
  2463. // std::cout << "first iter y is " << iter->first.evalAtX(x_) << "\n";
  2464. iterator previter = iter;
  2465. if(previter != polygon_arbitrary_formation<Unit>::scanData_.end() &&
  2466. previter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_) >= currentY &&
  2467. previter != polygon_arbitrary_formation<Unit>::scanData_.begin())
  2468. --previter;
  2469. while(iter != polygon_arbitrary_formation<Unit>::scanData_.end() &&
  2470. ((iter->first.pt.x() == polygon_arbitrary_formation<Unit>::x_ && iter->first.pt.y() == currentY) ||
  2471. (iter->first.other_pt.x() == polygon_arbitrary_formation<Unit>::x_ && iter->first.other_pt.y() == currentY))) {
  2472. //iter->first.evalAtX(polygon_arbitrary_formation<Unit>::x_) == (high_precision)currentY) {
  2473. //std::cout << "loop2\n";
  2474. elementIters.push_back(iter);
  2475. counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>
  2476. (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(iter->first.pt,
  2477. iter->first.other_pt),
  2478. iter->first.count),
  2479. iter->second));
  2480. ++iter;
  2481. }
  2482. Point currentPoint(polygon_arbitrary_formation<Unit>::x_, currentY);
  2483. //std::cout << "counts_from_scanline size " << counts_from_scanline.size() << "\n";
  2484. this->sort_incoming_count(counts_from_scanline, currentPoint);
  2485. vertex_arbitrary_count incoming;
  2486. //std::cout << "aggregating\n";
  2487. do {
  2488. //std::cout << "loop3\n";
  2489. const vertex_half_edge& elem = *currentIter;
  2490. incoming.push_back(std::pair<Point, int>(elem.other_pt, elem.count));
  2491. ++currentIter;
  2492. } while(currentIter != inputEnd && currentIter->pt.get(VERTICAL) == currentY &&
  2493. currentIter->pt.get(HORIZONTAL) == polygon_arbitrary_formation<Unit>::x_);
  2494. //print(incoming);
  2495. this->sort_vertex_arbitrary_count(incoming, currentPoint);
  2496. //std::cout << currentPoint.get(HORIZONTAL) << "," << currentPoint.get(VERTICAL) << "\n";
  2497. //print(incoming);
  2498. //std::cout << "incoming counts from input size " << incoming.size() << "\n";
  2499. //compact_vertex_arbitrary_count(currentPoint, incoming);
  2500. vertex_arbitrary_count tmp;
  2501. tmp.reserve(incoming.size());
  2502. for(std::size_t i = 0; i < incoming.size(); ++i) {
  2503. if(currentPoint < incoming[i].first) {
  2504. tmp.push_back(incoming[i]);
  2505. }
  2506. }
  2507. incoming.swap(tmp);
  2508. //std::cout << "incoming counts from input size " << incoming.size() << "\n";
  2509. //now counts_from_scanline has the data from the left and
  2510. //incoming has the data from the right at this point
  2511. //cancel out any end points
  2512. if(verticalTail) {
  2513. //std::cout << "adding vertical tail to counts from scanline\n";
  2514. //std::cout << -verticalCount.second << "\n";
  2515. counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>
  2516. (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(verticalCount.first,
  2517. currentPoint),
  2518. -verticalCount.second),
  2519. verticalTail));
  2520. }
  2521. if(!incoming.empty() && incoming.back().first.get(HORIZONTAL) == polygon_arbitrary_formation<Unit>::x_) {
  2522. //std::cout << "inverted vertical event\n";
  2523. incoming.back().second *= -1;
  2524. }
  2525. //std::cout << "calling processPoint_\n";
  2526. std::pair<std::pair<Point, int>, active_tail_arbitrary*> result = processPoint_(output, elements, verticalPair, previter, Point(polygon_arbitrary_formation<Unit>::x_, currentY), counts_from_scanline, incoming);
  2527. verticalCount = result.first;
  2528. verticalTail = result.second;
  2529. if(verticalPair.first != 0 && iter != polygon_arbitrary_formation<Unit>::scanData_.end() &&
  2530. (currentIter == inputEnd || currentIter->pt.x() != polygon_arbitrary_formation<Unit>::x_ ||
  2531. currentIter->pt.y() > (*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_))) {
  2532. //splice vertical pair into edge above
  2533. active_tail_arbitrary* tailabove = (*iter).second;
  2534. Point point(polygon_arbitrary_formation<Unit>::x_,
  2535. convert_high_precision_type<Unit>((*iter).first.evalAtX(polygon_arbitrary_formation<Unit>::x_)));
  2536. verticalPair.second->pushPoint(point);
  2537. active_tail_arbitrary::joinChains(point, tailabove, verticalPair.first, true, output);
  2538. (*iter).second = verticalPair.second;
  2539. verticalPair.first = 0;
  2540. verticalPair.second = 0;
  2541. }
  2542. }
  2543. //std::cout << "erasing\n";
  2544. //erase all elements from the tree
  2545. for(typename std::vector<iterator>::iterator iter = elementIters.begin();
  2546. iter != elementIters.end(); ++iter) {
  2547. //std::cout << "erasing loop\n";
  2548. polygon_arbitrary_formation<Unit>::scanData_.erase(*iter);
  2549. }
  2550. //switch comparison tie breaking policy
  2551. polygon_arbitrary_formation<Unit>::justBefore_ = false;
  2552. //add new elements into tree
  2553. //std::cout << "inserting\n";
  2554. for(typename std::vector<std::pair<vertex_half_edge, active_tail_arbitrary*> >::iterator iter = elements.begin();
  2555. iter != elements.end(); ++iter) {
  2556. //std::cout << "inserting loop\n";
  2557. polygon_arbitrary_formation<Unit>::scanData_.insert(polygon_arbitrary_formation<Unit>::scanData_.end(), *iter);
  2558. }
  2559. //std::cout << "end processEvent\n";
  2560. return currentIter;
  2561. }
  2562. public:
  2563. template <typename stream_type>
  2564. static inline bool testTrapezoidArbitraryFormationRect(stream_type& stdcout) {
  2565. stdcout << "testing trapezoid formation\n";
  2566. trapezoid_arbitrary_formation pf;
  2567. std::vector<polygon_data<Unit> > polys;
  2568. std::vector<vertex_half_edge> data;
  2569. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1));
  2570. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  2571. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  2572. data.push_back(vertex_half_edge(Point(0, 10), Point(10, 10), -1));
  2573. data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1));
  2574. data.push_back(vertex_half_edge(Point(10, 0), Point(10, 10), -1));
  2575. data.push_back(vertex_half_edge(Point(10, 10), Point(10, 0), 1));
  2576. data.push_back(vertex_half_edge(Point(10, 10), Point(0, 10), 1));
  2577. polygon_sort(data.begin(), data.end());
  2578. pf.scan(polys, data.begin(), data.end());
  2579. stdcout << "result size: " << polys.size() << "\n";
  2580. for(std::size_t i = 0; i < polys.size(); ++i) {
  2581. stdcout << polys[i] << "\n";
  2582. }
  2583. stdcout << "done testing trapezoid formation\n";
  2584. return true;
  2585. }
  2586. template <typename stream_type>
  2587. static inline bool testTrapezoidArbitraryFormationP1(stream_type& stdcout) {
  2588. stdcout << "testing trapezoid formation P1\n";
  2589. trapezoid_arbitrary_formation pf;
  2590. std::vector<polygon_data<Unit> > polys;
  2591. std::vector<vertex_half_edge> data;
  2592. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 10), 1));
  2593. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  2594. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  2595. data.push_back(vertex_half_edge(Point(0, 10), Point(10, 20), -1));
  2596. data.push_back(vertex_half_edge(Point(10, 10), Point(0, 0), -1));
  2597. data.push_back(vertex_half_edge(Point(10, 10), Point(10, 20), -1));
  2598. data.push_back(vertex_half_edge(Point(10, 20), Point(10, 10), 1));
  2599. data.push_back(vertex_half_edge(Point(10, 20), Point(0, 10), 1));
  2600. polygon_sort(data.begin(), data.end());
  2601. pf.scan(polys, data.begin(), data.end());
  2602. stdcout << "result size: " << polys.size() << "\n";
  2603. for(std::size_t i = 0; i < polys.size(); ++i) {
  2604. stdcout << polys[i] << "\n";
  2605. }
  2606. stdcout << "done testing trapezoid formation\n";
  2607. return true;
  2608. }
  2609. template <typename stream_type>
  2610. static inline bool testTrapezoidArbitraryFormationP2(stream_type& stdcout) {
  2611. stdcout << "testing trapezoid formation P2\n";
  2612. trapezoid_arbitrary_formation pf;
  2613. std::vector<polygon_data<Unit> > polys;
  2614. std::vector<vertex_half_edge> data;
  2615. data.push_back(vertex_half_edge(Point(-3, 1), Point(2, -4), 1));
  2616. data.push_back(vertex_half_edge(Point(-3, 1), Point(-2, 2), -1));
  2617. data.push_back(vertex_half_edge(Point(-2, 2), Point(2, 4), -1));
  2618. data.push_back(vertex_half_edge(Point(-2, 2), Point(-3, 1), 1));
  2619. data.push_back(vertex_half_edge(Point(2, -4), Point(-3, 1), -1));
  2620. data.push_back(vertex_half_edge(Point(2, -4), Point(2, 4), -1));
  2621. data.push_back(vertex_half_edge(Point(2, 4), Point(-2, 2), 1));
  2622. data.push_back(vertex_half_edge(Point(2, 4), Point(2, -4), 1));
  2623. polygon_sort(data.begin(), data.end());
  2624. pf.scan(polys, data.begin(), data.end());
  2625. stdcout << "result size: " << polys.size() << "\n";
  2626. for(std::size_t i = 0; i < polys.size(); ++i) {
  2627. stdcout << polys[i] << "\n";
  2628. }
  2629. stdcout << "done testing trapezoid formation\n";
  2630. return true;
  2631. }
  2632. template <typename stream_type>
  2633. static inline bool testTrapezoidArbitraryFormationPolys(stream_type& stdcout) {
  2634. stdcout << "testing trapezoid formation polys\n";
  2635. trapezoid_arbitrary_formation pf;
  2636. std::vector<polygon_with_holes_data<Unit> > polys;
  2637. //trapezoid_arbitrary_formation pf2(true);
  2638. //std::vector<polygon_with_holes_data<Unit> > polys2;
  2639. std::vector<vertex_half_edge> data;
  2640. data.push_back(vertex_half_edge(Point(0, 0), Point(100, 1), 1));
  2641. data.push_back(vertex_half_edge(Point(0, 0), Point(1, 100), -1));
  2642. data.push_back(vertex_half_edge(Point(1, 100), Point(0, 0), 1));
  2643. data.push_back(vertex_half_edge(Point(1, 100), Point(101, 101), -1));
  2644. data.push_back(vertex_half_edge(Point(100, 1), Point(0, 0), -1));
  2645. data.push_back(vertex_half_edge(Point(100, 1), Point(101, 101), 1));
  2646. data.push_back(vertex_half_edge(Point(101, 101), Point(100, 1), -1));
  2647. data.push_back(vertex_half_edge(Point(101, 101), Point(1, 100), 1));
  2648. data.push_back(vertex_half_edge(Point(2, 2), Point(10, 2), -1));
  2649. data.push_back(vertex_half_edge(Point(2, 2), Point(2, 10), -1));
  2650. data.push_back(vertex_half_edge(Point(2, 10), Point(2, 2), 1));
  2651. data.push_back(vertex_half_edge(Point(2, 10), Point(10, 10), 1));
  2652. data.push_back(vertex_half_edge(Point(10, 2), Point(2, 2), 1));
  2653. data.push_back(vertex_half_edge(Point(10, 2), Point(10, 10), 1));
  2654. data.push_back(vertex_half_edge(Point(10, 10), Point(10, 2), -1));
  2655. data.push_back(vertex_half_edge(Point(10, 10), Point(2, 10), -1));
  2656. data.push_back(vertex_half_edge(Point(2, 12), Point(10, 12), -1));
  2657. data.push_back(vertex_half_edge(Point(2, 12), Point(2, 22), -1));
  2658. data.push_back(vertex_half_edge(Point(2, 22), Point(2, 12), 1));
  2659. data.push_back(vertex_half_edge(Point(2, 22), Point(10, 22), 1));
  2660. data.push_back(vertex_half_edge(Point(10, 12), Point(2, 12), 1));
  2661. data.push_back(vertex_half_edge(Point(10, 12), Point(10, 22), 1));
  2662. data.push_back(vertex_half_edge(Point(10, 22), Point(10, 12), -1));
  2663. data.push_back(vertex_half_edge(Point(10, 22), Point(2, 22), -1));
  2664. polygon_sort(data.begin(), data.end());
  2665. pf.scan(polys, data.begin(), data.end());
  2666. stdcout << "result size: " << polys.size() << "\n";
  2667. for(std::size_t i = 0; i < polys.size(); ++i) {
  2668. stdcout << polys[i] << "\n";
  2669. }
  2670. //pf2.scan(polys2, data.begin(), data.end());
  2671. //stdcout << "result size: " << polys2.size() << "\n";
  2672. //for(std::size_t i = 0; i < polys2.size(); ++i) {
  2673. // stdcout << polys2[i] << "\n";
  2674. //}
  2675. stdcout << "done testing trapezoid formation\n";
  2676. return true;
  2677. }
  2678. template <typename stream_type>
  2679. static inline bool testTrapezoidArbitraryFormationSelfTouch1(stream_type& stdcout) {
  2680. stdcout << "testing trapezoid formation self touch 1\n";
  2681. trapezoid_arbitrary_formation pf;
  2682. std::vector<polygon_data<Unit> > polys;
  2683. std::vector<vertex_half_edge> data;
  2684. data.push_back(vertex_half_edge(Point(0, 0), Point(10, 0), 1));
  2685. data.push_back(vertex_half_edge(Point(0, 0), Point(0, 10), 1));
  2686. data.push_back(vertex_half_edge(Point(0, 10), Point(0, 0), -1));
  2687. data.push_back(vertex_half_edge(Point(0, 10), Point(5, 10), -1));
  2688. data.push_back(vertex_half_edge(Point(10, 0), Point(0, 0), -1));
  2689. data.push_back(vertex_half_edge(Point(10, 0), Point(10, 5), -1));
  2690. data.push_back(vertex_half_edge(Point(10, 5), Point(10, 0), 1));
  2691. data.push_back(vertex_half_edge(Point(10, 5), Point(5, 5), 1));
  2692. data.push_back(vertex_half_edge(Point(5, 10), Point(5, 5), 1));
  2693. data.push_back(vertex_half_edge(Point(5, 10), Point(0, 10), 1));
  2694. data.push_back(vertex_half_edge(Point(5, 2), Point(5, 5), -1));
  2695. data.push_back(vertex_half_edge(Point(5, 2), Point(7, 2), -1));
  2696. data.push_back(vertex_half_edge(Point(5, 5), Point(5, 10), -1));
  2697. data.push_back(vertex_half_edge(Point(5, 5), Point(5, 2), 1));
  2698. data.push_back(vertex_half_edge(Point(5, 5), Point(10, 5), -1));
  2699. data.push_back(vertex_half_edge(Point(5, 5), Point(7, 2), 1));
  2700. data.push_back(vertex_half_edge(Point(7, 2), Point(5, 5), -1));
  2701. data.push_back(vertex_half_edge(Point(7, 2), Point(5, 2), 1));
  2702. polygon_sort(data.begin(), data.end());
  2703. pf.scan(polys, data.begin(), data.end());
  2704. stdcout << "result size: " << polys.size() << "\n";
  2705. for(std::size_t i = 0; i < polys.size(); ++i) {
  2706. stdcout << polys[i] << "\n";
  2707. }
  2708. stdcout << "done testing trapezoid formation\n";
  2709. return true;
  2710. }
  2711. };
  2712. template <typename T>
  2713. struct PolyLineArbitraryByConcept<T, polygon_with_holes_concept> { typedef poly_line_arbitrary_polygon_data<T> type; };
  2714. template <typename T>
  2715. struct PolyLineArbitraryByConcept<T, polygon_concept> { typedef poly_line_arbitrary_hole_data<T> type; };
  2716. template <typename T>
  2717. struct geometry_concept<poly_line_arbitrary_polygon_data<T> > { typedef polygon_45_with_holes_concept type; };
  2718. template <typename T>
  2719. struct geometry_concept<poly_line_arbitrary_hole_data<T> > { typedef polygon_45_concept type; };
  2720. }
  2721. }
  2722. #endif