polygon_traits.hpp 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851
  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_TRAITS_HPP
  8. #define BOOST_POLYGON_POLYGON_TRAITS_HPP
  9. namespace boost { namespace polygon{
  10. template <typename T, typename enable = gtl_yes>
  11. struct polygon_90_traits {
  12. typedef typename T::coordinate_type coordinate_type;
  13. typedef typename T::compact_iterator_type compact_iterator_type;
  14. // Get the begin iterator
  15. static inline compact_iterator_type begin_compact(const T& t) {
  16. return t.begin_compact();
  17. }
  18. // Get the end iterator
  19. static inline compact_iterator_type end_compact(const T& t) {
  20. return t.end_compact();
  21. }
  22. // Get the number of sides of the polygon
  23. static inline std::size_t size(const T& t) {
  24. return t.size();
  25. }
  26. // Get the winding direction of the polygon
  27. static inline winding_direction winding(const T&) {
  28. return unknown_winding;
  29. }
  30. };
  31. template <typename T>
  32. struct polygon_traits_general {
  33. typedef typename T::coordinate_type coordinate_type;
  34. typedef typename T::iterator_type iterator_type;
  35. typedef typename T::point_type point_type;
  36. // Get the begin iterator
  37. static inline iterator_type begin_points(const T& t) {
  38. return t.begin();
  39. }
  40. // Get the end iterator
  41. static inline iterator_type end_points(const T& t) {
  42. return t.end();
  43. }
  44. // Get the number of sides of the polygon
  45. static inline std::size_t size(const T& t) {
  46. return t.size();
  47. }
  48. // Get the winding direction of the polygon
  49. static inline winding_direction winding(const T&) {
  50. return unknown_winding;
  51. }
  52. };
  53. template <typename T>
  54. struct polygon_traits_90 {
  55. typedef typename polygon_90_traits<T>::coordinate_type coordinate_type;
  56. typedef iterator_compact_to_points<typename polygon_90_traits<T>::compact_iterator_type, point_data<coordinate_type> > iterator_type;
  57. typedef point_data<coordinate_type> point_type;
  58. // Get the begin iterator
  59. static inline iterator_type begin_points(const T& t) {
  60. return iterator_type(polygon_90_traits<T>::begin_compact(t),
  61. polygon_90_traits<T>::end_compact(t));
  62. }
  63. // Get the end iterator
  64. static inline iterator_type end_points(const T& t) {
  65. return iterator_type(polygon_90_traits<T>::end_compact(t),
  66. polygon_90_traits<T>::end_compact(t));
  67. }
  68. // Get the number of sides of the polygon
  69. static inline std::size_t size(const T& t) {
  70. return polygon_90_traits<T>::size(t);
  71. }
  72. // Get the winding direction of the polygon
  73. static inline winding_direction winding(const T& t) {
  74. return polygon_90_traits<T>::winding(t);
  75. }
  76. };
  77. #ifndef BOOST_VERY_LITTLE_SFINAE
  78. template <typename T, typename enable = gtl_yes>
  79. struct polygon_traits {};
  80. template <typename T>
  81. struct polygon_traits<T,
  82. typename gtl_or_4<
  83. typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
  84. typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
  85. typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
  86. typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
  87. >::type> : public polygon_traits_general<T> {};
  88. template <typename T>
  89. struct polygon_traits< T,
  90. typename gtl_or<
  91. typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
  92. typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
  93. >::type > : public polygon_traits_90<T> {};
  94. #else
  95. template <typename T, typename T_IF, typename T_ELSE>
  96. struct gtl_ifelse {};
  97. template <typename T_IF, typename T_ELSE>
  98. struct gtl_ifelse<gtl_no, T_IF, T_ELSE> {
  99. typedef T_ELSE type;
  100. };
  101. template <typename T_IF, typename T_ELSE>
  102. struct gtl_ifelse<gtl_yes, T_IF, T_ELSE> {
  103. typedef T_IF type;
  104. };
  105. template <typename T, typename enable = gtl_yes>
  106. struct polygon_traits {};
  107. template <typename T>
  108. struct polygon_traits<T, typename gtl_or<typename gtl_or_4<
  109. typename gtl_same_type<typename geometry_concept<T>::type, polygon_concept>::type,
  110. typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_concept>::type,
  111. typename gtl_same_type<typename geometry_concept<T>::type, polygon_with_holes_concept>::type,
  112. typename gtl_same_type<typename geometry_concept<T>::type, polygon_45_with_holes_concept>::type
  113. >::type, typename gtl_or<
  114. typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
  115. typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type
  116. >::type>::type > : public gtl_ifelse<typename gtl_or<
  117. typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_concept>::type,
  118. typename gtl_same_type<typename geometry_concept<T>::type, polygon_90_with_holes_concept>::type >::type,
  119. polygon_traits_90<T>,
  120. polygon_traits_general<T> >::type {
  121. };
  122. #endif
  123. template <typename T, typename enable = void>
  124. struct polygon_with_holes_traits {
  125. typedef typename T::iterator_holes_type iterator_holes_type;
  126. typedef typename T::hole_type hole_type;
  127. // Get the begin iterator
  128. static inline iterator_holes_type begin_holes(const T& t) {
  129. return t.begin_holes();
  130. }
  131. // Get the end iterator
  132. static inline iterator_holes_type end_holes(const T& t) {
  133. return t.end_holes();
  134. }
  135. // Get the number of holes
  136. static inline std::size_t size_holes(const T& t) {
  137. return t.size_holes();
  138. }
  139. };
  140. template <typename T, typename enable = void>
  141. struct polygon_90_mutable_traits {
  142. // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
  143. template <typename iT>
  144. static inline T& set_compact(T& t, iT input_begin, iT input_end) {
  145. t.set_compact(input_begin, input_end);
  146. return t;
  147. }
  148. };
  149. template <typename T>
  150. struct polygon_90_mutable_traits<T, typename gtl_same_type<polygon_concept, typename geometry_concept<T>::type>::type> {
  151. // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
  152. template <typename iT>
  153. static inline T& set_compact(T& t, iT input_begin, iT input_end) {
  154. typedef iterator_points_to_compact<iT, typename polygon_traits<T>::point_type> iTp;
  155. t.set_points(iTp(polygon_traits<T>::begin_points(t)), iTp(polygon_traits<T>::end_points(t)));
  156. return t;
  157. }
  158. };
  159. template <typename T, typename enable = void>
  160. struct polygon_mutable_traits {
  161. // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
  162. template <typename iT>
  163. static inline T& set_points(T& t, iT input_begin, iT input_end) {
  164. t.set(input_begin, input_end);
  165. return t;
  166. }
  167. };
  168. template <typename T, typename enable = void>
  169. struct polygon_with_holes_mutable_traits {
  170. // Set the data of a polygon with the unique coordinates in an iterator, starting with an x
  171. template <typename iT>
  172. static inline T& set_holes(T& t, iT inputBegin, iT inputEnd) {
  173. t.set_holes(inputBegin, inputEnd);
  174. return t;
  175. }
  176. };
  177. }
  178. }
  179. #include "isotropy.hpp"
  180. //point
  181. #include "point_data.hpp"
  182. #include "point_traits.hpp"
  183. #include "point_concept.hpp"
  184. //interval
  185. #include "interval_data.hpp"
  186. #include "interval_traits.hpp"
  187. #include "interval_concept.hpp"
  188. //rectangle
  189. #include "rectangle_data.hpp"
  190. #include "rectangle_traits.hpp"
  191. #include "rectangle_concept.hpp"
  192. //algorithms needed by polygon types
  193. #include "detail/iterator_points_to_compact.hpp"
  194. #include "detail/iterator_compact_to_points.hpp"
  195. //polygons
  196. #include "polygon_45_data.hpp"
  197. #include "polygon_data.hpp"
  198. #include "polygon_90_data.hpp"
  199. #include "polygon_90_with_holes_data.hpp"
  200. #include "polygon_45_with_holes_data.hpp"
  201. #include "polygon_with_holes_data.hpp"
  202. namespace boost { namespace polygon{
  203. struct polygon_concept {};
  204. struct polygon_with_holes_concept {};
  205. struct polygon_45_concept {};
  206. struct polygon_45_with_holes_concept {};
  207. struct polygon_90_concept {};
  208. struct polygon_90_with_holes_concept {};
  209. template <typename T>
  210. struct is_polygon_90_type {
  211. typedef typename geometry_concept<T>::type GC;
  212. typedef typename gtl_same_type<polygon_90_concept, GC>::type type;
  213. };
  214. template <typename T>
  215. struct is_polygon_45_type {
  216. typedef typename geometry_concept<T>::type GC;
  217. typedef typename gtl_or<typename is_polygon_90_type<T>::type,
  218. typename gtl_same_type<polygon_45_concept, GC>::type>::type type;
  219. };
  220. template <typename T>
  221. struct is_polygon_type {
  222. typedef typename geometry_concept<T>::type GC;
  223. typedef typename gtl_or<typename is_polygon_45_type<T>::type,
  224. typename gtl_same_type<polygon_concept, GC>::type>::type type;
  225. };
  226. template <typename T>
  227. struct is_polygon_90_with_holes_type {
  228. typedef typename geometry_concept<T>::type GC;
  229. typedef typename gtl_or<typename is_polygon_90_type<T>::type,
  230. typename gtl_same_type<polygon_90_with_holes_concept, GC>::type>::type type;
  231. };
  232. template <typename T>
  233. struct is_polygon_45_with_holes_type {
  234. typedef typename geometry_concept<T>::type GC;
  235. typedef typename gtl_or_3<typename is_polygon_90_with_holes_type<T>::type,
  236. typename is_polygon_45_type<T>::type,
  237. typename gtl_same_type<polygon_45_with_holes_concept, GC>::type>::type type;
  238. };
  239. template <typename T>
  240. struct is_polygon_with_holes_type {
  241. typedef typename geometry_concept<T>::type GC;
  242. typedef typename gtl_or_3<typename is_polygon_45_with_holes_type<T>::type,
  243. typename is_polygon_type<T>::type,
  244. typename gtl_same_type<polygon_with_holes_concept, GC>::type>::type type;
  245. };
  246. template <typename T>
  247. struct is_mutable_polygon_90_type {
  248. typedef typename geometry_concept<T>::type GC;
  249. typedef typename gtl_same_type<polygon_90_concept, GC>::type type;
  250. };
  251. template <typename T>
  252. struct is_mutable_polygon_45_type {
  253. typedef typename geometry_concept<T>::type GC;
  254. typedef typename gtl_same_type<polygon_45_concept, GC>::type type;
  255. };
  256. template <typename T>
  257. struct is_mutable_polygon_type {
  258. typedef typename geometry_concept<T>::type GC;
  259. typedef typename gtl_same_type<polygon_concept, GC>::type type;
  260. };
  261. template <typename T>
  262. struct is_mutable_polygon_90_with_holes_type {
  263. typedef typename geometry_concept<T>::type GC;
  264. typedef typename gtl_same_type<polygon_90_with_holes_concept, GC>::type type;
  265. };
  266. template <typename T>
  267. struct is_mutable_polygon_45_with_holes_type {
  268. typedef typename geometry_concept<T>::type GC;
  269. typedef typename gtl_same_type<polygon_45_with_holes_concept, GC>::type type;
  270. };
  271. template <typename T>
  272. struct is_mutable_polygon_with_holes_type {
  273. typedef typename geometry_concept<T>::type GC;
  274. typedef typename gtl_same_type<polygon_with_holes_concept, GC>::type type;
  275. };
  276. template <typename T>
  277. struct is_any_mutable_polygon_with_holes_type {
  278. typedef typename gtl_or_3<typename is_mutable_polygon_90_with_holes_type<T>::type,
  279. typename is_mutable_polygon_45_with_holes_type<T>::type,
  280. typename is_mutable_polygon_with_holes_type<T>::type>::type type;
  281. };
  282. template <typename T>
  283. struct is_any_mutable_polygon_without_holes_type {
  284. typedef typename gtl_or_3<
  285. typename is_mutable_polygon_90_type<T>::type,
  286. typename is_mutable_polygon_45_type<T>::type,
  287. typename is_mutable_polygon_type<T>::type>::type type; };
  288. template <typename T>
  289. struct is_any_mutable_polygon_type {
  290. typedef typename gtl_or<typename is_any_mutable_polygon_with_holes_type<T>::type,
  291. typename is_any_mutable_polygon_without_holes_type<T>::type>::type type;
  292. };
  293. template <typename T>
  294. struct polygon_from_polygon_with_holes_type {};
  295. template <>
  296. struct polygon_from_polygon_with_holes_type<polygon_with_holes_concept> { typedef polygon_concept type; };
  297. template <>
  298. struct polygon_from_polygon_with_holes_type<polygon_45_with_holes_concept> { typedef polygon_45_concept type; };
  299. template <>
  300. struct polygon_from_polygon_with_holes_type<polygon_90_with_holes_concept> { typedef polygon_90_concept type; };
  301. template <>
  302. struct geometry_domain<polygon_45_concept> { typedef forty_five_domain type; };
  303. template <>
  304. struct geometry_domain<polygon_45_with_holes_concept> { typedef forty_five_domain type; };
  305. template <>
  306. struct geometry_domain<polygon_90_concept> { typedef manhattan_domain type; };
  307. template <>
  308. struct geometry_domain<polygon_90_with_holes_concept> { typedef manhattan_domain type; };
  309. template <typename domain_type, typename coordinate_type>
  310. struct distance_type_by_domain { typedef typename coordinate_traits<coordinate_type>::coordinate_distance type; };
  311. template <typename coordinate_type>
  312. struct distance_type_by_domain<manhattan_domain, coordinate_type> {
  313. typedef typename coordinate_traits<coordinate_type>::coordinate_difference type; };
  314. // \brief Sets the boundary of the polygon to the points in the iterator range
  315. // \tparam T A type that models polygon_concept
  316. // \tparam iT Iterator type over objects that model point_concept
  317. // \param t The polygon to set
  318. // \param begin_points The start of the range of points
  319. // \param end_points The end of the range of points
  320. /// \relatesalso polygon_concept
  321. template <typename T, typename iT>
  322. typename enable_if <typename is_any_mutable_polygon_type<T>::type, T>::type &
  323. set_points(T& t, iT begin_points, iT end_points) {
  324. polygon_mutable_traits<T>::set_points(t, begin_points, end_points);
  325. return t;
  326. }
  327. // \brief Sets the boundary of the polygon to the non-redundant coordinates in the iterator range
  328. // \tparam T A type that models polygon_90_concept
  329. // \tparam iT Iterator type over objects that model coordinate_concept
  330. // \param t The polygon to set
  331. // \param begin_compact_coordinates The start of the range of coordinates
  332. // \param end_compact_coordinates The end of the range of coordinates
  333. /// \relatesalso polygon_90_concept
  334. template <typename T, typename iT>
  335. typename enable_if <typename gtl_or<
  336. typename is_mutable_polygon_90_type<T>::type,
  337. typename is_mutable_polygon_90_with_holes_type<T>::type>::type, T>::type &
  338. set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) {
  339. polygon_90_mutable_traits<T>::set_compact(t, begin_compact_coordinates, end_compact_coordinates);
  340. return t;
  341. }
  342. /// \relatesalso polygon_with_holes_concept
  343. template <typename T, typename iT>
  344. typename enable_if< typename gtl_and <
  345. typename is_any_mutable_polygon_with_holes_type<T>::type,
  346. typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
  347. manhattan_domain>::type>::type,
  348. T>::type &
  349. set_compact(T& t, iT begin_compact_coordinates, iT end_compact_coordinates) {
  350. iterator_compact_to_points<iT, point_data<typename polygon_traits<T>::coordinate_type> >
  351. itrb(begin_compact_coordinates, end_compact_coordinates),
  352. itre(end_compact_coordinates, end_compact_coordinates);
  353. return set_points(t, itrb, itre);
  354. }
  355. /// \relatesalso polygon_with_holes_concept
  356. template <typename T, typename iT>
  357. typename enable_if <typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
  358. set_holes(T& t, iT begin_holes, iT end_holes) {
  359. polygon_with_holes_mutable_traits<T>::set_holes(t, begin_holes, end_holes);
  360. return t;
  361. }
  362. /// \relatesalso polygon_90_concept
  363. template <typename T>
  364. typename polygon_90_traits<T>::compact_iterator_type
  365. begin_compact(const T& polygon,
  366. typename enable_if<
  367. typename gtl_and <typename is_polygon_with_holes_type<T>::type,
  368. typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
  369. manhattan_domain>::type>::type>::type * = 0
  370. ) {
  371. return polygon_90_traits<T>::begin_compact(polygon);
  372. }
  373. /// \relatesalso polygon_90_concept
  374. template <typename T>
  375. typename polygon_90_traits<T>::compact_iterator_type
  376. end_compact(const T& polygon,
  377. typename enable_if<
  378. typename gtl_and <typename is_polygon_with_holes_type<T>::type,
  379. typename gtl_same_type<typename geometry_domain<typename geometry_concept<T>::type>::type,
  380. manhattan_domain>::type>::type>::type * = 0
  381. ) {
  382. return polygon_90_traits<T>::end_compact(polygon);
  383. }
  384. /// \relatesalso polygon_concept
  385. template <typename T>
  386. typename enable_if < typename gtl_if<
  387. typename is_polygon_with_holes_type<T>::type>::type,
  388. typename polygon_traits<T>::iterator_type>::type
  389. begin_points(const T& polygon) {
  390. return polygon_traits<T>::begin_points(polygon);
  391. }
  392. /// \relatesalso polygon_concept
  393. template <typename T>
  394. typename enable_if < typename gtl_if<
  395. typename is_polygon_with_holes_type<T>::type>::type,
  396. typename polygon_traits<T>::iterator_type>::type
  397. end_points(const T& polygon) {
  398. return polygon_traits<T>::end_points(polygon);
  399. }
  400. /// \relatesalso polygon_concept
  401. template <typename T>
  402. typename enable_if <typename is_polygon_with_holes_type<T>::type,
  403. std::size_t>::type
  404. size(const T& polygon) {
  405. return polygon_traits<T>::size(polygon);
  406. }
  407. /// \relatesalso polygon_with_holes_concept
  408. template <typename T>
  409. typename enable_if < typename gtl_if<
  410. typename is_polygon_with_holes_type<T>::type>::type,
  411. typename polygon_with_holes_traits<T>::iterator_holes_type>::type
  412. begin_holes(const T& polygon) {
  413. return polygon_with_holes_traits<T>::begin_holes(polygon);
  414. }
  415. /// \relatesalso polygon_with_holes_concept
  416. template <typename T>
  417. typename enable_if < typename gtl_if<
  418. typename is_polygon_with_holes_type<T>::type>::type,
  419. typename polygon_with_holes_traits<T>::iterator_holes_type>::type
  420. end_holes(const T& polygon) {
  421. return polygon_with_holes_traits<T>::end_holes(polygon);
  422. }
  423. /// \relatesalso polygon_with_holes_concept
  424. template <typename T>
  425. typename enable_if <typename is_polygon_with_holes_type<T>::type,
  426. std::size_t>::type
  427. size_holes(const T& polygon) {
  428. return polygon_with_holes_traits<T>::size_holes(polygon);
  429. }
  430. // \relatesalso polygon_concept
  431. template <typename T1, typename T2>
  432. typename enable_if<
  433. typename gtl_and< typename is_mutable_polygon_type<T1>::type,
  434. typename is_polygon_type<T2>::type>::type, T1>::type &
  435. assign(T1& lvalue, const T2& rvalue) {
  436. polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
  437. polygon_traits<T2>::end_points(rvalue));
  438. return lvalue;
  439. }
  440. // \relatesalso polygon_with_holes_concept
  441. template <typename T1, typename T2>
  442. typename enable_if<
  443. typename gtl_and< typename is_mutable_polygon_with_holes_type<T1>::type,
  444. typename is_polygon_with_holes_type<T2>::type>::type, T1>::type &
  445. assign(T1& lvalue, const T2& rvalue) {
  446. polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
  447. polygon_traits<T2>::end_points(rvalue));
  448. polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
  449. polygon_with_holes_traits<T2>::end_holes(rvalue));
  450. return lvalue;
  451. }
  452. // \relatesalso polygon_45_concept
  453. template <typename T1, typename T2>
  454. typename enable_if< typename gtl_and< typename is_mutable_polygon_45_type<T1>::type, typename is_polygon_45_type<T2>::type>::type, T1>::type &
  455. assign(T1& lvalue, const T2& rvalue) {
  456. polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
  457. polygon_traits<T2>::end_points(rvalue));
  458. return lvalue;
  459. }
  460. // \relatesalso polygon_45_with_holes_concept
  461. template <typename T1, typename T2>
  462. typename enable_if<
  463. typename gtl_and< typename is_mutable_polygon_45_with_holes_type<T1>::type,
  464. typename is_polygon_45_with_holes_type<T2>::type>::type, T1>::type &
  465. assign(T1& lvalue, const T2& rvalue) {
  466. polygon_mutable_traits<T1>::set_points(lvalue, polygon_traits<T2>::begin_points(rvalue),
  467. polygon_traits<T2>::end_points(rvalue));
  468. polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
  469. polygon_with_holes_traits<T2>::end_holes(rvalue));
  470. return lvalue;
  471. }
  472. // \relatesalso polygon_90_concept
  473. template <typename T1, typename T2>
  474. typename enable_if<
  475. typename gtl_and< typename is_mutable_polygon_90_type<T1>::type,
  476. typename is_polygon_90_type<T2>::type>::type, T1>::type &
  477. assign(T1& lvalue, const T2& rvalue) {
  478. polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue),
  479. polygon_90_traits<T2>::end_compact(rvalue));
  480. return lvalue;
  481. }
  482. // \relatesalso polygon_90_with_holes_concept
  483. template <typename T1, typename T2>
  484. typename enable_if<
  485. typename gtl_and< typename is_mutable_polygon_90_with_holes_type<T1>::type,
  486. typename is_polygon_90_with_holes_type<T2>::type>::type, T1>::type &
  487. assign(T1& lvalue, const T2& rvalue) {
  488. polygon_90_mutable_traits<T1>::set_compact(lvalue, polygon_90_traits<T2>::begin_compact(rvalue),
  489. polygon_90_traits<T2>::end_compact(rvalue));
  490. polygon_with_holes_mutable_traits<T1>::set_holes(lvalue, polygon_with_holes_traits<T2>::begin_holes(rvalue),
  491. polygon_with_holes_traits<T2>::end_holes(rvalue));
  492. return lvalue;
  493. }
  494. // \relatesalso polygon_90_concept
  495. template <typename T1, typename T2>
  496. typename enable_if<
  497. typename gtl_and< typename is_any_mutable_polygon_type<T1>::type,
  498. typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type, T1>::type &
  499. assign(T1& polygon, const T2& rect) {
  500. typedef point_data<typename polygon_traits<T1>::coordinate_type> PT;
  501. PT points[4] = {PT(xl(rect), yl(rect)), PT(xh(rect), yl(rect)), PT(xh(rect), yh(rect)), PT(xl(rect), yh(rect))};
  502. set_points(polygon, points, points+4);
  503. return polygon;
  504. }
  505. /// \relatesalso polygon_90_concept
  506. template <typename polygon_type, typename point_type>
  507. typename enable_if< typename gtl_and< typename is_mutable_polygon_90_type<polygon_type>::type,
  508. typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
  509. polygon_type>::type &
  510. convolve(polygon_type& polygon, const point_type& point) {
  511. std::vector<typename polygon_90_traits<polygon_type>::coordinate_type> coords;
  512. coords.reserve(size(polygon));
  513. bool pingpong = true;
  514. for(typename polygon_90_traits<polygon_type>::compact_iterator_type iter = begin_compact(polygon);
  515. iter != end_compact(polygon); ++iter) {
  516. coords.push_back((*iter) + (pingpong ? x(point) : y(point)));
  517. pingpong = !pingpong;
  518. }
  519. polygon_90_mutable_traits<polygon_type>::set_compact(polygon, coords.begin(), coords.end());
  520. return polygon;
  521. }
  522. /// \relatesalso polygon_concept
  523. template <typename polygon_type, typename point_type>
  524. typename enable_if< typename gtl_and< typename gtl_or<
  525. typename is_mutable_polygon_45_type<polygon_type>::type,
  526. typename is_mutable_polygon_type<polygon_type>::type>::type,
  527. typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
  528. polygon_type>::type &
  529. convolve(polygon_type& polygon, const point_type& point) {
  530. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  531. points.reserve(size(polygon));
  532. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  533. iter != end_points(polygon); ++iter) {
  534. points.push_back(*iter);
  535. convolve(points.back(), point);
  536. }
  537. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  538. return polygon;
  539. }
  540. /// \relatesalso polygon_with_holes_concept
  541. template <typename polygon_type, typename point_type>
  542. typename enable_if<
  543. typename gtl_and< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type,
  544. typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
  545. polygon_type>::type &
  546. convolve(polygon_type& polygon, const point_type& point) {
  547. typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
  548. hole_type h;
  549. set_points(h, begin_points(polygon), end_points(polygon));
  550. convolve(h, point);
  551. std::vector<hole_type> holes;
  552. holes.reserve(size_holes(polygon));
  553. for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon);
  554. itr != end_holes(polygon); ++itr) {
  555. holes.push_back(*itr);
  556. convolve(holes.back(), point);
  557. }
  558. assign(polygon, h);
  559. set_holes(polygon, holes.begin(), holes.end());
  560. return polygon;
  561. }
  562. /// \relatesalso polygon_concept
  563. template <typename T>
  564. typename enable_if< typename is_any_mutable_polygon_type<T>::type, T>::type &
  565. move(T& polygon, orientation_2d orient, typename polygon_traits<T>::coordinate_type displacement) {
  566. typedef typename polygon_traits<T>::coordinate_type Unit;
  567. if(orient == HORIZONTAL) return convolve(polygon, point_data<Unit>(displacement, Unit(0)));
  568. return convolve(polygon, point_data<Unit>(Unit(0), displacement));
  569. }
  570. /// \relatesalso polygon_concept
  571. /// \brief Applies a transformation to the polygon.
  572. /// \tparam polygon_type A type that models polygon_concept
  573. /// \tparam transform_type A type that may be either axis_transformation or transformation or that overloads point_concept::transform
  574. /// \param polygon The polygon to transform
  575. /// \param tr The transformation to apply
  576. template <typename polygon_type, typename transform_type>
  577. typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
  578. transform(polygon_type& polygon, const transform_type& tr) {
  579. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  580. points.reserve(size(polygon));
  581. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  582. iter != end_points(polygon); ++iter) {
  583. points.push_back(*iter);
  584. transform(points.back(), tr);
  585. }
  586. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  587. return polygon;
  588. }
  589. /// \relatesalso polygon_with_holes_concept
  590. template <typename T, typename transform_type>
  591. typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
  592. transform(T& polygon, const transform_type& tr) {
  593. typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
  594. hole_type h;
  595. set_points(h, begin_points(polygon), end_points(polygon));
  596. transform(h, tr);
  597. std::vector<hole_type> holes;
  598. holes.reserve(size_holes(polygon));
  599. for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
  600. itr != end_holes(polygon); ++itr) {
  601. holes.push_back(*itr);
  602. transform(holes.back(), tr);
  603. }
  604. assign(polygon, h);
  605. set_holes(polygon, holes.begin(), holes.end());
  606. return polygon;
  607. }
  608. template <typename polygon_type>
  609. typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
  610. scale_up(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
  611. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  612. points.reserve(size(polygon));
  613. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  614. iter != end_points(polygon); ++iter) {
  615. points.push_back(*iter);
  616. scale_up(points.back(), factor);
  617. }
  618. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  619. return polygon;
  620. }
  621. template <typename T>
  622. typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
  623. scale_up(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) {
  624. typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
  625. hole_type h;
  626. set_points(h, begin_points(polygon), end_points(polygon));
  627. scale_up(h, factor);
  628. std::vector<hole_type> holes;
  629. holes.reserve(size_holes(polygon));
  630. for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
  631. itr != end_holes(polygon); ++itr) {
  632. holes.push_back(*itr);
  633. scale_up(holes.back(), factor);
  634. }
  635. assign(polygon, h);
  636. set_holes(polygon, holes.begin(), holes.end());
  637. return polygon;
  638. }
  639. //scale non-45 down
  640. template <typename polygon_type>
  641. typename enable_if<
  642. typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
  643. typename gtl_not<typename gtl_same_type
  644. < forty_five_domain,
  645. typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type,
  646. polygon_type>::type &
  647. scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
  648. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  649. points.reserve(size(polygon));
  650. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  651. iter != end_points(polygon); ++iter) {
  652. points.push_back(*iter);
  653. scale_down(points.back(), factor);
  654. }
  655. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  656. return polygon;
  657. }
  658. template <typename Unit>
  659. Unit local_abs(Unit value) { return value < 0 ? (Unit)-value : value; }
  660. template <typename Unit>
  661. void snap_point_vector_to_45(std::vector<point_data<Unit> >& pts) {
  662. typedef point_data<Unit> Point;
  663. if(pts.size() < 3) { pts.clear(); return; }
  664. typename std::vector<point_data<Unit> >::iterator endLocation = std::unique(pts.begin(), pts.end());
  665. if(endLocation != pts.end()){
  666. pts.resize(endLocation - pts.begin());
  667. }
  668. if(pts.back() == pts[0]) pts.pop_back();
  669. //iterate over point triplets
  670. int numPts = pts.size();
  671. bool wrap_around = false;
  672. for(int i = 0; i < numPts; ++i) {
  673. Point& pt1 = pts[i];
  674. Point& pt2 = pts[(i + 1) % numPts];
  675. Point& pt3 = pts[(i + 2) % numPts];
  676. //check if non-45 edge
  677. Unit deltax = x(pt2) - x(pt1);
  678. Unit deltay = y(pt2) - y(pt1);
  679. if(deltax && deltay &&
  680. local_abs(deltax) != local_abs(deltay)) {
  681. //adjust the middle point
  682. Unit ndx = x(pt3) - x(pt2);
  683. Unit ndy = y(pt3) - y(pt2);
  684. if(ndx && ndy) {
  685. Unit diff = local_abs(local_abs(deltax) - local_abs(deltay));
  686. Unit halfdiff = diff/2;
  687. if((deltax > 0 && deltay > 0) ||
  688. (deltax < 0 && deltay < 0)) {
  689. //previous edge is rising slope
  690. if(local_abs(deltax + halfdiff + (diff % 2)) ==
  691. local_abs(deltay - halfdiff)) {
  692. x(pt2, x(pt2) + halfdiff + (diff % 2));
  693. y(pt2, y(pt2) - halfdiff);
  694. } else if(local_abs(deltax - halfdiff - (diff % 2)) ==
  695. local_abs(deltay + halfdiff)) {
  696. x(pt2, x(pt2) - halfdiff - (diff % 2));
  697. y(pt2, y(pt2) + halfdiff);
  698. } else{
  699. //std::cout << "fail1\n";
  700. }
  701. } else {
  702. //previous edge is falling slope
  703. if(local_abs(deltax + halfdiff + (diff % 2)) ==
  704. local_abs(deltay + halfdiff)) {
  705. x(pt2, x(pt2) + halfdiff + (diff % 2));
  706. y(pt2, y(pt2) + halfdiff);
  707. } else if(local_abs(deltax - halfdiff - (diff % 2)) ==
  708. local_abs(deltay - halfdiff)) {
  709. x(pt2, x(pt2) - halfdiff - (diff % 2));
  710. y(pt2, y(pt2) - halfdiff);
  711. } else {
  712. //std::cout << "fail2\n";
  713. }
  714. }
  715. if(i == numPts - 1 && (diff % 2)) {
  716. //we have a wrap around effect
  717. if(!wrap_around) {
  718. wrap_around = true;
  719. i = -1;
  720. }
  721. }
  722. } else if(ndx) {
  723. //next edge is horizontal
  724. //find the x value for pt1 that would make the abs(deltax) == abs(deltay)
  725. Unit newDeltaX = local_abs(deltay);
  726. if(deltax < 0) newDeltaX *= -1;
  727. x(pt2, x(pt1) + newDeltaX);
  728. } else { //ndy
  729. //next edge is vertical
  730. //find the y value for pt1 that would make the abs(deltax) == abs(deltay)
  731. Unit newDeltaY = local_abs(deltax);
  732. if(deltay < 0) newDeltaY *= -1;
  733. y(pt2, y(pt1) + newDeltaY);
  734. }
  735. }
  736. }
  737. }
  738. template <typename polygon_type>
  739. typename enable_if< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type, polygon_type>::type &
  740. snap_to_45(polygon_type& polygon) {
  741. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  742. points.reserve(size(polygon));
  743. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  744. iter != end_points(polygon); ++iter) {
  745. points.push_back(*iter);
  746. }
  747. snap_point_vector_to_45(points);
  748. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  749. return polygon;
  750. }
  751. template <typename polygon_type>
  752. typename enable_if< typename is_any_mutable_polygon_with_holes_type<polygon_type>::type, polygon_type>::type &
  753. snap_to_45(polygon_type& polygon) {
  754. typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
  755. hole_type h;
  756. set_points(h, begin_points(polygon), end_points(polygon));
  757. snap_to_45(h);
  758. std::vector<hole_type> holes;
  759. holes.reserve(size_holes(polygon));
  760. for(typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itr = begin_holes(polygon);
  761. itr != end_holes(polygon); ++itr) {
  762. holes.push_back(*itr);
  763. snap_to_45(holes.back());
  764. }
  765. assign(polygon, h);
  766. set_holes(polygon, holes.begin(), holes.end());
  767. return polygon;
  768. }
  769. //scale specifically 45 down
  770. template <typename polygon_type>
  771. typename enable_if<
  772. typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
  773. typename gtl_same_type
  774. < forty_five_domain,
  775. typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type,
  776. polygon_type>::type &
  777. scale_down(polygon_type& polygon, typename coordinate_traits<typename polygon_traits<polygon_type>::coordinate_type>::unsigned_area_type factor) {
  778. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  779. points.reserve(size(polygon));
  780. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  781. iter != end_points(polygon); ++iter) {
  782. points.push_back(*iter);
  783. scale_down(points.back(), factor);
  784. }
  785. snap_point_vector_to_45(points);
  786. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  787. return polygon;
  788. }
  789. template <typename T>
  790. typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type, T>::type &
  791. scale_down(T& polygon, typename coordinate_traits<typename polygon_traits<T>::coordinate_type>::unsigned_area_type factor) {
  792. typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
  793. hole_type h;
  794. set_points(h, begin_points(polygon), end_points(polygon));
  795. scale_down(h, factor);
  796. std::vector<hole_type> holes;
  797. holes.reserve(size_holes(polygon));
  798. for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
  799. itr != end_holes(polygon); ++itr) {
  800. holes.push_back(*itr);
  801. scale_down(holes.back(), factor);
  802. }
  803. assign(polygon, h);
  804. set_holes(polygon, holes.begin(), holes.end());
  805. return polygon;
  806. }
  807. //scale non-45
  808. template <typename polygon_type>
  809. typename enable_if<
  810. typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
  811. typename gtl_not<typename gtl_same_type
  812. < forty_five_domain,
  813. typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type,
  814. polygon_type>::type &
  815. scale(polygon_type& polygon, double factor) {
  816. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  817. points.reserve(size(polygon));
  818. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  819. iter != end_points(polygon); ++iter) {
  820. points.push_back(*iter);
  821. scale(points.back(), anisotropic_scale_factor<double>(factor, factor));
  822. }
  823. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  824. return polygon;
  825. }
  826. //scale specifically 45
  827. template <typename polygon_type>
  828. polygon_type&
  829. scale(polygon_type& polygon, double factor,
  830. typename enable_if<
  831. typename gtl_and< typename is_any_mutable_polygon_without_holes_type<polygon_type>::type,
  832. typename gtl_same_type
  833. < forty_five_domain,
  834. typename geometry_domain<typename geometry_concept<polygon_type>::type>::type>::type>::type>::type * = 0
  835. ) {
  836. std::vector<typename std::iterator_traits<typename polygon_traits<polygon_type>::iterator_type>::value_type> points;
  837. points.reserve(size(polygon));
  838. for(typename polygon_traits<polygon_type>::iterator_type iter = begin_points(polygon);
  839. iter != end_points(polygon); ++iter) {
  840. points.push_back(*iter);
  841. scale(points.back(), anisotropic_scale_factor<double>(factor, factor));
  842. }
  843. snap_point_vector_to_45(points);
  844. polygon_mutable_traits<polygon_type>::set_points(polygon, points.begin(), points.end());
  845. return polygon;
  846. }
  847. template <typename T>
  848. T&
  849. scale(T& polygon, double factor,
  850. typename enable_if< typename is_any_mutable_polygon_with_holes_type<T>::type>::type * = 0
  851. ) {
  852. typedef typename polygon_with_holes_traits<T>::hole_type hole_type;
  853. hole_type h;
  854. set_points(h, begin_points(polygon), end_points(polygon));
  855. scale(h, factor);
  856. std::vector<hole_type> holes;
  857. holes.reserve(size_holes(polygon));
  858. for(typename polygon_with_holes_traits<T>::iterator_holes_type itr = begin_holes(polygon);
  859. itr != end_holes(polygon); ++itr) {
  860. holes.push_back(*itr);
  861. scale(holes.back(), factor);
  862. }
  863. assign(polygon, h);
  864. set_holes(polygon, holes.begin(), holes.end());
  865. return polygon;
  866. }
  867. template <typename iterator_type, typename area_type>
  868. static area_type
  869. point_sequence_area(iterator_type begin_range, iterator_type end_range) {
  870. typedef typename std::iterator_traits<iterator_type>::value_type point_type;
  871. typedef typename point_traits<point_type>::coordinate_type Unit;
  872. if(begin_range == end_range) return area_type(0);
  873. point_type first = *begin_range;
  874. point_type previous = first;
  875. ++begin_range;
  876. // Initialize trapezoid base line
  877. area_type y_base = (area_type)y(first);
  878. // Initialize area accumulator
  879. area_type area(0);
  880. while (begin_range != end_range) {
  881. area_type x1 = (area_type)x(previous);
  882. area_type x2 = (area_type)x(*begin_range);
  883. #ifdef BOOST_POLYGON_ICC
  884. #pragma warning (push)
  885. #pragma warning (disable:1572)
  886. #endif
  887. if(x1 != x2) {
  888. #ifdef BOOST_POLYGON_ICC
  889. #pragma warning (pop)
  890. #endif
  891. // do trapezoid area accumulation
  892. area += (x2 - x1) * (((area_type)y(*begin_range) - y_base) +
  893. ((area_type)y(previous) - y_base)) / 2;
  894. }
  895. previous = *begin_range;
  896. // go to next point
  897. ++begin_range;
  898. }
  899. //wrap around to evaluate the edge between first and last if not closed
  900. if(!equivalence(first, previous)) {
  901. area_type x1 = (area_type)x(previous);
  902. area_type x2 = (area_type)x(first);
  903. area += (x2 - x1) * (((area_type)y(first) - y_base) +
  904. ((area_type)y(previous) - y_base)) / 2;
  905. }
  906. return area;
  907. }
  908. template <typename T>
  909. typename enable_if<
  910. typename is_polygon_with_holes_type<T>::type,
  911. typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
  912. typename polygon_traits<T>::coordinate_type>::type>::type
  913. area(const T& polygon) {
  914. typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
  915. typename polygon_traits<T>::coordinate_type>::type area_type;
  916. area_type retval = point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>
  917. (begin_points(polygon), end_points(polygon));
  918. if(retval < 0) retval *= -1;
  919. for(typename polygon_with_holes_traits<T>::iterator_holes_type itr =
  920. polygon_with_holes_traits<T>::begin_holes(polygon);
  921. itr != polygon_with_holes_traits<T>::end_holes(polygon); ++itr) {
  922. area_type tmp_area = point_sequence_area
  923. <typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type, area_type>
  924. (begin_points(*itr), end_points(*itr));
  925. if(tmp_area < 0) tmp_area *= -1;
  926. retval -= tmp_area;
  927. }
  928. return retval;
  929. }
  930. template <typename iT>
  931. bool point_sequence_is_45(iT itr, iT itr_end) {
  932. typedef typename std::iterator_traits<iT>::value_type Point;
  933. typedef typename point_traits<Point>::coordinate_type Unit;
  934. if(itr == itr_end) return true;
  935. Point firstPt = *itr;
  936. Point prevPt = firstPt;
  937. ++itr;
  938. while(itr != itr_end) {
  939. Point pt = *itr;
  940. Unit deltax = x(pt) - x(prevPt);
  941. Unit deltay = y(pt) - y(prevPt);
  942. if(deltax && deltay &&
  943. local_abs(deltax) != local_abs(deltay))
  944. return false;
  945. prevPt = pt;
  946. ++itr;
  947. }
  948. Unit deltax = x(firstPt) - x(prevPt);
  949. Unit deltay = y(firstPt) - y(prevPt);
  950. if(deltax && deltay &&
  951. local_abs(deltax) != local_abs(deltay))
  952. return false;
  953. return true;
  954. }
  955. template <typename polygon_type>
  956. typename enable_if< typename is_polygon_with_holes_type<polygon_type>::type, bool>::type
  957. is_45(const polygon_type& polygon) {
  958. typename polygon_traits<polygon_type>::iterator_type itr = begin_points(polygon), itr_end = end_points(polygon);
  959. if(!point_sequence_is_45(itr, itr_end)) return false;
  960. typename polygon_with_holes_traits<polygon_type>::iterator_holes_type itrh = begin_holes(polygon), itrh_end = end_holes(polygon);
  961. typedef typename polygon_with_holes_traits<polygon_type>::hole_type hole_type;
  962. for(; itrh != itrh_end; ++ itrh) {
  963. typename polygon_traits<hole_type>::iterator_type itr1 = begin_points(polygon), itr1_end = end_points(polygon);
  964. if(!point_sequence_is_45(itr1, itr1_end)) return false;
  965. }
  966. return true;
  967. }
  968. template <typename distance_type, typename iterator_type>
  969. distance_type point_sequence_distance(iterator_type itr, iterator_type itr_end) {
  970. typedef distance_type Unit;
  971. typedef iterator_type iterator;
  972. typedef typename std::iterator_traits<iterator>::value_type point_type;
  973. Unit return_value = Unit(0);
  974. point_type previous_point, first_point;
  975. if(itr == itr_end) return return_value;
  976. previous_point = first_point = *itr;
  977. ++itr;
  978. for( ; itr != itr_end; ++itr) {
  979. point_type current_point = *itr;
  980. return_value += (Unit)euclidean_distance(current_point, previous_point);
  981. previous_point = current_point;
  982. }
  983. return_value += (Unit)euclidean_distance(previous_point, first_point);
  984. return return_value;
  985. }
  986. template <typename T>
  987. typename distance_type_by_domain
  988. <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type
  989. perimeter(const T& polygon,
  990. typename enable_if<
  991. typename is_polygon_with_holes_type<T>::type>::type * = 0
  992. ) {
  993. typedef typename distance_type_by_domain
  994. <typename geometry_domain<typename geometry_concept<T>::type>::type, typename polygon_traits<T>::coordinate_type>::type Unit;
  995. typedef typename polygon_traits<T>::iterator_type iterator;
  996. iterator itr = begin_points(polygon);
  997. iterator itr_end = end_points(polygon);
  998. Unit return_value = point_sequence_distance<Unit, iterator>(itr, itr_end);
  999. for(typename polygon_with_holes_traits<T>::iterator_holes_type itr_holes = begin_holes(polygon);
  1000. itr_holes != end_holes(polygon); ++itr_holes) {
  1001. typedef typename polygon_traits<typename polygon_with_holes_traits<T>::hole_type>::iterator_type hitertype;
  1002. return_value += point_sequence_distance<Unit, hitertype>(begin_points(*itr_holes), end_points(*itr_holes));
  1003. }
  1004. return return_value;
  1005. }
  1006. template <typename T>
  1007. typename enable_if <typename is_polygon_with_holes_type<T>::type,
  1008. direction_1d>::type
  1009. winding(const T& polygon) {
  1010. winding_direction wd = polygon_traits<T>::winding(polygon);
  1011. if(wd != unknown_winding) {
  1012. return wd == clockwise_winding ? CLOCKWISE: COUNTERCLOCKWISE;
  1013. }
  1014. typedef typename area_type_by_domain< typename geometry_domain<typename geometry_concept<T>::type>::type,
  1015. typename polygon_traits<T>::coordinate_type>::type area_type;
  1016. return point_sequence_area<typename polygon_traits<T>::iterator_type, area_type>(begin_points(polygon), end_points(polygon)) < 0 ?
  1017. COUNTERCLOCKWISE : CLOCKWISE;
  1018. }
  1019. template <typename T, typename input_point_type>
  1020. typename enable_if<
  1021. typename gtl_and< typename is_polygon_90_type<T>::type,
  1022. typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
  1023. bool>::type
  1024. contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
  1025. typedef T polygon_type;
  1026. typedef typename polygon_traits<polygon_type>::coordinate_type coordinate_type;
  1027. typedef typename polygon_traits<polygon_type>::iterator_type iterator;
  1028. typedef typename std::iterator_traits<iterator>::value_type point_type;
  1029. coordinate_type point_x = x(point);
  1030. coordinate_type point_y = y(point);
  1031. bool inside = false;
  1032. for (iterator iter = begin_points(polygon); iter != end_points(polygon);) {
  1033. point_type curr_point = *iter;
  1034. ++iter;
  1035. point_type next_point = (iter == end_points(polygon)) ? *begin_points(polygon) : *iter;
  1036. if (x(curr_point) == x(next_point)) {
  1037. if (x(curr_point) > point_x) {
  1038. continue;
  1039. }
  1040. coordinate_type min_y = (std::min)(y(curr_point), y(next_point));
  1041. coordinate_type max_y = (std::max)(y(curr_point), y(next_point));
  1042. if (point_y > min_y && point_y < max_y) {
  1043. if (x(curr_point) == point_x) {
  1044. return consider_touch;
  1045. }
  1046. inside ^= true;
  1047. }
  1048. } else {
  1049. coordinate_type min_x = (std::min)(x(curr_point), x(next_point));
  1050. coordinate_type max_x = (std::max)(x(curr_point), x(next_point));
  1051. if (point_x >= min_x && point_x <= max_x) {
  1052. if (y(curr_point) == point_y) {
  1053. return consider_touch;
  1054. }
  1055. }
  1056. }
  1057. }
  1058. return inside;
  1059. }
  1060. //TODO: refactor to expose as user APIs
  1061. template <typename Unit>
  1062. struct edge_utils {
  1063. typedef point_data<Unit> Point;
  1064. typedef std::pair<Point, Point> half_edge;
  1065. class less_point : public std::binary_function<Point, Point, bool> {
  1066. public:
  1067. inline less_point() {}
  1068. inline bool operator () (const Point& pt1, const Point& pt2) const {
  1069. if(pt1.get(HORIZONTAL) < pt2.get(HORIZONTAL)) return true;
  1070. if(pt1.get(HORIZONTAL) == pt2.get(HORIZONTAL)) {
  1071. if(pt1.get(VERTICAL) < pt2.get(VERTICAL)) return true;
  1072. }
  1073. return false;
  1074. }
  1075. };
  1076. static inline bool between(Point pt, Point pt1, Point pt2) {
  1077. less_point lp;
  1078. if(lp(pt1, pt2))
  1079. return lp(pt, pt2) && lp(pt1, pt);
  1080. return lp(pt, pt1) && lp(pt2, pt);
  1081. }
  1082. template <typename area_type>
  1083. static inline bool equal_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
  1084. typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
  1085. unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
  1086. unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
  1087. int dx1_sign = dx1 < 0 ? -1 : 1;
  1088. int dx2_sign = dx2 < 0 ? -1 : 1;
  1089. int dy1_sign = dy1 < 0 ? -1 : 1;
  1090. int dy2_sign = dy2 < 0 ? -1 : 1;
  1091. int cross_1_sign = dx2_sign * dy1_sign;
  1092. int cross_2_sign = dx1_sign * dy2_sign;
  1093. return cross_1 == cross_2 && (cross_1_sign == cross_2_sign || cross_1 == 0);
  1094. }
  1095. static inline bool equal_slope(const Unit& x, const Unit& y,
  1096. const Point& pt1, const Point& pt2) {
  1097. const Point* pts[2] = {&pt1, &pt2};
  1098. typedef typename coordinate_traits<Unit>::manhattan_area_type at;
  1099. at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
  1100. at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
  1101. at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
  1102. at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
  1103. return equal_slope(dx1, dy1, dx2, dy2);
  1104. }
  1105. template <typename area_type>
  1106. static inline bool less_slope(area_type dx1, area_type dy1, area_type dx2, area_type dy2) {
  1107. //reflext x and y slopes to right hand side half plane
  1108. if(dx1 < 0) {
  1109. dy1 *= -1;
  1110. dx1 *= -1;
  1111. } else if(dx1 == 0) {
  1112. //if the first slope is vertical the first cannot be less
  1113. return false;
  1114. }
  1115. if(dx2 < 0) {
  1116. dy2 *= -1;
  1117. dx2 *= -1;
  1118. } else if(dx2 == 0) {
  1119. //if the second slope is vertical the first is always less unless it is also vertical, in which case they are equal
  1120. return dx1 != 0;
  1121. }
  1122. typedef typename coordinate_traits<Unit>::unsigned_area_type unsigned_product_type;
  1123. unsigned_product_type cross_1 = (unsigned_product_type)(dx2 < 0 ? -dx2 :dx2) * (unsigned_product_type)(dy1 < 0 ? -dy1 : dy1);
  1124. unsigned_product_type cross_2 = (unsigned_product_type)(dx1 < 0 ? -dx1 :dx1) * (unsigned_product_type)(dy2 < 0 ? -dy2 : dy2);
  1125. int dx1_sign = dx1 < 0 ? -1 : 1;
  1126. int dx2_sign = dx2 < 0 ? -1 : 1;
  1127. int dy1_sign = dy1 < 0 ? -1 : 1;
  1128. int dy2_sign = dy2 < 0 ? -1 : 1;
  1129. int cross_1_sign = dx2_sign * dy1_sign;
  1130. int cross_2_sign = dx1_sign * dy2_sign;
  1131. if(cross_1_sign < cross_2_sign) return true;
  1132. if(cross_2_sign < cross_1_sign) return false;
  1133. if(cross_1_sign == -1) return cross_2 < cross_1;
  1134. return cross_1 < cross_2;
  1135. }
  1136. static inline bool less_slope(const Unit& x, const Unit& y,
  1137. const Point& pt1, const Point& pt2) {
  1138. const Point* pts[2] = {&pt1, &pt2};
  1139. //compute y value on edge from pt_ to pts[1] at the x value of pts[0]
  1140. typedef typename coordinate_traits<Unit>::manhattan_area_type at;
  1141. at dy2 = (at)pts[1]->get(VERTICAL) - (at)y;
  1142. at dy1 = (at)pts[0]->get(VERTICAL) - (at)y;
  1143. at dx2 = (at)pts[1]->get(HORIZONTAL) - (at)x;
  1144. at dx1 = (at)pts[0]->get(HORIZONTAL) - (at)x;
  1145. return less_slope(dx1, dy1, dx2, dy2);
  1146. }
  1147. //return -1 below, 0 on and 1 above line
  1148. //assumes point is on x interval of segment
  1149. static inline int on_above_or_below(Point pt, const half_edge& he) {
  1150. if(pt == he.first || pt == he.second) return 0;
  1151. if(equal_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second)) return 0;
  1152. bool less_result = less_slope(pt.get(HORIZONTAL), pt.get(VERTICAL), he.first, he.second);
  1153. int retval = less_result ? -1 : 1;
  1154. less_point lp;
  1155. if(lp(he.second, he.first)) retval *= -1;
  1156. if(!between(pt, he.first, he.second)) retval *= -1;
  1157. return retval;
  1158. }
  1159. };
  1160. template <typename T, typename input_point_type>
  1161. typename enable_if<
  1162. typename gtl_and< typename is_any_mutable_polygon_with_holes_type<T>::type,
  1163. typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
  1164. bool>::type
  1165. contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
  1166. typedef typename polygon_with_holes_traits<T>::iterator_holes_type holes_iterator;
  1167. bool isInside = contains( view_as< typename polygon_from_polygon_with_holes_type<
  1168. typename geometry_concept<T>::type>::type>( polygon ), point, consider_touch );
  1169. if(!isInside) return false; //no need to check holes
  1170. holes_iterator itH = begin_holes( polygon );
  1171. while( itH != end_holes( polygon ) ) {
  1172. if( contains( *itH, point, !consider_touch ) ) {
  1173. isInside = false;
  1174. break;
  1175. }
  1176. ++itH;
  1177. }
  1178. return isInside;
  1179. }
  1180. template <typename T, typename input_point_type>
  1181. typename enable_if<
  1182. typename gtl_and_3<
  1183. typename is_polygon_type<T>::type,
  1184. typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type,
  1185. typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
  1186. bool>::type
  1187. contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
  1188. typedef typename point_traits<input_point_type>::coordinate_type Unit;
  1189. typedef point_data<Unit> Point;
  1190. typedef std::pair<Point, Point> half_edge;
  1191. typedef typename polygon_traits<T>::iterator_type iterator;
  1192. iterator itr = begin_points(polygon);
  1193. iterator itrEnd = end_points(polygon);
  1194. half_edge he;
  1195. if(itr == itrEnd) return false;
  1196. assign(he.first, *itr);
  1197. Point firstPt;
  1198. assign(firstPt, *itr);
  1199. ++itr;
  1200. if(itr == itrEnd) return false;
  1201. bool done = false;
  1202. int above = 0;
  1203. while(!done) {
  1204. Point currentPt;
  1205. if(itr == itrEnd) {
  1206. done = true;
  1207. currentPt = firstPt;
  1208. } else {
  1209. assign(currentPt, *itr);
  1210. ++itr;
  1211. }
  1212. if(currentPt == he.first) {
  1213. continue;
  1214. } else {
  1215. he.second = currentPt;
  1216. if(equivalence(point, currentPt)) return consider_touch;
  1217. Unit xmin = (std::min)(x(he.first), x(he.second));
  1218. Unit xmax = (std::max)(x(he.first), x(he.second));
  1219. if(x(point) >= xmin && x(point) < xmax) { //double counts if <= xmax
  1220. Point tmppt;
  1221. assign(tmppt, point);
  1222. int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he);
  1223. if(oabedge == 0) return consider_touch;
  1224. if(oabedge == 1) ++above;
  1225. } else if(x(point) == xmax) {
  1226. if(x(point) == xmin) {
  1227. Unit ymin = (std::min)(y(he.first), y(he.second));
  1228. Unit ymax = (std::max)(y(he.first), y(he.second));
  1229. Unit ypt = y(point);
  1230. if(ypt <= ymax && ypt >= ymin)
  1231. return consider_touch;
  1232. } else {
  1233. Point tmppt;
  1234. assign(tmppt, point);
  1235. if( edge_utils<Unit>::on_above_or_below(tmppt, he) == 0 ) {
  1236. return consider_touch;
  1237. }
  1238. }
  1239. }
  1240. }
  1241. he.first = he.second;
  1242. }
  1243. return above % 2 != 0; //if the point is above an odd number of edges is must be inside polygon
  1244. }
  1245. /*
  1246. template <typename T, typename input_point_type>
  1247. typename enable_if<
  1248. typename gtl_and_3<
  1249. typename is_polygon_with_holes_type<T>::type,
  1250. typename gtl_different_type<typename geometry_domain<typename geometry_concept<T>::type>::type, manhattan_domain>::type,
  1251. typename gtl_same_type<typename geometry_concept<input_point_type>::type, point_concept>::type>::type,
  1252. bool>::type
  1253. contains(const T& polygon, const input_point_type& point, bool consider_touch = true) {
  1254. typedef typename point_traits<input_point_type>::coordinate_type Unit;
  1255. typedef point_data<Unit> Point;
  1256. typedef std::pair<Point, Point> half_edge;
  1257. typedef typename polygon_traits<T>::iterator_type iterator;
  1258. iterator itr = begin_points(polygon);
  1259. iterator itrEnd = end_points(polygon);
  1260. half_edge he;
  1261. if(itr == itrEnd) return false;
  1262. assign(he.first, *itr);
  1263. Point firstPt;
  1264. assign(firstPt, *itr);
  1265. ++itr;
  1266. if(itr == itrEnd) return false;
  1267. bool done = false;
  1268. int above = 0;
  1269. while(!done) {
  1270. Point currentPt;
  1271. if(itr == itrEnd) {
  1272. done = true;
  1273. currentPt = firstPt;
  1274. } else {
  1275. assign(currentPt, *itr);
  1276. ++itr;
  1277. }
  1278. if(currentPt == he.first) {
  1279. continue;
  1280. } else {
  1281. he.second = currentPt;
  1282. if(equivalence(point, currentPt)) return consider_touch;
  1283. Unit xmin = (std::min)(x(he.first), x(he.second));
  1284. Unit xmax = (std::max)(x(he.first), x(he.second));
  1285. if(x(point) >= xmin && x(point) < xmax) { //double counts if <= xmax
  1286. Point tmppt;
  1287. assign(tmppt, point);
  1288. int oabedge = edge_utils<Unit>::on_above_or_below(tmppt, he);
  1289. if(oabedge == 0) return consider_touch;
  1290. if(oabedge == 1) ++above;
  1291. }
  1292. }
  1293. he.first = he.second;
  1294. }
  1295. return above % 2 != 0; //if the point is above an odd number of edges is must be inside polygon
  1296. }
  1297. */
  1298. template <typename T1, typename T2>
  1299. typename enable_if<
  1300. typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type,
  1301. typename is_polygon_with_holes_type<T2>::type>::type,
  1302. bool>::type
  1303. center(T1& center_point, const T2& polygon) {
  1304. typedef typename polygon_traits<T2>::coordinate_type coordinate_type;
  1305. rectangle_data<coordinate_type> bbox;
  1306. extents(bbox, polygon);
  1307. return center(center_point, bbox);
  1308. }
  1309. template <typename T1, typename T2>
  1310. typename enable_if<
  1311. typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<T1>::type>::type,
  1312. typename is_polygon_with_holes_type<T2>::type>::type,
  1313. bool>::type
  1314. extents(T1& bounding_box, const T2& polygon) {
  1315. typedef typename polygon_traits<T2>::iterator_type iterator;
  1316. bool first_iteration = true;
  1317. iterator itr_end = end_points(polygon);
  1318. for(iterator itr = begin_points(polygon); itr != itr_end; ++itr) {
  1319. if(first_iteration) {
  1320. set_points(bounding_box, *itr, *itr);
  1321. first_iteration = false;
  1322. } else {
  1323. encompass(bounding_box, *itr);
  1324. }
  1325. }
  1326. if(first_iteration) return false;
  1327. return true;
  1328. }
  1329. template <class T>
  1330. template <class T2>
  1331. polygon_90_data<T>& polygon_90_data<T>::operator=(const T2& rvalue) {
  1332. assign(*this, rvalue);
  1333. return *this;
  1334. }
  1335. template <class T>
  1336. template <class T2>
  1337. polygon_45_data<T>& polygon_45_data<T>::operator=(const T2& rvalue) {
  1338. assign(*this, rvalue);
  1339. return *this;
  1340. }
  1341. template <class T>
  1342. template <class T2>
  1343. polygon_data<T>& polygon_data<T>::operator=(const T2& rvalue) {
  1344. assign(*this, rvalue);
  1345. return *this;
  1346. }
  1347. template <class T>
  1348. template <class T2>
  1349. polygon_90_with_holes_data<T>& polygon_90_with_holes_data<T>::operator=(const T2& rvalue) {
  1350. assign(*this, rvalue);
  1351. return *this;
  1352. }
  1353. template <class T>
  1354. template <class T2>
  1355. polygon_45_with_holes_data<T>& polygon_45_with_holes_data<T>::operator=(const T2& rvalue) {
  1356. assign(*this, rvalue);
  1357. return *this;
  1358. }
  1359. template <class T>
  1360. template <class T2>
  1361. polygon_with_holes_data<T>& polygon_with_holes_data<T>::operator=(const T2& rvalue) {
  1362. assign(*this, rvalue);
  1363. return *this;
  1364. }
  1365. template <typename T>
  1366. struct geometry_concept<polygon_data<T> > {
  1367. typedef polygon_concept type;
  1368. };
  1369. template <typename T>
  1370. struct geometry_concept<polygon_45_data<T> > {
  1371. typedef polygon_45_concept type;
  1372. };
  1373. template <typename T>
  1374. struct geometry_concept<polygon_90_data<T> > {
  1375. typedef polygon_90_concept type;
  1376. };
  1377. template <typename T>
  1378. struct geometry_concept<polygon_with_holes_data<T> > {
  1379. typedef polygon_with_holes_concept type;
  1380. };
  1381. template <typename T>
  1382. struct geometry_concept<polygon_45_with_holes_data<T> > {
  1383. typedef polygon_45_with_holes_concept type;
  1384. };
  1385. template <typename T>
  1386. struct geometry_concept<polygon_90_with_holes_data<T> > {
  1387. typedef polygon_90_with_holes_concept type;
  1388. };
  1389. // template <typename T> struct polygon_with_holes_traits<polygon_90_data<T> > {
  1390. // typedef polygon_90_data<T> hole_type;
  1391. // typedef const hole_type* iterator_holes_type;
  1392. // static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
  1393. // static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
  1394. // static inline std::size_t size_holes(const hole_type& t) { return 0; }
  1395. // };
  1396. // template <typename T> struct polygon_with_holes_traits<polygon_45_data<T> > {
  1397. // typedef polygon_45_data<T> hole_type;
  1398. // typedef const hole_type* iterator_holes_type;
  1399. // static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
  1400. // static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
  1401. // static inline std::size_t size_holes(const hole_type& t) { return 0; }
  1402. // };
  1403. // template <typename T> struct polygon_with_holes_traits<polygon_data<T> > {
  1404. // typedef polygon_data<T> hole_type;
  1405. // typedef const hole_type* iterator_holes_type;
  1406. // static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
  1407. // static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
  1408. // static inline std::size_t size_holes(const hole_type& t) { return 0; }
  1409. // };
  1410. template <typename T> struct get_void {};
  1411. template <> struct get_void<gtl_yes> { typedef void type; };
  1412. template <typename T> struct polygon_with_holes_traits<
  1413. T, typename get_void<typename is_any_mutable_polygon_without_holes_type<T>::type>::type > {
  1414. typedef T hole_type;
  1415. typedef const hole_type* iterator_holes_type;
  1416. static inline iterator_holes_type begin_holes(const hole_type& t) { return &t; }
  1417. static inline iterator_holes_type end_holes(const hole_type& t) { return &t; }
  1418. static inline std::size_t size_holes(const hole_type& t) { return 0; }
  1419. };
  1420. template <typename T>
  1421. struct view_of<rectangle_concept, T> {
  1422. typedef typename polygon_traits<T>::coordinate_type coordinate_type;
  1423. typedef interval_data<coordinate_type> interval_type;
  1424. rectangle_data<coordinate_type> rect;
  1425. view_of(const T& obj) : rect() {
  1426. point_data<coordinate_type> pts[2];
  1427. typename polygon_traits<T>::iterator_type itr =
  1428. begin_points(obj), itre = end_points(obj);
  1429. if(itr == itre) return;
  1430. assign(pts[0], *itr);
  1431. ++itr;
  1432. if(itr == itre) return;
  1433. ++itr;
  1434. if(itr == itre) return;
  1435. assign(pts[1], *itr);
  1436. set_points(rect, pts[0], pts[1]);
  1437. }
  1438. inline interval_type get(orientation_2d orient) const {
  1439. return rect.get(orient); }
  1440. };
  1441. template <typename T>
  1442. struct geometry_concept<view_of<rectangle_concept, T> > {
  1443. typedef rectangle_concept type;
  1444. };
  1445. template <typename T>
  1446. struct view_of<polygon_45_concept, T> {
  1447. const T* t;
  1448. view_of(const T& obj) : t(&obj) {}
  1449. typedef typename polygon_traits<T>::coordinate_type coordinate_type;
  1450. typedef typename polygon_traits<T>::iterator_type iterator_type;
  1451. typedef typename polygon_traits<T>::point_type point_type;
  1452. /// Get the begin iterator
  1453. inline iterator_type begin() const {
  1454. return polygon_traits<T>::begin_points(*t);
  1455. }
  1456. /// Get the end iterator
  1457. inline iterator_type end() const {
  1458. return polygon_traits<T>::end_points(*t);
  1459. }
  1460. /// Get the number of sides of the polygon
  1461. inline std::size_t size() const {
  1462. return polygon_traits<T>::size(*t);
  1463. }
  1464. /// Get the winding direction of the polygon
  1465. inline winding_direction winding() const {
  1466. return polygon_traits<T>::winding(*t);
  1467. }
  1468. };
  1469. template <typename T>
  1470. struct geometry_concept<view_of<polygon_45_concept, T> > {
  1471. typedef polygon_45_concept type;
  1472. };
  1473. template <typename T>
  1474. struct view_of<polygon_90_concept, T> {
  1475. const T* t;
  1476. view_of(const T& obj) : t(&obj) {}
  1477. typedef typename polygon_traits<T>::coordinate_type coordinate_type;
  1478. typedef typename polygon_traits<T>::iterator_type iterator_type;
  1479. typedef typename polygon_traits<T>::point_type point_type;
  1480. typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
  1481. /// Get the begin iterator
  1482. inline compact_iterator_type begin_compact() const {
  1483. return compact_iterator_type(polygon_traits<T>::begin_points(*t),
  1484. polygon_traits<T>::end_points(*t));
  1485. }
  1486. /// Get the end iterator
  1487. inline compact_iterator_type end_compact() const {
  1488. return compact_iterator_type(polygon_traits<T>::end_points(*t),
  1489. polygon_traits<T>::end_points(*t));
  1490. }
  1491. /// Get the number of sides of the polygon
  1492. inline std::size_t size() const {
  1493. return polygon_traits<T>::size(*t);
  1494. }
  1495. /// Get the winding direction of the polygon
  1496. inline winding_direction winding() const {
  1497. return polygon_traits<T>::winding(*t);
  1498. }
  1499. };
  1500. template <typename T>
  1501. struct geometry_concept<view_of<polygon_90_concept, T> > {
  1502. typedef polygon_90_concept type;
  1503. };
  1504. template <typename T>
  1505. struct view_of<polygon_45_with_holes_concept, T> {
  1506. const T* t;
  1507. view_of(const T& obj) : t(&obj) {}
  1508. typedef typename polygon_traits<T>::coordinate_type coordinate_type;
  1509. typedef typename polygon_traits<T>::iterator_type iterator_type;
  1510. typedef typename polygon_traits<T>::point_type point_type;
  1511. typedef view_of<polygon_45_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type;
  1512. struct iterator_holes_type {
  1513. typedef std::forward_iterator_tag iterator_category;
  1514. typedef hole_type value_type;
  1515. typedef std::ptrdiff_t difference_type;
  1516. typedef const hole_type* pointer; //immutable
  1517. typedef const hole_type& reference; //immutable
  1518. typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht;
  1519. iht internal_itr;
  1520. iterator_holes_type() : internal_itr() {}
  1521. iterator_holes_type(iht iht_in) : internal_itr(iht_in) {}
  1522. inline iterator_holes_type& operator++() {
  1523. ++internal_itr;
  1524. return *this;
  1525. }
  1526. inline const iterator_holes_type operator++(int) {
  1527. iterator_holes_type tmp(*this);
  1528. ++(*this);
  1529. return tmp;
  1530. }
  1531. inline bool operator==(const iterator_holes_type& that) const {
  1532. return (internal_itr == that.internal_itr);
  1533. }
  1534. inline bool operator!=(const iterator_holes_type& that) const {
  1535. return (internal_itr != that.internal_itr);
  1536. }
  1537. inline value_type operator*() const {
  1538. return view_as<polygon_45_concept>(*internal_itr);
  1539. }
  1540. };
  1541. /// Get the begin iterator
  1542. inline iterator_type begin() const {
  1543. return polygon_traits<T>::begin_points(*t);
  1544. }
  1545. /// Get the end iterator
  1546. inline iterator_type end() const {
  1547. return polygon_traits<T>::end_points(*t);
  1548. }
  1549. /// Get the number of sides of the polygon
  1550. inline std::size_t size() const {
  1551. return polygon_traits<T>::size(*t);
  1552. }
  1553. /// Get the winding direction of the polygon
  1554. inline winding_direction winding() const {
  1555. return polygon_traits<T>::winding(*t);
  1556. }
  1557. /// Get the begin iterator
  1558. inline iterator_holes_type begin_holes() const {
  1559. return polygon_with_holes_traits<T>::begin_holes(*t);
  1560. }
  1561. /// Get the end iterator
  1562. inline iterator_holes_type end_holes() const {
  1563. return polygon_with_holes_traits<T>::end_holes(*t);
  1564. }
  1565. /// Get the number of sides of the polygon
  1566. inline std::size_t size_holes() const {
  1567. return polygon_with_holes_traits<T>::size_holes(*t);
  1568. }
  1569. };
  1570. template <typename T>
  1571. struct geometry_concept<view_of<polygon_45_with_holes_concept, T> > {
  1572. typedef polygon_45_with_holes_concept type;
  1573. };
  1574. template <typename T>
  1575. struct view_of<polygon_90_with_holes_concept, T> {
  1576. const T* t;
  1577. view_of(const T& obj) : t(&obj) {}
  1578. typedef typename polygon_traits<T>::coordinate_type coordinate_type;
  1579. typedef typename polygon_traits<T>::iterator_type iterator_type;
  1580. typedef typename polygon_traits<T>::point_type point_type;
  1581. typedef iterator_points_to_compact<iterator_type, point_type> compact_iterator_type;
  1582. typedef view_of<polygon_90_concept, typename polygon_with_holes_traits<T>::hole_type> hole_type;
  1583. struct iterator_holes_type {
  1584. typedef std::forward_iterator_tag iterator_category;
  1585. typedef hole_type value_type;
  1586. typedef std::ptrdiff_t difference_type;
  1587. typedef const hole_type* pointer; //immutable
  1588. typedef const hole_type& reference; //immutable
  1589. typedef typename polygon_with_holes_traits<T>::iterator_holes_type iht;
  1590. iht internal_itr;
  1591. iterator_holes_type() : internal_itr() {}
  1592. iterator_holes_type(iht iht_in) : internal_itr(iht_in) {}
  1593. inline iterator_holes_type& operator++() {
  1594. ++internal_itr;
  1595. return *this;
  1596. }
  1597. inline const iterator_holes_type operator++(int) {
  1598. iterator_holes_type tmp(*this);
  1599. ++(*this);
  1600. return tmp;
  1601. }
  1602. inline bool operator==(const iterator_holes_type& that) const {
  1603. return (internal_itr == that.internal_itr);
  1604. }
  1605. inline bool operator!=(const iterator_holes_type& that) const {
  1606. return (internal_itr != that.internal_itr);
  1607. }
  1608. inline value_type operator*() const {
  1609. return view_as<polygon_90_concept>(*internal_itr);
  1610. }
  1611. };
  1612. /// Get the begin iterator
  1613. inline compact_iterator_type begin_compact() const {
  1614. return compact_iterator_type(polygon_traits<T>::begin_points(*t),
  1615. polygon_traits<T>::end_points(*t));
  1616. }
  1617. /// Get the end iterator
  1618. inline compact_iterator_type end_compact() const {
  1619. return compact_iterator_type(polygon_traits<T>::end_points(*t),
  1620. polygon_traits<T>::end_points(*t));
  1621. }
  1622. /// Get the number of sides of the polygon
  1623. inline std::size_t size() const {
  1624. return polygon_traits<T>::size(*t);
  1625. }
  1626. /// Get the winding direction of the polygon
  1627. inline winding_direction winding() const {
  1628. return polygon_traits<T>::winding(*t);
  1629. }
  1630. /// Get the begin iterator
  1631. inline iterator_holes_type begin_holes() const {
  1632. return polygon_with_holes_traits<T>::begin_holes(*t);
  1633. }
  1634. /// Get the end iterator
  1635. inline iterator_holes_type end_holes() const {
  1636. return polygon_with_holes_traits<T>::end_holes(*t);
  1637. }
  1638. /// Get the number of sides of the polygon
  1639. inline std::size_t size_holes() const {
  1640. return polygon_with_holes_traits<T>::size_holes(*t);
  1641. }
  1642. };
  1643. template <typename T>
  1644. struct geometry_concept<view_of<polygon_90_with_holes_concept, T> > {
  1645. typedef polygon_90_with_holes_concept type;
  1646. };
  1647. template <typename T>
  1648. struct view_of<polygon_concept, T> {
  1649. const T* t;
  1650. view_of(const T& obj) : t(&obj) {}
  1651. typedef typename polygon_traits<T>::coordinate_type coordinate_type;
  1652. typedef typename polygon_traits<T>::iterator_type iterator_type;
  1653. typedef typename polygon_traits<T>::point_type point_type;
  1654. /// Get the begin iterator
  1655. inline iterator_type begin() const {
  1656. return polygon_traits<T>::begin_points(*t);
  1657. }
  1658. /// Get the end iterator
  1659. inline iterator_type end() const {
  1660. return polygon_traits<T>::end_points(*t);
  1661. }
  1662. /// Get the number of sides of the polygon
  1663. inline std::size_t size() const {
  1664. return polygon_traits<T>::size(*t);
  1665. }
  1666. /// Get the winding direction of the polygon
  1667. inline winding_direction winding() const {
  1668. return polygon_traits<T>::winding(*t);
  1669. }
  1670. };
  1671. template <typename T>
  1672. struct geometry_concept<view_of<polygon_concept, T> > {
  1673. typedef polygon_concept type;
  1674. };
  1675. }
  1676. }
  1677. #endif