polygon_45_set_concept.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. Copyright 2008 Intel Corporation
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. #ifndef BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP
  8. #define BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP
  9. #include "polygon_45_set_data.hpp"
  10. #include "polygon_45_set_traits.hpp"
  11. #include "detail/polygon_45_touch.hpp"
  12. namespace boost { namespace polygon{
  13. template <typename T, typename T2>
  14. struct is_either_polygon_45_set_type {
  15. typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_45_set_type<T2>::type >::type type;
  16. };
  17. template <typename T>
  18. struct is_polygon_45_or_90_set_type {
  19. typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_90_set_type<T>::type >::type type;
  20. };
  21. template <typename polygon_set_type>
  22. typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type,
  23. typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type
  24. begin_45_set_data(const polygon_set_type& polygon_set) {
  25. return polygon_45_set_traits<polygon_set_type>::begin(polygon_set);
  26. }
  27. template <typename polygon_set_type>
  28. typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type,
  29. typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type
  30. end_45_set_data(const polygon_set_type& polygon_set) {
  31. return polygon_45_set_traits<polygon_set_type>::end(polygon_set);
  32. }
  33. template <typename polygon_set_type>
  34. typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
  35. bool>::type
  36. clean(const polygon_set_type& polygon_set) {
  37. return polygon_45_set_traits<polygon_set_type>::clean(polygon_set);
  38. }
  39. //assign
  40. template <typename polygon_set_type_1, typename polygon_set_type_2>
  41. typename enable_if< typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type,
  42. typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type>::type,
  43. polygon_set_type_1>::type &
  44. assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
  45. polygon_45_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_45_set_data(rvalue), end_45_set_data(rvalue));
  46. return lvalue;
  47. }
  48. //get trapezoids
  49. template <typename output_container_type, typename polygon_set_type>
  50. typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
  51. void>::type
  52. get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) {
  53. clean(polygon_set);
  54. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
  55. assign(ps, polygon_set);
  56. ps.get_trapezoids(output);
  57. }
  58. //get trapezoids
  59. template <typename output_container_type, typename polygon_set_type>
  60. typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
  61. void>::type
  62. get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) {
  63. clean(polygon_set);
  64. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
  65. assign(ps, polygon_set);
  66. ps.get_trapezoids(output, slicing_orientation);
  67. }
  68. //equivalence
  69. template <typename polygon_set_type_1, typename polygon_set_type_2>
  70. typename enable_if< typename gtl_and_3<typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_1>::type>::type,
  71. typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type,
  72. typename gtl_if<typename is_either_polygon_45_set_type<polygon_set_type_1,
  73. polygon_set_type_2>::type>::type>::type,
  74. bool>::type
  75. equivalence(const polygon_set_type_1& lvalue,
  76. const polygon_set_type_2& rvalue) {
  77. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type> ps1;
  78. assign(ps1, lvalue);
  79. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_2>::coordinate_type> ps2;
  80. assign(ps2, rvalue);
  81. return ps1 == ps2;
  82. }
  83. //clear
  84. template <typename polygon_set_type>
  85. typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
  86. void>::type
  87. clear(polygon_set_type& polygon_set) {
  88. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
  89. assign(polygon_set, ps);
  90. }
  91. //empty
  92. template <typename polygon_set_type>
  93. typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
  94. bool>::type
  95. empty(const polygon_set_type& polygon_set) {
  96. if(clean(polygon_set)) return begin_45_set_data(polygon_set) == end_45_set_data(polygon_set);
  97. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
  98. assign(ps, polygon_set);
  99. ps.clean();
  100. return ps.empty();
  101. }
  102. //extents
  103. template <typename polygon_set_type, typename rectangle_type>
  104. typename enable_if<
  105. typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
  106. typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
  107. bool>::type
  108. extents(rectangle_type& extents_rectangle,
  109. const polygon_set_type& polygon_set) {
  110. clean(polygon_set);
  111. polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
  112. assign(ps, polygon_set);
  113. return ps.extents(extents_rectangle);
  114. }
  115. //area
  116. template <typename polygon_set_type>
  117. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  118. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type>::type
  119. area(const polygon_set_type& polygon_set) {
  120. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  121. typedef polygon_45_with_holes_data<Unit> p_type;
  122. typedef typename coordinate_traits<Unit>::area_type area_type;
  123. std::vector<p_type> polys;
  124. assign(polys, polygon_set);
  125. area_type retval = (area_type)0;
  126. for(std::size_t i = 0; i < polys.size(); ++i) {
  127. retval += area(polys[i]);
  128. }
  129. return retval;
  130. }
  131. //interact
  132. template <typename polygon_set_type_1, typename polygon_set_type_2>
  133. typename enable_if <
  134. typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type,
  135. typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type >::type,
  136. polygon_set_type_1>::type&
  137. interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
  138. typedef typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type Unit;
  139. std::vector<polygon_45_data<Unit> > polys;
  140. assign(polys, polygon_set_1);
  141. std::vector<std::set<int> > graph(polys.size()+1, std::set<int>());
  142. connectivity_extraction_45<Unit> ce;
  143. ce.insert(polygon_set_2);
  144. for(std::size_t i = 0; i < polys.size(); ++i){
  145. ce.insert(polys[i]);
  146. }
  147. ce.extract(graph);
  148. clear(polygon_set_1);
  149. polygon_45_set_data<Unit> ps;
  150. for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){
  151. ps.insert(polys[(*itr)-1]);
  152. }
  153. assign(polygon_set_1, ps);
  154. return polygon_set_1;
  155. }
  156. // //self_intersect
  157. // template <typename polygon_set_type>
  158. // typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
  159. // polygon_set_type>::type &
  160. // self_intersect(polygon_set_type& polygon_set) {
  161. // typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  162. // //TODO
  163. // }
  164. template <typename polygon_set_type, typename coord_type>
  165. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  166. polygon_set_type>::type &
  167. resize(polygon_set_type& polygon_set, coord_type resizing,
  168. RoundingOption rounding = CLOSEST, CornerOption corner = INTERSECTION) {
  169. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  170. clean(polygon_set);
  171. polygon_45_set_data<Unit> ps;
  172. assign(ps, polygon_set);
  173. ps.resize(resizing, rounding, corner);
  174. assign(polygon_set, ps);
  175. return polygon_set;
  176. }
  177. template <typename polygon_set_type>
  178. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  179. polygon_set_type>::type &
  180. bloat(polygon_set_type& polygon_set,
  181. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
  182. return resize(polygon_set, static_cast<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>(bloating));
  183. }
  184. template <typename polygon_set_type>
  185. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  186. polygon_set_type>::type &
  187. shrink(polygon_set_type& polygon_set,
  188. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
  189. return resize(polygon_set, -(typename polygon_45_set_traits<polygon_set_type>::coordinate_type)shrinking);
  190. }
  191. template <typename polygon_set_type>
  192. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  193. polygon_set_type>::type &
  194. grow_and(polygon_set_type& polygon_set,
  195. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
  196. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  197. std::vector<polygon_45_data<Unit> > polys;
  198. assign(polys, polygon_set);
  199. clear(polygon_set);
  200. polygon_45_set_data<Unit> ps;
  201. for(std::size_t i = 0; i < polys.size(); ++i) {
  202. polygon_45_set_data<Unit> tmpPs;
  203. tmpPs.insert(polys[i]);
  204. bloat(tmpPs, bloating);
  205. tmpPs.clean(); //apply implicit OR on tmp polygon set
  206. ps.insert(tmpPs);
  207. }
  208. ps.self_intersect();
  209. assign(polygon_set, ps);
  210. return polygon_set;
  211. }
  212. template <typename polygon_set_type>
  213. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  214. polygon_set_type>::type &
  215. scale_up(polygon_set_type& polygon_set,
  216. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
  217. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  218. clean(polygon_set);
  219. polygon_45_set_data<Unit> ps;
  220. assign(ps, polygon_set);
  221. ps.scale_up(factor);
  222. assign(polygon_set, ps);
  223. return polygon_set;
  224. }
  225. template <typename polygon_set_type>
  226. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  227. polygon_set_type>::type &
  228. scale_down(polygon_set_type& polygon_set,
  229. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
  230. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  231. clean(polygon_set);
  232. polygon_45_set_data<Unit> ps;
  233. assign(ps, polygon_set);
  234. ps.scale_down(factor);
  235. assign(polygon_set, ps);
  236. return polygon_set;
  237. }
  238. template <typename polygon_set_type>
  239. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  240. polygon_set_type>::type &
  241. scale(polygon_set_type& polygon_set, double factor) {
  242. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  243. clean(polygon_set);
  244. polygon_45_set_data<Unit> ps;
  245. assign(ps, polygon_set);
  246. ps.scale(factor);
  247. assign(polygon_set, ps);
  248. return polygon_set;
  249. }
  250. //self_intersect
  251. template <typename polygon_set_type>
  252. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  253. polygon_set_type>::type &
  254. self_intersect(polygon_set_type& polygon_set) {
  255. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  256. polygon_45_set_data<Unit> ps;
  257. assign(ps, polygon_set);
  258. ps.self_intersect();
  259. assign(polygon_set, ps);
  260. return polygon_set;
  261. }
  262. //self_xor
  263. template <typename polygon_set_type>
  264. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  265. polygon_set_type>::type &
  266. self_xor(polygon_set_type& polygon_set) {
  267. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  268. polygon_45_set_data<Unit> ps;
  269. assign(ps, polygon_set);
  270. ps.self_xor();
  271. assign(polygon_set, ps);
  272. return polygon_set;
  273. }
  274. //transform
  275. template <typename polygon_set_type, typename transformation_type>
  276. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  277. polygon_set_type>::type &
  278. transform(polygon_set_type& polygon_set,
  279. const transformation_type& transformation) {
  280. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  281. clean(polygon_set);
  282. polygon_45_set_data<Unit> ps;
  283. assign(ps, polygon_set);
  284. ps.transform(transformation);
  285. assign(polygon_set, ps);
  286. return polygon_set;
  287. }
  288. //keep
  289. template <typename polygon_set_type>
  290. typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
  291. polygon_set_type>::type &
  292. keep(polygon_set_type& polygon_set,
  293. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type min_area,
  294. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type max_area,
  295. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
  296. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
  297. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
  298. typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
  299. typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
  300. typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
  301. std::list<polygon_45_data<Unit> > polys;
  302. assign(polys, polygon_set);
  303. typename std::list<polygon_45_data<Unit> >::iterator itr_nxt;
  304. for(typename std::list<polygon_45_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
  305. itr_nxt = itr;
  306. ++itr_nxt;
  307. rectangle_data<Unit> bbox;
  308. extents(bbox, *itr);
  309. uat pwidth = delta(bbox, HORIZONTAL);
  310. if(pwidth > min_width && pwidth <= max_width){
  311. uat pheight = delta(bbox, VERTICAL);
  312. if(pheight > min_height && pheight <= max_height){
  313. typename coordinate_traits<Unit>::area_type parea = area(*itr);
  314. if(parea <= max_area && parea >= min_area) {
  315. continue;
  316. }
  317. }
  318. }
  319. polys.erase(itr);
  320. }
  321. assign(polygon_set, polys);
  322. return polygon_set;
  323. }
  324. template <typename T>
  325. struct view_of<polygon_90_set_concept, T> {
  326. typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
  327. T* tp;
  328. std::vector<polygon_90_with_holes_data<coordinate_type> > polys;
  329. view_of(T& obj) : tp(&obj), polys() {
  330. std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
  331. assign(gpolys, obj);
  332. for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
  333. itr != gpolys.end(); ++itr) {
  334. polys.push_back(polygon_90_with_holes_data<coordinate_type>());
  335. assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr));
  336. }
  337. }
  338. view_of(const T& obj) : tp(), polys() {
  339. std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
  340. assign(gpolys, obj);
  341. for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
  342. itr != gpolys.end(); ++itr) {
  343. polys.push_back(polygon_90_with_holes_data<coordinate_type>());
  344. assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr));
  345. }
  346. }
  347. typedef typename std::vector<polygon_90_with_holes_data<coordinate_type> >::const_iterator iterator_type;
  348. typedef view_of operator_arg_type;
  349. inline iterator_type begin() const {
  350. return polys.begin();
  351. }
  352. inline iterator_type end() const {
  353. return polys.end();
  354. }
  355. inline orientation_2d orient() const { return HORIZONTAL; }
  356. inline bool clean() const { return false; }
  357. inline bool sorted() const { return false; }
  358. inline T& get() { return *tp; }
  359. };
  360. template <typename T>
  361. struct polygon_90_set_traits<view_of<polygon_90_set_concept, T> > {
  362. typedef typename view_of<polygon_90_set_concept, T>::coordinate_type coordinate_type;
  363. typedef typename view_of<polygon_90_set_concept, T>::iterator_type iterator_type;
  364. typedef view_of<polygon_90_set_concept, T> operator_arg_type;
  365. static inline iterator_type begin(const view_of<polygon_90_set_concept, T>& polygon_set) {
  366. return polygon_set.begin();
  367. }
  368. static inline iterator_type end(const view_of<polygon_90_set_concept, T>& polygon_set) {
  369. return polygon_set.end();
  370. }
  371. static inline orientation_2d orient(const view_of<polygon_90_set_concept, T>& polygon_set) {
  372. return polygon_set.orient(); }
  373. static inline bool clean(const view_of<polygon_90_set_concept, T>& polygon_set) {
  374. return polygon_set.clean(); }
  375. static inline bool sorted(const view_of<polygon_90_set_concept, T>& polygon_set) {
  376. return polygon_set.sorted(); }
  377. };
  378. template <typename T>
  379. struct geometry_concept<view_of<polygon_90_set_concept, T> > {
  380. typedef polygon_90_set_concept type;
  381. };
  382. template <typename T>
  383. struct get_coordinate_type<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> {
  384. typedef typename view_of<polygon_90_set_concept, T>::coordinate_type type;
  385. };
  386. template <typename T>
  387. struct get_iterator_type_2<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> {
  388. typedef typename view_of<polygon_90_set_concept, T>::iterator_type type;
  389. static type begin(const view_of<polygon_90_set_concept, T>& t) { return t.begin(); }
  390. static type end(const view_of<polygon_90_set_concept, T>& t) { return t.end(); }
  391. };
  392. }
  393. }
  394. #include "detail/polygon_45_set_view.hpp"
  395. #endif