Chris@16: /* Chris@16: Copyright 2008 Intel Corporation Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: */ Chris@16: #ifndef BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP Chris@16: #define BOOST_POLYGON_POLYGON_45_SET_CONCEPT_HPP Chris@16: #include "polygon_45_set_data.hpp" Chris@16: #include "polygon_45_set_traits.hpp" Chris@16: #include "detail/polygon_45_touch.hpp" Chris@16: namespace boost { namespace polygon{ Chris@16: Chris@16: template Chris@16: struct is_either_polygon_45_set_type { Chris@16: typedef typename gtl_or::type, typename is_polygon_45_set_type::type >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_polygon_45_or_90_set_type { Chris@16: typedef typename gtl_or::type, typename is_polygon_90_set_type::type >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: typename polygon_45_set_traits::iterator_type>::type Chris@16: begin_45_set_data(const polygon_set_type& polygon_set) { Chris@16: return polygon_45_set_traits::begin(polygon_set); Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: typename polygon_45_set_traits::iterator_type>::type Chris@16: end_45_set_data(const polygon_set_type& polygon_set) { Chris@16: return polygon_45_set_traits::end(polygon_set); Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: bool>::type Chris@16: clean(const polygon_set_type& polygon_set) { Chris@16: return polygon_45_set_traits::clean(polygon_set); Chris@16: } Chris@16: Chris@16: //assign Chris@16: template Chris@16: typename enable_if< typename gtl_and< typename gtl_if::type>::type, Chris@16: typename gtl_if::type>::type>::type, Chris@16: polygon_set_type_1>::type & Chris@16: assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) { Chris@16: polygon_45_set_mutable_traits::set(lvalue, begin_45_set_data(rvalue), end_45_set_data(rvalue)); Chris@16: return lvalue; Chris@16: } Chris@16: Chris@16: //get trapezoids Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: void>::type Chris@16: get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) { Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data::coordinate_type> ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.get_trapezoids(output); Chris@16: } Chris@16: Chris@16: //get trapezoids Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: void>::type Chris@16: get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set, orientation_2d slicing_orientation) { Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data::coordinate_type> ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.get_trapezoids(output, slicing_orientation); Chris@16: } Chris@16: Chris@16: //equivalence Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename gtl_if::type>::type, Chris@16: typename gtl_if::type>::type>::type, Chris@16: bool>::type Chris@16: equivalence(const polygon_set_type_1& lvalue, Chris@16: const polygon_set_type_2& rvalue) { Chris@16: polygon_45_set_data::coordinate_type> ps1; Chris@16: assign(ps1, lvalue); Chris@16: polygon_45_set_data::coordinate_type> ps2; Chris@16: assign(ps2, rvalue); Chris@16: return ps1 == ps2; Chris@16: } Chris@16: Chris@16: //clear Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: void>::type Chris@16: clear(polygon_set_type& polygon_set) { Chris@16: polygon_45_set_data::coordinate_type> ps; Chris@16: assign(polygon_set, ps); Chris@16: } Chris@16: Chris@16: //empty Chris@16: template Chris@16: typename enable_if< typename gtl_if::type>::type, Chris@16: bool>::type Chris@16: empty(const polygon_set_type& polygon_set) { Chris@16: if(clean(polygon_set)) return begin_45_set_data(polygon_set) == end_45_set_data(polygon_set); Chris@16: polygon_45_set_data::coordinate_type> ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.clean(); Chris@16: return ps.empty(); Chris@16: } Chris@16: Chris@16: //extents Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< typename gtl_if::type>::type, Chris@16: typename is_mutable_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: extents(rectangle_type& extents_rectangle, Chris@16: const polygon_set_type& polygon_set) { Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data::coordinate_type> ps; Chris@16: assign(ps, polygon_set); Chris@16: return ps.extents(extents_rectangle); Chris@16: } Chris@16: Chris@16: //area Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: typename coordinate_traits::coordinate_type>::area_type>::type Chris@16: area(const polygon_set_type& polygon_set) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: typedef polygon_45_with_holes_data p_type; Chris@16: typedef typename coordinate_traits::area_type area_type; Chris@16: std::vector polys; Chris@16: assign(polys, polygon_set); Chris@16: area_type retval = (area_type)0; Chris@16: for(std::size_t i = 0; i < polys.size(); ++i) { Chris@16: retval += area(polys[i]); Chris@16: } Chris@16: return retval; Chris@16: } Chris@16: Chris@16: //interact Chris@16: template Chris@16: typename enable_if < Chris@16: typename gtl_and< typename gtl_if::type>::type, Chris@16: typename gtl_if::type>::type >::type, Chris@16: polygon_set_type_1>::type& Chris@16: interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: std::vector > polys; Chris@16: assign(polys, polygon_set_1); Chris@16: std::vector > graph(polys.size()+1, std::set()); Chris@16: connectivity_extraction_45 ce; Chris@16: ce.insert(polygon_set_2); Chris@16: for(std::size_t i = 0; i < polys.size(); ++i){ Chris@16: ce.insert(polys[i]); Chris@16: } Chris@16: ce.extract(graph); Chris@16: clear(polygon_set_1); Chris@16: polygon_45_set_data ps; Chris@16: for(std::set::iterator itr = graph[0].begin(); itr != graph[0].end(); ++itr){ Chris@16: ps.insert(polys[(*itr)-1]); Chris@16: } Chris@16: assign(polygon_set_1, ps); Chris@16: return polygon_set_1; Chris@16: } Chris@16: Chris@16: // //self_intersect Chris@16: // template Chris@16: // typename enable_if< typename is_mutable_polygon_45_set_type::type>::type, Chris@16: // polygon_set_type>::type & Chris@16: // self_intersect(polygon_set_type& polygon_set) { Chris@16: // typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: // //TODO Chris@16: // } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: resize(polygon_set_type& polygon_set, coord_type resizing, Chris@16: RoundingOption rounding = CLOSEST, CornerOption corner = INTERSECTION) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.resize(resizing, rounding, corner); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: bloat(polygon_set_type& polygon_set, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type bloating) { Chris@16: return resize(polygon_set, static_cast::coordinate_type>(bloating)); Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: shrink(polygon_set_type& polygon_set, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type shrinking) { Chris@16: return resize(polygon_set, -(typename polygon_45_set_traits::coordinate_type)shrinking); Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: grow_and(polygon_set_type& polygon_set, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type bloating) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: std::vector > polys; Chris@16: assign(polys, polygon_set); Chris@16: clear(polygon_set); Chris@16: polygon_45_set_data ps; Chris@16: for(std::size_t i = 0; i < polys.size(); ++i) { Chris@16: polygon_45_set_data tmpPs; Chris@16: tmpPs.insert(polys[i]); Chris@16: bloat(tmpPs, bloating); Chris@16: tmpPs.clean(); //apply implicit OR on tmp polygon set Chris@16: ps.insert(tmpPs); Chris@16: } Chris@16: ps.self_intersect(); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: scale_up(polygon_set_type& polygon_set, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type factor) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.scale_up(factor); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: scale_down(polygon_set_type& polygon_set, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type factor) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.scale_down(factor); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: scale(polygon_set_type& polygon_set, double factor) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.scale(factor); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: //self_intersect Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: self_intersect(polygon_set_type& polygon_set) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.self_intersect(); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: //self_xor Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: self_xor(polygon_set_type& polygon_set) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.self_xor(); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: //transform Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: transform(polygon_set_type& polygon_set, Chris@16: const transformation_type& transformation) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: clean(polygon_set); Chris@16: polygon_45_set_data ps; Chris@16: assign(ps, polygon_set); Chris@16: ps.transform(transformation); Chris@16: assign(polygon_set, ps); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: //keep Chris@16: template Chris@16: typename enable_if< typename is_mutable_polygon_45_set_type::type, Chris@16: polygon_set_type>::type & Chris@16: keep(polygon_set_type& polygon_set, Chris@16: typename coordinate_traits::coordinate_type>::area_type min_area, Chris@16: typename coordinate_traits::coordinate_type>::area_type max_area, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type min_width, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type max_width, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type min_height, Chris@16: typename coordinate_traits::coordinate_type>::unsigned_area_type max_height) { Chris@16: typedef typename polygon_45_set_traits::coordinate_type Unit; Chris@16: typedef typename coordinate_traits::unsigned_area_type uat; Chris@16: std::list > polys; Chris@16: assign(polys, polygon_set); Chris@16: typename std::list >::iterator itr_nxt; Chris@16: for(typename std::list >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){ Chris@16: itr_nxt = itr; Chris@16: ++itr_nxt; Chris@16: rectangle_data bbox; Chris@16: extents(bbox, *itr); Chris@16: uat pwidth = delta(bbox, HORIZONTAL); Chris@16: if(pwidth > min_width && pwidth <= max_width){ Chris@16: uat pheight = delta(bbox, VERTICAL); Chris@16: if(pheight > min_height && pheight <= max_height){ Chris@16: typename coordinate_traits::area_type parea = area(*itr); Chris@16: if(parea <= max_area && parea >= min_area) { Chris@16: continue; Chris@16: } Chris@16: } Chris@16: } Chris@16: polys.erase(itr); Chris@16: } Chris@16: assign(polygon_set, polys); Chris@16: return polygon_set; Chris@16: } Chris@16: Chris@16: template Chris@16: struct view_of { Chris@16: typedef typename get_coordinate_type::type >::type coordinate_type; Chris@16: T* tp; Chris@16: std::vector > polys; Chris@16: view_of(T& obj) : tp(&obj), polys() { Chris@16: std::vector > gpolys; Chris@16: assign(gpolys, obj); Chris@16: for(typename std::vector >::iterator itr = gpolys.begin(); Chris@16: itr != gpolys.end(); ++itr) { Chris@16: polys.push_back(polygon_90_with_holes_data()); Chris@16: assign(polys.back(), view_as(*itr)); Chris@16: } Chris@16: } Chris@16: view_of(const T& obj) : tp(), polys() { Chris@16: std::vector > gpolys; Chris@16: assign(gpolys, obj); Chris@16: for(typename std::vector >::iterator itr = gpolys.begin(); Chris@16: itr != gpolys.end(); ++itr) { Chris@16: polys.push_back(polygon_90_with_holes_data()); Chris@16: assign(polys.back(), view_as(*itr)); Chris@16: } Chris@16: } Chris@16: Chris@16: typedef typename std::vector >::const_iterator iterator_type; Chris@16: typedef view_of operator_arg_type; Chris@16: Chris@16: inline iterator_type begin() const { Chris@16: return polys.begin(); Chris@16: } Chris@16: Chris@16: inline iterator_type end() const { Chris@16: return polys.end(); Chris@16: } Chris@16: Chris@16: inline orientation_2d orient() const { return HORIZONTAL; } Chris@16: Chris@16: inline bool clean() const { return false; } Chris@16: Chris@16: inline bool sorted() const { return false; } Chris@16: Chris@16: inline T& get() { return *tp; } Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: struct polygon_90_set_traits > { Chris@16: typedef typename view_of::coordinate_type coordinate_type; Chris@16: typedef typename view_of::iterator_type iterator_type; Chris@16: typedef view_of operator_arg_type; Chris@16: Chris@16: static inline iterator_type begin(const view_of& polygon_set) { Chris@16: return polygon_set.begin(); Chris@16: } Chris@16: Chris@16: static inline iterator_type end(const view_of& polygon_set) { Chris@16: return polygon_set.end(); Chris@16: } Chris@16: Chris@16: static inline orientation_2d orient(const view_of& polygon_set) { Chris@16: return polygon_set.orient(); } Chris@16: Chris@16: static inline bool clean(const view_of& polygon_set) { Chris@16: return polygon_set.clean(); } Chris@16: Chris@16: static inline bool sorted(const view_of& polygon_set) { Chris@16: return polygon_set.sorted(); } Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: struct geometry_concept > { Chris@16: typedef polygon_90_set_concept type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct get_coordinate_type, polygon_90_set_concept> { Chris@16: typedef typename view_of::coordinate_type type; Chris@16: }; Chris@16: template Chris@16: struct get_iterator_type_2, polygon_90_set_concept> { Chris@16: typedef typename view_of::iterator_type type; Chris@16: static type begin(const view_of& t) { return t.begin(); } Chris@16: static type end(const view_of& t) { return t.end(); } Chris@16: }; Chris@16: Chris@16: } Chris@16: } Chris@16: #include "detail/polygon_45_set_view.hpp" Chris@16: #endif