File indexing completed on 2025-01-18 09:47:59
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP
0009 #define BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP
0010 #include "polygon_45_set_data.hpp"
0011 #include "polygon_45_set_traits.hpp"
0012 #include "detail/polygon_45_touch.hpp"
0013 namespace boost { namespace polygon{
0014
0015 template <typename T, typename T2>
0016 struct is_either_polygon_45_set_type {
0017 typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_45_set_type<T2>::type >::type type;
0018 };
0019
0020 template <typename T>
0021 struct is_polygon_45_or_90_set_type {
0022 typedef typename gtl_or<typename is_polygon_45_set_type<T>::type, typename is_polygon_90_set_type<T>::type >::type type;
0023 };
0024
0025 template <typename polygon_set_type>
0026 typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type,
0027 typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type
0028 begin_45_set_data(const polygon_set_type& polygon_set) {
0029 return polygon_45_set_traits<polygon_set_type>::begin(polygon_set);
0030 }
0031
0032 template <typename polygon_set_type>
0033 typename enable_if< typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type>::type>::type,
0034 typename polygon_45_set_traits<polygon_set_type>::iterator_type>::type
0035 end_45_set_data(const polygon_set_type& polygon_set) {
0036 return polygon_45_set_traits<polygon_set_type>::end(polygon_set);
0037 }
0038
0039 template <typename polygon_set_type>
0040 typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
0041 bool>::type
0042 clean(const polygon_set_type& polygon_set) {
0043 return polygon_45_set_traits<polygon_set_type>::clean(polygon_set);
0044 }
0045
0046
0047 template <typename polygon_set_type_1, typename polygon_set_type_2>
0048 typename enable_if< typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type,
0049 typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type>::type,
0050 polygon_set_type_1>::type &
0051 assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
0052 polygon_45_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_45_set_data(rvalue), end_45_set_data(rvalue));
0053 return lvalue;
0054 }
0055
0056
0057 template <typename output_container_type, typename polygon_set_type>
0058 typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
0059 void>::type
0060 get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) {
0061 clean(polygon_set);
0062 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
0063 assign(ps, polygon_set);
0064 ps.get_trapezoids(output);
0065 }
0066
0067
0068 template <typename output_container_type, typename polygon_set_type>
0069 typename enable_if< typename gtl_if<typename is_polygon_45_set_type<polygon_set_type>::type>::type,
0070 void>::type
0071 get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) {
0072 clean(polygon_set);
0073 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
0074 assign(ps, polygon_set);
0075 ps.get_trapezoids(output, slicing_orientation);
0076 }
0077
0078
0079 template <typename polygon_set_type_1, typename polygon_set_type_2>
0080 typename enable_if< typename gtl_and_3<typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_1>::type>::type,
0081 typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type,
0082 typename gtl_if<typename is_either_polygon_45_set_type<polygon_set_type_1,
0083 polygon_set_type_2>::type>::type>::type,
0084 bool>::type
0085 equivalence(const polygon_set_type_1& lvalue,
0086 const polygon_set_type_2& rvalue) {
0087 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type> ps1;
0088 assign(ps1, lvalue);
0089 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type_2>::coordinate_type> ps2;
0090 assign(ps2, rvalue);
0091 return ps1 == ps2;
0092 }
0093
0094
0095 template <typename polygon_set_type>
0096 typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
0097 void>::type
0098 clear(polygon_set_type& polygon_set) {
0099 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
0100 assign(polygon_set, ps);
0101 }
0102
0103
0104 template <typename polygon_set_type>
0105 typename enable_if< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
0106 bool>::type
0107 empty(const polygon_set_type& polygon_set) {
0108 if(clean(polygon_set)) return begin_45_set_data(polygon_set) == end_45_set_data(polygon_set);
0109 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
0110 assign(ps, polygon_set);
0111 ps.clean();
0112 return ps.empty();
0113 }
0114
0115
0116 template <typename polygon_set_type, typename rectangle_type>
0117 typename enable_if<
0118 typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type>::type>::type,
0119 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0120 bool>::type
0121 extents(rectangle_type& extents_rectangle,
0122 const polygon_set_type& polygon_set) {
0123 clean(polygon_set);
0124 polygon_45_set_data<typename polygon_45_set_traits<polygon_set_type>::coordinate_type> ps;
0125 assign(ps, polygon_set);
0126 return ps.extents(extents_rectangle);
0127 }
0128
0129
0130 template <typename polygon_set_type>
0131 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0132 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type>::type
0133 area(const polygon_set_type& polygon_set) {
0134 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0135 typedef polygon_45_with_holes_data<Unit> p_type;
0136 typedef typename coordinate_traits<Unit>::area_type area_type;
0137 std::vector<p_type> polys;
0138 assign(polys, polygon_set);
0139 area_type retval = (area_type)0;
0140 for(std::size_t i = 0; i < polys.size(); ++i) {
0141 retval += area(polys[i]);
0142 }
0143 return retval;
0144 }
0145
0146
0147 template <typename polygon_set_type_1, typename polygon_set_type_2>
0148 typename enable_if <
0149 typename gtl_and< typename gtl_if<typename is_mutable_polygon_45_set_type<polygon_set_type_1>::type>::type,
0150 typename gtl_if<typename is_polygon_45_or_90_set_type<polygon_set_type_2>::type>::type >::type,
0151 polygon_set_type_1>::type&
0152 interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
0153 typedef typename polygon_45_set_traits<polygon_set_type_1>::coordinate_type Unit;
0154 std::vector<polygon_45_data<Unit> > polys;
0155 assign(polys, polygon_set_1);
0156 std::vector<std::set<int> > graph(polys.size()+1, std::set<int>());
0157 connectivity_extraction_45<Unit> ce;
0158 ce.insert(polygon_set_2);
0159 for(std::size_t i = 0; i < polys.size(); ++i){
0160 ce.insert(polys[i]);
0161 }
0162 ce.extract(graph);
0163 clear(polygon_set_1);
0164 polygon_45_set_data<Unit> ps;
0165 for(std::set<int>::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){
0166 ps.insert(polys[(*itr)-1]);
0167 }
0168 assign(polygon_set_1, ps);
0169 return polygon_set_1;
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 template <typename polygon_set_type, typename coord_type>
0182 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0183 polygon_set_type>::type &
0184 resize(polygon_set_type& polygon_set, coord_type resizing,
0185 RoundingOption rounding = CLOSEST, CornerOption corner = INTERSECTION) {
0186 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0187 clean(polygon_set);
0188 polygon_45_set_data<Unit> ps;
0189 assign(ps, polygon_set);
0190 ps.resize(resizing, rounding, corner);
0191 assign(polygon_set, ps);
0192 return polygon_set;
0193 }
0194
0195 template <typename polygon_set_type>
0196 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0197 polygon_set_type>::type &
0198 bloat(polygon_set_type& polygon_set,
0199 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0200 return resize(polygon_set, static_cast<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>(bloating));
0201 }
0202
0203 template <typename polygon_set_type>
0204 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0205 polygon_set_type>::type &
0206 shrink(polygon_set_type& polygon_set,
0207 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
0208 return resize(polygon_set, -(typename polygon_45_set_traits<polygon_set_type>::coordinate_type)shrinking);
0209 }
0210
0211 template <typename polygon_set_type>
0212 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0213 polygon_set_type>::type &
0214 grow_and(polygon_set_type& polygon_set,
0215 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0216 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0217 std::vector<polygon_45_data<Unit> > polys;
0218 assign(polys, polygon_set);
0219 clear(polygon_set);
0220 polygon_45_set_data<Unit> ps;
0221 for(std::size_t i = 0; i < polys.size(); ++i) {
0222 polygon_45_set_data<Unit> tmpPs;
0223 tmpPs.insert(polys[i]);
0224 bloat(tmpPs, bloating);
0225 tmpPs.clean();
0226 ps.insert(tmpPs);
0227 }
0228 ps.self_intersect();
0229 assign(polygon_set, ps);
0230 return polygon_set;
0231 }
0232
0233 template <typename polygon_set_type>
0234 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0235 polygon_set_type>::type &
0236 scale_up(polygon_set_type& polygon_set,
0237 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
0238 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0239 clean(polygon_set);
0240 polygon_45_set_data<Unit> ps;
0241 assign(ps, polygon_set);
0242 ps.scale_up(factor);
0243 assign(polygon_set, ps);
0244 return polygon_set;
0245 }
0246
0247 template <typename polygon_set_type>
0248 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0249 polygon_set_type>::type &
0250 scale_down(polygon_set_type& polygon_set,
0251 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
0252 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0253 clean(polygon_set);
0254 polygon_45_set_data<Unit> ps;
0255 assign(ps, polygon_set);
0256 ps.scale_down(factor);
0257 assign(polygon_set, ps);
0258 return polygon_set;
0259 }
0260
0261 template <typename polygon_set_type>
0262 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0263 polygon_set_type>::type &
0264 scale(polygon_set_type& polygon_set, double factor) {
0265 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0266 clean(polygon_set);
0267 polygon_45_set_data<Unit> ps;
0268 assign(ps, polygon_set);
0269 ps.scale(factor);
0270 assign(polygon_set, ps);
0271 return polygon_set;
0272 }
0273
0274
0275 template <typename polygon_set_type>
0276 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0277 polygon_set_type>::type &
0278 self_intersect(polygon_set_type& polygon_set) {
0279 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0280 polygon_45_set_data<Unit> ps;
0281 assign(ps, polygon_set);
0282 ps.self_intersect();
0283 assign(polygon_set, ps);
0284 return polygon_set;
0285 }
0286
0287
0288 template <typename polygon_set_type>
0289 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0290 polygon_set_type>::type &
0291 self_xor(polygon_set_type& polygon_set) {
0292 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0293 polygon_45_set_data<Unit> ps;
0294 assign(ps, polygon_set);
0295 ps.self_xor();
0296 assign(polygon_set, ps);
0297 return polygon_set;
0298 }
0299
0300
0301 template <typename polygon_set_type, typename transformation_type>
0302 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0303 polygon_set_type>::type &
0304 transform(polygon_set_type& polygon_set,
0305 const transformation_type& transformation) {
0306 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0307 clean(polygon_set);
0308 polygon_45_set_data<Unit> ps;
0309 assign(ps, polygon_set);
0310 ps.transform(transformation);
0311 assign(polygon_set, ps);
0312 return polygon_set;
0313 }
0314
0315
0316 template <typename polygon_set_type>
0317 typename enable_if< typename is_mutable_polygon_45_set_type<polygon_set_type>::type,
0318 polygon_set_type>::type &
0319 keep(polygon_set_type& polygon_set,
0320 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type min_area,
0321 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::area_type max_area,
0322 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
0323 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
0324 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
0325 typename coordinate_traits<typename polygon_45_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
0326 typedef typename polygon_45_set_traits<polygon_set_type>::coordinate_type Unit;
0327 typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
0328 std::list<polygon_45_data<Unit> > polys;
0329 assign(polys, polygon_set);
0330 typename std::list<polygon_45_data<Unit> >::iterator itr_nxt;
0331 for(typename std::list<polygon_45_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
0332 itr_nxt = itr;
0333 ++itr_nxt;
0334 rectangle_data<Unit> bbox;
0335 extents(bbox, *itr);
0336 uat pwidth = delta(bbox, HORIZONTAL);
0337 if(pwidth > min_width && pwidth <= max_width){
0338 uat pheight = delta(bbox, VERTICAL);
0339 if(pheight > min_height && pheight <= max_height){
0340 typename coordinate_traits<Unit>::area_type parea = area(*itr);
0341 if(parea <= max_area && parea >= min_area) {
0342 continue;
0343 }
0344 }
0345 }
0346 polys.erase(itr);
0347 }
0348 assign(polygon_set, polys);
0349 return polygon_set;
0350 }
0351
0352 template <typename T>
0353 struct view_of<polygon_90_set_concept, T> {
0354 typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
0355 T* tp;
0356 std::vector<polygon_90_with_holes_data<coordinate_type> > polys;
0357 view_of(T& obj) : tp(&obj), polys() {
0358 std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
0359 assign(gpolys, obj);
0360 for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
0361 itr != gpolys.end(); ++itr) {
0362 polys.push_back(polygon_90_with_holes_data<coordinate_type>());
0363 assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr));
0364 }
0365 }
0366 view_of(const T& obj) : tp(), polys() {
0367 std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
0368 assign(gpolys, obj);
0369 for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
0370 itr != gpolys.end(); ++itr) {
0371 polys.push_back(polygon_90_with_holes_data<coordinate_type>());
0372 assign(polys.back(), view_as<polygon_90_with_holes_concept>(*itr));
0373 }
0374 }
0375
0376 typedef typename std::vector<polygon_90_with_holes_data<coordinate_type> >::const_iterator iterator_type;
0377 typedef view_of operator_arg_type;
0378
0379 inline iterator_type begin() const {
0380 return polys.begin();
0381 }
0382
0383 inline iterator_type end() const {
0384 return polys.end();
0385 }
0386
0387 inline orientation_2d orient() const { return HORIZONTAL; }
0388
0389 inline bool clean() const { return false; }
0390
0391 inline bool sorted() const { return false; }
0392
0393 inline T& get() { return *tp; }
0394
0395 };
0396
0397 template <typename T>
0398 struct polygon_90_set_traits<view_of<polygon_90_set_concept, T> > {
0399 typedef typename view_of<polygon_90_set_concept, T>::coordinate_type coordinate_type;
0400 typedef typename view_of<polygon_90_set_concept, T>::iterator_type iterator_type;
0401 typedef view_of<polygon_90_set_concept, T> operator_arg_type;
0402
0403 static inline iterator_type begin(const view_of<polygon_90_set_concept, T>& polygon_set) {
0404 return polygon_set.begin();
0405 }
0406
0407 static inline iterator_type end(const view_of<polygon_90_set_concept, T>& polygon_set) {
0408 return polygon_set.end();
0409 }
0410
0411 static inline orientation_2d orient(const view_of<polygon_90_set_concept, T>& polygon_set) {
0412 return polygon_set.orient(); }
0413
0414 static inline bool clean(const view_of<polygon_90_set_concept, T>& polygon_set) {
0415 return polygon_set.clean(); }
0416
0417 static inline bool sorted(const view_of<polygon_90_set_concept, T>& polygon_set) {
0418 return polygon_set.sorted(); }
0419
0420 };
0421
0422 template <typename T>
0423 struct geometry_concept<view_of<polygon_90_set_concept, T> > {
0424 typedef polygon_90_set_concept type;
0425 };
0426
0427 template <typename T>
0428 struct get_coordinate_type<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> {
0429 typedef typename view_of<polygon_90_set_concept, T>::coordinate_type type;
0430 };
0431 template <typename T>
0432 struct get_iterator_type_2<view_of<polygon_90_set_concept, T>, polygon_90_set_concept> {
0433 typedef typename view_of<polygon_90_set_concept, T>::iterator_type type;
0434 static type begin(const view_of<polygon_90_set_concept, T>& t) { return t.begin(); }
0435 static type end(const view_of<polygon_90_set_concept, T>& t) { return t.end(); }
0436 };
0437
0438 }
0439 }
0440 #include "detail/polygon_45_set_view.hpp"
0441 #endif