Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:55:23

0001 /*
0002   Copyright 2008 Intel Corporation
0003 
0004   Use, modification and distribution are subject to the Boost Software License,
0005   Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006   http://www.boost.org/LICENSE_1_0.txt).
0007 */
0008 #ifndef BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP
0009 #define BOOST_POLYGON_POLYGON_90_SET_CONCEPT_HPP
0010 #include "polygon_90_set_data.hpp"
0011 #include "polygon_90_set_traits.hpp"
0012 namespace boost { namespace polygon{
0013 
0014   template <typename polygon_set_type>
0015   typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
0016                        typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type
0017   begin_90_set_data(const polygon_set_type& polygon_set) {
0018     return polygon_90_set_traits<polygon_set_type>::begin(polygon_set);
0019   }
0020 
0021   template <typename polygon_set_type>
0022   typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
0023                        typename polygon_90_set_traits<polygon_set_type>::iterator_type>::type
0024   end_90_set_data(const polygon_set_type& polygon_set) {
0025     return polygon_90_set_traits<polygon_set_type>::end(polygon_set);
0026   }
0027 
0028   template <typename polygon_set_type>
0029   typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
0030                        orientation_2d>::type
0031   scanline_orientation(const polygon_set_type& polygon_set) {
0032     return polygon_90_set_traits<polygon_set_type>::orient(polygon_set);
0033   }
0034 
0035   template <typename polygon_set_type>
0036   typename enable_if< typename is_polygon_90_set_type<polygon_set_type>::type,
0037                        bool>::type
0038   clean(const polygon_set_type& polygon_set) {
0039     return polygon_90_set_traits<polygon_set_type>::clean(polygon_set);
0040   }
0041 
0042   //assign
0043   template <typename polygon_set_type_1, typename polygon_set_type_2>
0044   typename enable_if <
0045     typename gtl_and<
0046       typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type,
0047       typename is_polygon_90_set_type<polygon_set_type_2>::type>::type,
0048     polygon_set_type_1>::type &
0049   assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
0050     polygon_90_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_90_set_data(rvalue), end_90_set_data(rvalue),
0051                                                            scanline_orientation(rvalue));
0052     return lvalue;
0053   }
0054 
0055   template <typename T1, typename T2>
0056   struct are_not_both_rectangle_concept { typedef gtl_yes type; };
0057   template <>
0058   struct are_not_both_rectangle_concept<rectangle_concept, rectangle_concept> { typedef gtl_no type; };
0059 
0060   //equivalence
0061   template <typename polygon_set_type_1, typename polygon_set_type_2>
0062   typename enable_if< typename gtl_and_3<
0063     typename is_polygon_90_set_type<polygon_set_type_1>::type,
0064     typename is_polygon_90_set_type<polygon_set_type_2>::type,
0065     typename are_not_both_rectangle_concept<typename geometry_concept<polygon_set_type_1>::type,
0066                                             typename geometry_concept<polygon_set_type_2>::type>::type>::type,
0067                        bool>::type
0068   equivalence(const polygon_set_type_1& lvalue,
0069               const polygon_set_type_2& rvalue) {
0070     polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type> ps1;
0071     assign(ps1, lvalue);
0072     polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type_2>::coordinate_type> ps2;
0073     assign(ps2, rvalue);
0074     return ps1 == ps2;
0075   }
0076 
0077 
0078   //get rectangle tiles (slicing orientation is vertical)
0079   template <typename output_container_type, typename polygon_set_type>
0080   typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type,
0081                        void>::type
0082   get_rectangles(output_container_type& output, const polygon_set_type& polygon_set) {
0083     clean(polygon_set);
0084     polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(VERTICAL);
0085     assign(ps, polygon_set);
0086     ps.get_rectangles(output);
0087   }
0088 
0089   //get rectangle tiles
0090   template <typename output_container_type, typename polygon_set_type>
0091   typename enable_if< typename gtl_if<typename is_polygon_90_set_type<polygon_set_type>::type>::type,
0092                        void>::type
0093   get_rectangles(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) {
0094     clean(polygon_set);
0095     polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps;
0096     assign(ps, polygon_set);
0097     ps.get_rectangles(output, slicing_orientation);
0098   }
0099 
0100   //get: min_rectangles max_rectangles
0101   template <typename output_container_type, typename polygon_set_type>
0102   typename enable_if <typename gtl_and<
0103     typename is_polygon_90_set_type<polygon_set_type>::type,
0104     typename gtl_same_type<rectangle_concept,
0105                            typename geometry_concept
0106                            <typename std::iterator_traits
0107                             <typename output_container_type::iterator>::value_type>::type>::type>::type,
0108                        void>::type
0109   get_max_rectangles(output_container_type& output, const polygon_set_type& polygon_set) {
0110     std::vector<rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> > rects;
0111     assign(rects, polygon_set);
0112     MaxCover<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::getMaxCover(output, rects, scanline_orientation(polygon_set));
0113   }
0114 
0115   //clear
0116   template <typename polygon_set_type>
0117   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0118                        void>::type
0119   clear(polygon_set_type& polygon_set) {
0120     polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps(scanline_orientation(polygon_set));
0121     assign(polygon_set, ps);
0122   }
0123 
0124   //empty
0125   template <typename polygon_set_type>
0126   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0127                        bool>::type
0128   empty(const polygon_set_type& polygon_set) {
0129     if(clean(polygon_set)) return begin_90_set_data(polygon_set) == end_90_set_data(polygon_set);
0130     polygon_90_set_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> ps;
0131     assign(ps, polygon_set);
0132     ps.clean();
0133     return ps.empty();
0134   }
0135 
0136   //extents
0137   template <typename polygon_set_type, typename rectangle_type>
0138   typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0139                                          typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0140                        bool>::type
0141   extents(rectangle_type& extents_rectangle,
0142                              const polygon_set_type& polygon_set) {
0143     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0144     polygon_90_set_data<Unit> ps;
0145     assign(ps, polygon_set);
0146     return ps.extents(extents_rectangle);
0147   }
0148 
0149   //area
0150   template <typename polygon_set_type>
0151   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0152                        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type>::type
0153   area(const polygon_set_type& polygon_set) {
0154     typedef rectangle_data<typename polygon_90_set_traits<polygon_set_type>::coordinate_type> rectangle_type;
0155     typedef typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::manhattan_area_type area_type;
0156     std::vector<rectangle_type> rects;
0157     assign(rects, polygon_set);
0158     area_type retval = (area_type)0;
0159     for(std::size_t i = 0; i < rects.size(); ++i) {
0160       retval += (area_type)area(rects[i]);
0161     }
0162     return retval;
0163   }
0164 
0165   //interact
0166   template <typename polygon_set_type_1, typename polygon_set_type_2>
0167   typename enable_if <typename gtl_and< typename is_mutable_polygon_90_set_type<polygon_set_type_1>::type,
0168                                          typename is_mutable_polygon_90_set_type<polygon_set_type_2>::type>::type,
0169                        polygon_set_type_1>::type&
0170   interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
0171     typedef typename polygon_90_set_traits<polygon_set_type_1>::coordinate_type Unit;
0172     polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set_2));
0173     polygon_90_set_data<Unit> ps2(ps);
0174     ps.insert(polygon_set_1);
0175     ps2.insert(polygon_set_2);
0176     ps.interact(ps2);
0177     assign(polygon_set_1, ps);
0178     return polygon_set_1;
0179   }
0180 
0181   //self_intersect
0182   template <typename polygon_set_type>
0183   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0184                        polygon_set_type>::type &
0185   self_intersect(polygon_set_type& polygon_set) {
0186     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0187     polygon_90_set_data<Unit> ps;
0188     assign(ps, polygon_set);
0189     ps.self_intersect();
0190     assign(polygon_set, ps);
0191     return polygon_set;
0192   }
0193 
0194   //self_xor
0195   template <typename polygon_set_type>
0196   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0197                        polygon_set_type>::type &
0198   self_xor(polygon_set_type& polygon_set) {
0199     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0200     polygon_90_set_data<Unit> ps;
0201     assign(ps, polygon_set);
0202     ps.self_xor();
0203     assign(polygon_set, ps);
0204     return polygon_set;
0205   }
0206 
0207   template <typename polygon_set_type>
0208   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0209                        polygon_set_type>::type &
0210   bloat(polygon_set_type& polygon_set,
0211         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0212     return bloat(polygon_set, bloating, bloating, bloating, bloating);
0213   }
0214 
0215   template <typename polygon_set_type>
0216   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0217                        polygon_set_type>::type &
0218   bloat(polygon_set_type& polygon_set, orientation_2d orient,
0219         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0220     if(orient == orientation_2d(HORIZONTAL))
0221       return bloat(polygon_set, bloating, bloating, 0, 0);
0222     return bloat(polygon_set, 0, 0, bloating, bloating);
0223   }
0224 
0225   template <typename polygon_set_type>
0226   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0227                        polygon_set_type>::type &
0228   bloat(polygon_set_type& polygon_set, orientation_2d orient,
0229         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating,
0230         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) {
0231     if(orient == orientation_2d(HORIZONTAL))
0232       return bloat(polygon_set, low_bloating, high_bloating, 0, 0);
0233     return bloat(polygon_set, 0, 0, low_bloating, high_bloating);
0234   }
0235 
0236   template <typename polygon_set_type>
0237   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0238                        polygon_set_type>::type &
0239   bloat(polygon_set_type& polygon_set, direction_2d dir,
0240         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0241     if(dir == direction_2d(EAST))
0242       return bloat(polygon_set, 0, bloating, 0, 0);
0243     if(dir == direction_2d(WEST))
0244       return bloat(polygon_set, bloating, 0, 0, 0);
0245     if(dir == direction_2d(SOUTH))
0246       return bloat(polygon_set, 0, 0, bloating, 0);
0247     return bloat(polygon_set, 0, 0, 0, bloating);
0248   }
0249 
0250   template <typename polygon_set_type>
0251   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0252                        polygon_set_type>::type &
0253   bloat(polygon_set_type& polygon_set,
0254         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating,
0255         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating,
0256         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating,
0257         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) {
0258     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0259     polygon_90_set_data<Unit> ps;
0260     assign(ps, polygon_set);
0261     ps.bloat(west_bloating, east_bloating, south_bloating, north_bloating);
0262     ps.clean();
0263     assign(polygon_set, ps);
0264     return polygon_set;
0265   }
0266 
0267   template <typename polygon_set_type>
0268   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0269                        polygon_set_type>::type &
0270   shrink(polygon_set_type& polygon_set,
0271         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
0272     return shrink(polygon_set, shrinking, shrinking, shrinking, shrinking);
0273   }
0274 
0275   template <typename polygon_set_type>
0276   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0277                        polygon_set_type>::type &
0278   shrink(polygon_set_type& polygon_set, orientation_2d orient,
0279         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
0280     if(orient == orientation_2d(HORIZONTAL))
0281       return shrink(polygon_set, shrinking, shrinking, 0, 0);
0282     return shrink(polygon_set, 0, 0, shrinking, shrinking);
0283   }
0284 
0285   template <typename polygon_set_type>
0286   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0287                        polygon_set_type>::type &
0288   shrink(polygon_set_type& polygon_set, orientation_2d orient,
0289         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_shrinking,
0290         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_shrinking) {
0291     if(orient == orientation_2d(HORIZONTAL))
0292       return shrink(polygon_set, low_shrinking, high_shrinking, 0, 0);
0293     return shrink(polygon_set, 0, 0, low_shrinking, high_shrinking);
0294   }
0295 
0296   template <typename polygon_set_type>
0297   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0298                        polygon_set_type>::type &
0299   shrink(polygon_set_type& polygon_set, direction_2d dir,
0300         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
0301     if(dir == direction_2d(EAST))
0302       return shrink(polygon_set, 0, shrinking, 0, 0);
0303     if(dir == direction_2d(WEST))
0304       return shrink(polygon_set, shrinking, 0, 0, 0);
0305     if(dir == direction_2d(SOUTH))
0306       return shrink(polygon_set, 0, 0, shrinking, 0);
0307     return shrink(polygon_set, 0, 0, 0, shrinking);
0308   }
0309 
0310   template <typename polygon_set_type>
0311   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0312                        polygon_set_type>::type &
0313   shrink(polygon_set_type& polygon_set,
0314         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_shrinking,
0315         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_shrinking,
0316         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_shrinking,
0317         typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_shrinking) {
0318     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0319     polygon_90_set_data<Unit> ps;
0320     assign(ps, polygon_set);
0321     ps.shrink(west_shrinking, east_shrinking, south_shrinking, north_shrinking);
0322     ps.clean();
0323     assign(polygon_set, ps);
0324     return polygon_set;
0325   }
0326 
0327   template <typename polygon_set_type, typename coord_type>
0328   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0329                        polygon_set_type>::type &
0330   resize(polygon_set_type& polygon_set, coord_type resizing) {
0331     if(resizing > 0) {
0332       return bloat(polygon_set, resizing);
0333     }
0334     if(resizing < 0) {
0335       return shrink(polygon_set, -resizing);
0336     }
0337     return polygon_set;
0338   }
0339 
0340   //positive or negative values allow for any and all directions of sizing
0341   template <typename polygon_set_type, typename coord_type>
0342   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0343                        polygon_set_type>::type &
0344   resize(polygon_set_type& polygon_set, coord_type west, coord_type east, coord_type south, coord_type north) {
0345     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0346     polygon_90_set_data<Unit> ps;
0347     assign(ps, polygon_set);
0348     ps.resize(west, east, south, north);
0349     assign(polygon_set, ps);
0350     return polygon_set;
0351   }
0352 
0353   template <typename polygon_set_type>
0354   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0355                        polygon_set_type>::type &
0356   grow_and(polygon_set_type& polygon_set,
0357            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0358     return grow_and(polygon_set, bloating, bloating, bloating, bloating);
0359   }
0360 
0361   template <typename polygon_set_type>
0362   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0363                        polygon_set_type>::type &
0364   grow_and(polygon_set_type& polygon_set, orientation_2d orient,
0365            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0366     if(orient == orientation_2d(HORIZONTAL))
0367       return grow_and(polygon_set, bloating, bloating, 0, 0);
0368     return grow_and(polygon_set, 0, 0, bloating, bloating);
0369   }
0370 
0371   template <typename polygon_set_type>
0372   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0373                        polygon_set_type>::type &
0374   grow_and(polygon_set_type& polygon_set, orientation_2d orient,
0375            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type low_bloating,
0376            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type high_bloating) {
0377     if(orient == orientation_2d(HORIZONTAL))
0378       return grow_and(polygon_set, low_bloating, high_bloating, 0, 0);
0379     return grow_and(polygon_set, 0, 0, low_bloating, high_bloating);
0380   }
0381 
0382   template <typename polygon_set_type>
0383   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0384                        polygon_set_type>::type &
0385   grow_and(polygon_set_type& polygon_set, direction_2d dir,
0386            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0387     if(dir == direction_2d(EAST))
0388       return grow_and(polygon_set, 0, bloating, 0, 0);
0389     if(dir == direction_2d(WEST))
0390       return grow_and(polygon_set, bloating, 0, 0, 0);
0391     if(dir == direction_2d(SOUTH))
0392       return grow_and(polygon_set, 0, 0, bloating, 0);
0393     return grow_and(polygon_set, 0, 0, 0, bloating);
0394   }
0395 
0396   template <typename polygon_set_type>
0397   typename enable_if< typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type,
0398                        polygon_set_type>::type &
0399   grow_and(polygon_set_type& polygon_set,
0400            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type west_bloating,
0401            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type east_bloating,
0402            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type south_bloating,
0403            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type north_bloating) {
0404     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0405     std::vector<polygon_90_data<Unit> > polys;
0406     assign(polys, polygon_set);
0407     clear(polygon_set);
0408     polygon_90_set_data<Unit> ps(scanline_orientation(polygon_set));
0409     for(std::size_t i = 0; i < polys.size(); ++i) {
0410       polygon_90_set_data<Unit> tmpPs(scanline_orientation(polygon_set));
0411       tmpPs.insert(polys[i]);
0412       bloat(tmpPs, west_bloating, east_bloating, south_bloating, north_bloating);
0413       tmpPs.clean(); //apply implicit OR on tmp polygon set
0414       ps.insert(tmpPs);
0415     }
0416     self_intersect(ps);
0417     assign(polygon_set, ps);
0418     return polygon_set;
0419   }
0420 
0421   template <typename polygon_set_type>
0422   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0423                        polygon_set_type>::type &
0424   scale_up(polygon_set_type& polygon_set,
0425            typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>
0426            ::unsigned_area_type factor) {
0427     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0428     polygon_90_set_data<Unit> ps;
0429     assign(ps, polygon_set);
0430     ps.scale_up(factor);
0431     assign(polygon_set, ps);
0432     return polygon_set;
0433   }
0434 
0435   template <typename polygon_set_type>
0436   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0437                        polygon_set_type>::type &
0438   scale_down(polygon_set_type& polygon_set,
0439              typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>
0440              ::unsigned_area_type factor) {
0441     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0442     polygon_90_set_data<Unit> ps;
0443     assign(ps, polygon_set);
0444     ps.scale_down(factor);
0445     assign(polygon_set, ps);
0446     return polygon_set;
0447   }
0448 
0449   template <typename polygon_set_type, typename scaling_type>
0450   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0451                        polygon_set_type>::type &
0452   scale(polygon_set_type& polygon_set,
0453         const scaling_type& scaling) {
0454     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0455     polygon_90_set_data<Unit> ps;
0456     assign(ps, polygon_set);
0457     ps.scale(scaling);
0458     assign(polygon_set, ps);
0459     return polygon_set;
0460   }
0461 
0462   struct y_p_s_move : gtl_yes {};
0463 
0464   //move
0465   template <typename polygon_set_type>
0466   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,
0467                       polygon_set_type>::type &
0468   move(polygon_set_type& polygon_set,
0469   orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement) {
0470     if(orient == HORIZONTAL)
0471       return move(polygon_set, displacement, 0);
0472     else
0473       return move(polygon_set, 0, displacement);
0474   }
0475 
0476   struct y_p_s_move2 : gtl_yes {};
0477 
0478   template <typename polygon_set_type>
0479   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,
0480                       polygon_set_type>::type &
0481   move(polygon_set_type& polygon_set, typename polygon_90_set_traits<polygon_set_type>::coordinate_type x_displacement,
0482   typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement) {
0483     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0484     polygon_90_set_data<Unit> ps;
0485     assign(ps, polygon_set);
0486     ps.move(x_displacement, y_displacement);
0487     ps.clean();
0488     assign(polygon_set, ps);
0489     return polygon_set;
0490   }
0491 
0492   //transform
0493   template <typename polygon_set_type, typename transformation_type>
0494   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0495                        polygon_set_type>::type &
0496   transform(polygon_set_type& polygon_set,
0497             const transformation_type& transformation) {
0498     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0499     polygon_90_set_data<Unit> ps;
0500     assign(ps, polygon_set);
0501     ps.transform(transformation);
0502     ps.clean();
0503     assign(polygon_set, ps);
0504     return polygon_set;
0505     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0506   }
0507 
0508   //keep
0509   template <typename polygon_set_type>
0510   typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type,
0511                        polygon_set_type>::type &
0512   keep(polygon_set_type& polygon_set,
0513        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_area,
0514        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_area,
0515        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
0516        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
0517        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
0518        typename coordinate_traits<typename polygon_90_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
0519     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
0520     typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
0521     std::list<polygon_90_data<Unit> > polys;
0522     assign(polys, polygon_set);
0523     clear(polygon_set);
0524     typename std::list<polygon_90_data<Unit> >::iterator itr_nxt;
0525     for(typename std::list<polygon_90_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
0526       itr_nxt = itr;
0527       ++itr_nxt;
0528       rectangle_data<Unit> bbox;
0529       extents(bbox, *itr);
0530       uat pwidth = delta(bbox, HORIZONTAL);
0531       if(pwidth > min_width && pwidth <= max_width){
0532         uat pheight = delta(bbox, VERTICAL);
0533         if(pheight > min_height && pheight <= max_height){
0534           uat parea = area(*itr);
0535           if(parea <= max_area && parea >= min_area) {
0536             continue;
0537           }
0538         }
0539       }
0540       polys.erase(itr);
0541     }
0542     assign(polygon_set, polys);
0543     return polygon_set;
0544   }
0545 
0546 
0547 }
0548 }
0549 #include "detail/polygon_90_set_view.hpp"
0550 #endif