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 |
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 |
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 |
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 |
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 & |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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& |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 & |
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 | |