1 /* 2 Copyright 2008 Intel Corporation 3 4 Use, modification and distribution are subject to the Boost Software License, 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt). 7 */ 8 #ifndef BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP 9 #define BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP 10 #include "polygon_90_set_data.hpp" 11 #include "polygon_90_set_traits.hpp" 12 namespace boost { namespace polygon{ 13 14 template <typename polygon_set_type> 15 typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, 16 typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type begin_90_set_data(const polygon_set_type & polygon_set)17 begin_90_set_data(const polygon_set_type& polygon_set) { 18 return polygon_90_set_traits<polygon_set_type>::begin(polygon_set); 19 } 20 21 template <typename polygon_set_type> 22 typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, 23 typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type end_90_set_data(const polygon_set_type & polygon_set)24 end_90_set_data(const polygon_set_type& polygon_set) { 25 return polygon_90_set_traits<polygon_set_type>::end(polygon_set); 26 } 27 28 template <typename polygon_set_type> 29 typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, 30 orientation_2d>::type scanline_orientation(const polygon_set_type & polygon_set)31 scanline_orientation(const polygon_set_type& polygon_set) { 32 return polygon_90_set_traits<polygon_set_type>::orient(polygon_set); 33 } 34 35 template <typename polygon_set_type> 36 typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type, 37 bool>::type clean(const polygon_set_type & polygon_set)38 clean(const polygon_set_type& polygon_set) { 39 return polygon_90_set_traits<polygon_set_type>::clean(polygon_set); 40 } 41 42 //assign 43 template <typename polygon_set_type_1, typename polygon_set_type_2> 44 typename enable_if < 45 typename gtl_and< 46 typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type, 47 typename is_polygon_90_set_type<polygon_set_type_2>::type>::type, 48 polygon_set_type_1>::type & assign(polygon_set_type_1 & lvalue,const polygon_set_type_2 & rvalue)49 assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { 50 polygon_90_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_90_set_data(rvalue), end_90_set_data(rvalue), 51 scanline_orientation(rvalue)); 52 return lvalue; 53 } 54 55 template <typename T1, typename T2> 56 struct are_not_both_rectangle_concept { typedef gtl_yes type; }; 57 template <> 58 struct are_not_both_rectangle_concept<rectangle_concept, rectangle_concept> { typedef gtl_no type; }; 59 60 //equivalence 61 template <typename polygon_set_type_1, typename polygon_set_type_2> 62 typename enable_if< typename gtl_and_3< 63 typename is_polygon_90_set_type<polygon_set_type_1>::type, 64 typename is_polygon_90_set_type<polygon_set_type_2>::type, 65 typename are_not_both_rectangle_concept<typename geometry_concept<polygon_set_type_1>::type, 66 typename geometry_concept<polygon_set_type_2>::type>::type>::type, 67 bool>::type equivalence(const polygon_set_type_1 & lvalue,const polygon_set_type_2 & rvalue)68 equivalence(const polygon_set_type_1& lvalue, 69 const polygon_set_type_2& rvalue) { 70 polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type> ps1; 71 assign(ps1, lvalue); 72 polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_2>::coordinate_type> ps2; 73 assign(ps2, rvalue); 74 return ps1 == ps2; 75 } 76 77 78 //get rectangle tiles (slicing orientation is vertical) 79 template <typename output_container_type, typename polygon_set_type> 80 typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type, 81 void>::type get_rectangles(output_container_type & output,const polygon_set_type & polygon_set)82 get_rectangles(output_container_type& output, const polygon_set_type& polygon_set) { 83 clean(polygon_set); 84 polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(VERTICAL); 85 assign(ps, polygon_set); 86 ps.get_rectangles(output); 87 } 88 89 //get rectangle tiles 90 template <typename output_container_type, typename polygon_set_type> 91 typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type, 92 void>::type get_rectangles(output_container_type & output,const polygon_set_type & polygon_set,orientation_2d slicing_orientation)93 get_rectangles(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) { 94 clean(polygon_set); 95 polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps; 96 assign(ps, polygon_set); 97 ps.get_rectangles(output, slicing_orientation); 98 } 99 100 //get: min_rectangles max_rectangles 101 template <typename output_container_type, typename polygon_set_type> 102 typename enable_if <typename gtl_and< 103 typename is_polygon_90_set_type<polygon_set_type>::type, 104 typename gtl_same_type<rectangle_concept, 105 typename geometry_concept 106 <typename std::iterator_traits 107 <typename output_container_type::iterator>::value_type>::type>::type>::type, 108 void>::type get_max_rectangles(output_container_type & output,const polygon_set_type & polygon_set)109 get_max_rectangles(output_container_type& output, const polygon_set_type& polygon_set) { 110 std::vector<rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> > rects; 111 assign(rects, polygon_set); 112 MaxCover<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::getMaxCover(output, rects, scanline_orientation(polygon_set)); 113 } 114 115 //clear 116 template <typename polygon_set_type> 117 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 118 void>::type clear(polygon_set_type & polygon_set)119 clear(polygon_set_type& polygon_set) { 120 polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(scanline_orientation(polygon_set)); 121 assign(polygon_set, ps); 122 } 123 124 //empty 125 template <typename polygon_set_type> 126 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 127 bool>::type empty(const polygon_set_type & polygon_set)128 empty(const polygon_set_type& polygon_set) { 129 if(clean(polygon_set)) return begin_90_set_data(polygon_set) == end_90_set_data(polygon_set); 130 polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps; 131 assign(ps, polygon_set); 132 ps.clean(); 133 return ps.empty(); 134 } 135 136 //extents 137 template <typename polygon_set_type, typename rectangle_type> 138 typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 139 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 140 bool>::type extents(rectangle_type & extents_rectangle,const polygon_set_type & polygon_set)141 extents(rectangle_type& extents_rectangle, 142 const polygon_set_type& polygon_set) { 143 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 144 polygon_90_set_data<Unit> ps; 145 assign(ps, polygon_set); 146 return ps.extents(extents_rectangle); 147 } 148 149 //area 150 template <typename polygon_set_type> 151 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 152 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type>::type area(const polygon_set_type & polygon_set)153 area(const polygon_set_type& polygon_set) { 154 typedef rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> rectangle_type; 155 typedef typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type area_type; 156 std::vector<rectangle_type> rects; 157 assign(rects, polygon_set); 158 area_type retval = (area_type)0; 159 for(std::size_t i = 0; i < rects.size(); ++i) { 160 retval += (area_type)area(rects[i]); 161 } 162 return retval; 163 } 164 165 //interact 166 template <typename polygon_set_type_1, typename polygon_set_type_2> 167 typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type, 168 typename is_mutable_polygon_90_set_type<polygon_set_type_2>::type>::type, 169 polygon_set_type_1>::type& interact(polygon_set_type_1 & polygon_set_1,const polygon_set_type_2 & polygon_set_2)170 interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { 171 typedef typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type Unit; 172 polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set_2)); 173 polygon_90_set_data<Unit> ps2(ps); 174 ps.insert(polygon_set_1); 175 ps2.insert(polygon_set_2); 176 ps.interact(ps2); 177 assign(polygon_set_1, ps); 178 return polygon_set_1; 179 } 180 181 //self_intersect 182 template <typename polygon_set_type> 183 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 184 polygon_set_type>::type & self_intersect(polygon_set_type & polygon_set)185 self_intersect(polygon_set_type& polygon_set) { 186 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 187 polygon_90_set_data<Unit> ps; 188 assign(ps, polygon_set); 189 ps.self_intersect(); 190 assign(polygon_set, ps); 191 return polygon_set; 192 } 193 194 //self_xor 195 template <typename polygon_set_type> 196 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 197 polygon_set_type>::type & self_xor(polygon_set_type & polygon_set)198 self_xor(polygon_set_type& polygon_set) { 199 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 200 polygon_90_set_data<Unit> ps; 201 assign(ps, polygon_set); 202 ps.self_xor(); 203 assign(polygon_set, ps); 204 return polygon_set; 205 } 206 207 template <typename polygon_set_type> 208 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 209 polygon_set_type>::type & bloat(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)210 bloat(polygon_set_type& polygon_set, 211 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { 212 return bloat(polygon_set, bloating, bloating, bloating, bloating); 213 } 214 215 template <typename polygon_set_type> 216 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 217 polygon_set_type>::type & bloat(polygon_set_type & polygon_set,orientation_2d orient,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)218 bloat(polygon_set_type& polygon_set, orientation_2d orient, 219 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { 220 if(orient == orientation_2d(HORIZONTAL)) 221 return bloat(polygon_set, bloating, bloating, 0, 0); 222 return bloat(polygon_set, 0, 0, bloating, bloating); 223 } 224 225 template <typename polygon_set_type> 226 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 227 polygon_set_type>::type & bloat(polygon_set_type & polygon_set,orientation_2d orient,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating)228 bloat(polygon_set_type& polygon_set, orientation_2d orient, 229 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating, 230 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) { 231 if(orient == orientation_2d(HORIZONTAL)) 232 return bloat(polygon_set, low_bloating, high_bloating, 0, 0); 233 return bloat(polygon_set, 0, 0, low_bloating, high_bloating); 234 } 235 236 template <typename polygon_set_type> 237 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 238 polygon_set_type>::type & bloat(polygon_set_type & polygon_set,direction_2d dir,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)239 bloat(polygon_set_type& polygon_set, direction_2d dir, 240 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { 241 if(dir == direction_2d(EAST)) 242 return bloat(polygon_set, 0, bloating, 0, 0); 243 if(dir == direction_2d(WEST)) 244 return bloat(polygon_set, bloating, 0, 0, 0); 245 if(dir == direction_2d(SOUTH)) 246 return bloat(polygon_set, 0, 0, bloating, 0); 247 return bloat(polygon_set, 0, 0, 0, bloating); 248 } 249 250 template <typename polygon_set_type> 251 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 252 polygon_set_type>::type & bloat(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating)253 bloat(polygon_set_type& polygon_set, 254 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating, 255 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating, 256 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating, 257 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) { 258 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 259 polygon_90_set_data<Unit> ps; 260 assign(ps, polygon_set); 261 ps.bloat(west_bloating, east_bloating, south_bloating, north_bloating); 262 ps.clean(); 263 assign(polygon_set, ps); 264 return polygon_set; 265 } 266 267 template <typename polygon_set_type> 268 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 269 polygon_set_type>::type & shrink(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking)270 shrink(polygon_set_type& polygon_set, 271 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { 272 return shrink(polygon_set, shrinking, shrinking, shrinking, shrinking); 273 } 274 275 template <typename polygon_set_type> 276 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 277 polygon_set_type>::type & shrink(polygon_set_type & polygon_set,orientation_2d orient,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking)278 shrink(polygon_set_type& polygon_set, orientation_2d orient, 279 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { 280 if(orient == orientation_2d(HORIZONTAL)) 281 return shrink(polygon_set, shrinking, shrinking, 0, 0); 282 return shrink(polygon_set, 0, 0, shrinking, shrinking); 283 } 284 285 template <typename polygon_set_type> 286 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 287 polygon_set_type>::type & shrink(polygon_set_type & polygon_set,orientation_2d orient,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_shrinking,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_shrinking)288 shrink(polygon_set_type& polygon_set, orientation_2d orient, 289 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_shrinking, 290 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_shrinking) { 291 if(orient == orientation_2d(HORIZONTAL)) 292 return shrink(polygon_set, low_shrinking, high_shrinking, 0, 0); 293 return shrink(polygon_set, 0, 0, low_shrinking, high_shrinking); 294 } 295 296 template <typename polygon_set_type> 297 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 298 polygon_set_type>::type & shrink(polygon_set_type & polygon_set,direction_2d dir,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking)299 shrink(polygon_set_type& polygon_set, direction_2d dir, 300 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) { 301 if(dir == direction_2d(EAST)) 302 return shrink(polygon_set, 0, shrinking, 0, 0); 303 if(dir == direction_2d(WEST)) 304 return shrink(polygon_set, shrinking, 0, 0, 0); 305 if(dir == direction_2d(SOUTH)) 306 return shrink(polygon_set, 0, 0, shrinking, 0); 307 return shrink(polygon_set, 0, 0, 0, shrinking); 308 } 309 310 template <typename polygon_set_type> 311 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 312 polygon_set_type>::type & shrink(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_shrinking,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_shrinking,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_shrinking,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_shrinking)313 shrink(polygon_set_type& polygon_set, 314 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_shrinking, 315 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_shrinking, 316 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_shrinking, 317 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_shrinking) { 318 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 319 polygon_90_set_data<Unit> ps; 320 assign(ps, polygon_set); 321 ps.shrink(west_shrinking, east_shrinking, south_shrinking, north_shrinking); 322 ps.clean(); 323 assign(polygon_set, ps); 324 return polygon_set; 325 } 326 327 template <typename polygon_set_type, typename coord_type> 328 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 329 polygon_set_type>::type & resize(polygon_set_type & polygon_set,coord_type resizing)330 resize(polygon_set_type& polygon_set, coord_type resizing) { 331 if(resizing > 0) { 332 return bloat(polygon_set, resizing); 333 } 334 if(resizing < 0) { 335 return shrink(polygon_set, -resizing); 336 } 337 return polygon_set; 338 } 339 340 //positive or negative values allow for any and all directions of sizing 341 template <typename polygon_set_type, typename coord_type> 342 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 343 polygon_set_type>::type & resize(polygon_set_type & polygon_set,coord_type west,coord_type east,coord_type south,coord_type north)344 resize(polygon_set_type& polygon_set, coord_type west, coord_type east, coord_type south, coord_type north) { 345 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 346 polygon_90_set_data<Unit> ps; 347 assign(ps, polygon_set); 348 ps.resize(west, east, south, north); 349 assign(polygon_set, ps); 350 return polygon_set; 351 } 352 353 template <typename polygon_set_type> 354 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 355 polygon_set_type>::type & grow_and(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)356 grow_and(polygon_set_type& polygon_set, 357 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { 358 return grow_and(polygon_set, bloating, bloating, bloating, bloating); 359 } 360 361 template <typename polygon_set_type> 362 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 363 polygon_set_type>::type & grow_and(polygon_set_type & polygon_set,orientation_2d orient,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)364 grow_and(polygon_set_type& polygon_set, orientation_2d orient, 365 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { 366 if(orient == orientation_2d(HORIZONTAL)) 367 return grow_and(polygon_set, bloating, bloating, 0, 0); 368 return grow_and(polygon_set, 0, 0, bloating, bloating); 369 } 370 371 template <typename polygon_set_type> 372 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 373 polygon_set_type>::type & grow_and(polygon_set_type & polygon_set,orientation_2d orient,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating)374 grow_and(polygon_set_type& polygon_set, orientation_2d orient, 375 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating, 376 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) { 377 if(orient == orientation_2d(HORIZONTAL)) 378 return grow_and(polygon_set, low_bloating, high_bloating, 0, 0); 379 return grow_and(polygon_set, 0, 0, low_bloating, high_bloating); 380 } 381 382 template <typename polygon_set_type> 383 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 384 polygon_set_type>::type & grow_and(polygon_set_type & polygon_set,direction_2d dir,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating)385 grow_and(polygon_set_type& polygon_set, direction_2d dir, 386 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) { 387 if(dir == direction_2d(EAST)) 388 return grow_and(polygon_set, 0, bloating, 0, 0); 389 if(dir == direction_2d(WEST)) 390 return grow_and(polygon_set, bloating, 0, 0, 0); 391 if(dir == direction_2d(SOUTH)) 392 return grow_and(polygon_set, 0, 0, bloating, 0); 393 return grow_and(polygon_set, 0, 0, 0, bloating); 394 } 395 396 template <typename polygon_set_type> 397 typename enable_if< typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type, 398 polygon_set_type>::type & grow_and(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating)399 grow_and(polygon_set_type& polygon_set, 400 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating, 401 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating, 402 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating, 403 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) { 404 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 405 std::vector<polygon_90_data<Unit> > polys; 406 assign(polys, polygon_set); 407 clear(polygon_set); 408 polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set)); 409 for(std::size_t i = 0; i < polys.size(); ++i) { 410 polygon_90_set_data<Unit> tmpPs(scanline_orientation(polygon_set)); 411 tmpPs.insert(polys[i]); 412 bloat(tmpPs, west_bloating, east_bloating, south_bloating, north_bloating); 413 tmpPs.clean(); //apply implicit OR on tmp polygon set 414 ps.insert(tmpPs); 415 } 416 self_intersect(ps); 417 assign(polygon_set, ps); 418 return polygon_set; 419 } 420 421 template <typename polygon_set_type> 422 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 423 polygon_set_type>::type & scale_up(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor)424 scale_up(polygon_set_type& polygon_set, 425 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> 426 ::unsigned_area_type factor) { 427 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 428 polygon_90_set_data<Unit> ps; 429 assign(ps, polygon_set); 430 ps.scale_up(factor); 431 assign(polygon_set, ps); 432 return polygon_set; 433 } 434 435 template <typename polygon_set_type> 436 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 437 polygon_set_type>::type & scale_down(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor)438 scale_down(polygon_set_type& polygon_set, 439 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> 440 ::unsigned_area_type factor) { 441 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 442 polygon_90_set_data<Unit> ps; 443 assign(ps, polygon_set); 444 ps.scale_down(factor); 445 assign(polygon_set, ps); 446 return polygon_set; 447 } 448 449 template <typename polygon_set_type, typename scaling_type> 450 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 451 polygon_set_type>::type & scale(polygon_set_type & polygon_set,const scaling_type & scaling)452 scale(polygon_set_type& polygon_set, 453 const scaling_type& scaling) { 454 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 455 polygon_90_set_data<Unit> ps; 456 assign(ps, polygon_set); 457 ps.scale(scaling); 458 assign(polygon_set, ps); 459 return polygon_set; 460 } 461 462 struct y_p_s_move : gtl_yes {}; 463 464 //move 465 template <typename polygon_set_type> 466 typename enable_if< typename gtl_and<y_p_s_move, typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type>::type, 467 polygon_set_type>::type & move(polygon_set_type & polygon_set,orientation_2d orient,typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement)468 move(polygon_set_type& polygon_set, 469 orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement) { 470 if(orient == HORIZONTAL) 471 return move(polygon_set, displacement, 0); 472 else 473 return move(polygon_set, 0, displacement); 474 } 475 476 struct y_p_s_move2 : gtl_yes {}; 477 478 template <typename polygon_set_type> 479 typename enable_if< typename gtl_and<y_p_s_move2, typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type>::type, 480 polygon_set_type>::type & move(polygon_set_type & polygon_set,typename polygon_90_set_traits<polygon_set_type>::coordinate_type x_displacement,typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement)481 move(polygon_set_type& polygon_set, typename polygon_90_set_traits<polygon_set_type>::coordinate_type x_displacement, 482 typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement) { 483 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 484 polygon_90_set_data<Unit> ps; 485 assign(ps, polygon_set); 486 ps.move(x_displacement, y_displacement); 487 ps.clean(); 488 assign(polygon_set, ps); 489 return polygon_set; 490 } 491 492 //transform 493 template <typename polygon_set_type, typename transformation_type> 494 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 495 polygon_set_type>::type & transform(polygon_set_type & polygon_set,const transformation_type & transformation)496 transform(polygon_set_type& polygon_set, 497 const transformation_type& transformation) { 498 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 499 polygon_90_set_data<Unit> ps; 500 assign(ps, polygon_set); 501 ps.transform(transformation); 502 ps.clean(); 503 assign(polygon_set, ps); 504 return polygon_set; 505 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 506 } 507 508 //keep 509 template <typename polygon_set_type> 510 typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type, 511 polygon_set_type>::type & keep(polygon_set_type & polygon_set,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_area,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_area,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height)512 keep(polygon_set_type& polygon_set, 513 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_area, 514 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_area, 515 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width, 516 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width, 517 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height, 518 typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) { 519 typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit; 520 typedef typename coordinate_traits<Unit>::unsigned_area_type uat; 521 std::list<polygon_90_data<Unit> > polys; 522 assign(polys, polygon_set); 523 clear(polygon_set); 524 typename std::list<polygon_90_data<Unit> >::iterator itr_nxt; 525 for(typename std::list<polygon_90_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ 526 itr_nxt = itr; 527 ++itr_nxt; 528 rectangle_data<Unit> bbox; 529 extents(bbox, *itr); 530 uat pwidth = delta(bbox, HORIZONTAL); 531 if(pwidth > min_width && pwidth <= max_width){ 532 uat pheight = delta(bbox, VERTICAL); 533 if(pheight > min_height && pheight <= max_height){ 534 uat parea = area(*itr); 535 if(parea <= max_area && parea >= min_area) { 536 continue; 537 } 538 } 539 } 540 polys.erase(itr); 541 } 542 assign(polygon_set, polys); 543 return polygon_set; 544 } 545 546 547 } 548 } 549 #include "detail/polygon_90_set_view.hpp" 550 #endif 551