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_RECTANGLE_CONCEPT_HPP Chris@16: #define BOOST_POLYGON_RECTANGLE_CONCEPT_HPP Chris@16: Chris@16: #include "isotropy.hpp" Chris@16: Chris@16: //point Chris@16: #include "point_data.hpp" Chris@16: #include "point_traits.hpp" Chris@16: #include "point_concept.hpp" Chris@16: Chris@16: //interval Chris@16: #include "interval_data.hpp" Chris@16: #include "interval_traits.hpp" Chris@16: #include "interval_concept.hpp" Chris@16: Chris@16: #include "rectangle_data.hpp" Chris@16: #include "rectangle_traits.hpp" Chris@16: Chris@16: namespace boost { namespace polygon{ Chris@16: struct rectangle_concept {}; Chris@16: Chris@16: template Chris@16: struct is_rectangle_concept { typedef gtl_no type; }; Chris@16: template <> Chris@16: struct is_rectangle_concept { typedef gtl_yes type; }; Chris@16: Chris@16: template Chris@16: struct is_mutable_rectangle_concept { typedef gtl_no type; }; Chris@16: template <> Chris@16: struct is_mutable_rectangle_concept { typedef gtl_yes type; }; Chris@16: Chris@16: template <> Chris@16: struct geometry_domain { typedef manhattan_domain type; }; Chris@16: Chris@16: template Chris@16: struct rectangle_interval_type_by_concept { typedef void type; }; Chris@16: template Chris@16: struct rectangle_interval_type_by_concept { typedef typename rectangle_traits::interval_type type; }; Chris@16: Chris@16: template Chris@16: struct rectangle_interval_type { Chris@16: typedef typename rectangle_interval_type_by_concept::type>::type>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct rectangle_coordinate_type_by_concept { typedef void type; }; Chris@16: template Chris@16: struct rectangle_coordinate_type_by_concept { typedef typename rectangle_traits::coordinate_type type; }; Chris@16: Chris@16: template Chris@16: struct rectangle_coordinate_type { Chris@16: typedef typename rectangle_coordinate_type_by_concept::type>::type>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct rectangle_difference_type_by_concept { typedef void type; }; Chris@16: template Chris@16: struct rectangle_difference_type_by_concept { Chris@16: typedef typename coordinate_traits::coordinate_type>::coordinate_difference type; }; Chris@16: Chris@16: template Chris@16: struct rectangle_difference_type { Chris@16: typedef typename rectangle_difference_type_by_concept< Chris@16: T, typename is_rectangle_concept::type>::type>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct rectangle_distance_type_by_concept { typedef void type; }; Chris@16: template Chris@16: struct rectangle_distance_type_by_concept { Chris@16: typedef typename coordinate_traits::type>::coordinate_distance type; }; Chris@16: Chris@16: template Chris@16: struct rectangle_distance_type { Chris@16: typedef typename rectangle_distance_type_by_concept< Chris@16: T, typename is_rectangle_concept::type>::type>::type type; Chris@16: }; Chris@16: Chris@16: struct y_r_get_interval : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_interval_type::type>::type Chris@16: get(const T& rectangle, orientation_2d orient) { Chris@16: return rectangle_traits::get(rectangle, orient); Chris@16: } Chris@16: Chris@16: struct y_r_h : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_interval_type::type>::type Chris@16: horizontal(const T& rectangle) { Chris@16: return rectangle_traits::get(rectangle, HORIZONTAL); Chris@16: } Chris@16: Chris@16: struct y_r_v : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_interval_type::type>::type Chris@16: vertical(const T& rectangle) { Chris@16: return rectangle_traits::get(rectangle, VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_r_set : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_interval_concept::type>::type>::type, Chris@16: void>::type Chris@16: set(T& rectangle, const T2& interval) { Chris@16: rectangle_mutable_traits::set(rectangle, orient, interval); Chris@16: } Chris@16: Chris@16: struct y_r_set2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_interval_concept::type>::type>::type, Chris@16: void>::type Chris@16: set(T& rectangle, orientation_2d orient, const T2& interval) { Chris@16: rectangle_mutable_traits::set(rectangle, orient, interval); Chris@16: } Chris@16: Chris@16: struct y_r_h2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_interval_concept::type>::type>::type, Chris@16: void>::type Chris@16: horizontal(T& rectangle, const T2& interval) { Chris@16: rectangle_mutable_traits::set(rectangle, HORIZONTAL, interval); Chris@16: } Chris@16: Chris@16: struct y_r_v2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_interval_concept::type>::type>::type, void>::type Chris@16: vertical(T& rectangle, const T2& interval) { Chris@16: rectangle_mutable_traits::set(rectangle, VERTICAL, interval); Chris@16: } Chris@16: Chris@16: struct y_r_construct : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: T>::type Chris@16: construct(const T2& interval_horizontal, Chris@16: const T3& interval_vertical) { Chris@16: return rectangle_mutable_traits::construct(interval_horizontal, interval_vertical); } Chris@16: Chris@16: struct y_r_construct2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: T>::type Chris@16: construct(coord_type xl, coord_type yl, coord_type xh, coord_type yh) { Chris@16: return rectangle_mutable_traits::construct(interval_data(xl, xh), Chris@16: interval_data(yl, yh)); Chris@16: } Chris@16: Chris@16: struct y_r_cconstruct : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: T>::type Chris@16: copy_construct(const T2& rectangle) { Chris@16: return construct (get(rectangle, HORIZONTAL), get(rectangle, VERTICAL)); Chris@16: } Chris@16: Chris@16: struct y_r_assign : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< y_r_assign, Chris@16: typename is_mutable_rectangle_concept::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: rectangle_type_1>::type & Chris@16: assign(rectangle_type_1& lvalue, const rectangle_type_2& rvalue) { Chris@16: set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL)); Chris@16: set(lvalue, VERTICAL, get(rvalue, VERTICAL)); Chris@16: return lvalue; Chris@16: } Chris@16: Chris@16: struct y_r_equiv : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< y_r_equiv, Chris@16: typename is_rectangle_concept::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: equivalence(const T& rect1, const T2& rect2) { Chris@16: return equivalence(get(rect1, HORIZONTAL), get(rect2, HORIZONTAL)) && Chris@16: equivalence(get(rect1, VERTICAL), get(rect2, VERTICAL)); Chris@16: } Chris@16: Chris@16: struct y_r_get : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_coordinate_type::type>::type Chris@16: get(const rectangle_type& rectangle, orientation_2d orient, direction_1d dir) { Chris@16: return get(rectangle_traits::get(rectangle, orient), dir); Chris@16: } Chris@16: Chris@16: struct y_r_set3 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, void>::type Chris@16: set(rectangle_type& rectangle, orientation_2d orient, direction_1d dir, Chris@16: typename rectangle_coordinate_type::type value) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, orient); Chris@16: set(ivl, dir, value); Chris@16: set(rectangle, orient, ivl); Chris@16: } Chris@16: Chris@16: struct y_r_xl : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_coordinate_type::type>::type Chris@16: xl(const rectangle_type& rectangle) { Chris@16: return get(rectangle, HORIZONTAL, LOW); Chris@16: } Chris@16: Chris@16: struct y_r_xl2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, void>::type Chris@16: xl(rectangle_type& rectangle, typename rectangle_coordinate_type::type value) { Chris@16: return set(rectangle, HORIZONTAL, LOW, value); Chris@16: } Chris@16: Chris@16: struct y_r_xh : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_coordinate_type::type>::type Chris@16: xh(const rectangle_type& rectangle) { Chris@16: return get(rectangle, HORIZONTAL, HIGH); Chris@16: } Chris@16: Chris@16: struct y_r_xh2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, void>::type Chris@16: xh(rectangle_type& rectangle, typename rectangle_coordinate_type::type value) { Chris@16: return set(rectangle, HORIZONTAL, HIGH, value); Chris@16: } Chris@16: Chris@16: struct y_r_yl : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_coordinate_type::type>::type Chris@16: yl(const rectangle_type& rectangle) { Chris@16: return get(rectangle, VERTICAL, LOW); Chris@16: } Chris@16: Chris@16: struct y_r_yl2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, void>::type Chris@16: yl(rectangle_type& rectangle, typename rectangle_coordinate_type::type value) { Chris@16: return set(rectangle, VERTICAL, LOW, value); Chris@16: } Chris@16: Chris@16: struct y_r_yh : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_coordinate_type::type>::type Chris@16: yh(const rectangle_type& rectangle) { Chris@16: return get(rectangle, VERTICAL, HIGH); Chris@16: } Chris@16: Chris@16: struct y_r_yh2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, void>::type Chris@16: yh(rectangle_type& rectangle, typename rectangle_coordinate_type::type value) { Chris@16: return set(rectangle, VERTICAL, HIGH, value); Chris@16: } Chris@16: Chris@16: struct y_r_ll : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: point_data::type> >::type Chris@16: ll(const rectangle_type& rectangle) { Chris@16: return point_data::type> (xl(rectangle), yl(rectangle)); Chris@16: } Chris@16: Chris@16: struct y_r_lr : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: point_data::type> >::type Chris@16: lr(const rectangle_type& rectangle) { Chris@16: return point_data::type> (xh(rectangle), yl(rectangle)); Chris@16: } Chris@16: Chris@16: struct y_r_ul : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: point_data::type> >::type Chris@16: ul(const rectangle_type& rectangle) { Chris@16: return point_data::type> (xl(rectangle), yh(rectangle)); Chris@16: } Chris@16: Chris@16: struct y_r_ur : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: point_data::type> >::type Chris@16: ur(const rectangle_type& rectangle) { Chris@16: return point_data::type> (xh(rectangle), yh(rectangle)); Chris@16: } Chris@16: Chris@16: struct y_r_contains : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: contains(const rectangle_type& rectangle, const rectangle_type_2 rectangle_contained, Chris@16: bool consider_touch = true) { Chris@16: return contains(horizontal(rectangle), horizontal(rectangle_contained), consider_touch) && Chris@16: contains(vertical(rectangle), vertical(rectangle_contained), consider_touch); Chris@16: } Chris@16: Chris@16: struct y_r_contains2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, bool>::type Chris@16: contains(const rectangle_type& rectangle, const point_type point_contained, Chris@16: bool consider_touch = true) { Chris@16: return contains(horizontal(rectangle), x(point_contained), consider_touch) && Chris@16: contains(vertical(rectangle), y(point_contained), consider_touch); Chris@16: } Chris@16: Chris@16: struct y_r_set_points : gtl_yes {}; Chris@16: Chris@16: // set all four coordinates based upon two points Chris@16: template Chris@16: typename enable_if< typename gtl_and_4< y_r_set_points, Chris@16: typename is_mutable_rectangle_concept::type>::type, Chris@16: typename is_point_concept::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: set_points(rectangle_type& rectangle, const point_type_1& p1, Chris@16: const point_type_2& p2) { Chris@16: typedef typename rectangle_coordinate_type::type Unit; Chris@16: Unit x1(x(p1)); Chris@16: Unit x2(x(p2)); Chris@16: Unit y1(y(p1)); Chris@16: Unit y2(y(p2)); Chris@16: horizontal(rectangle, construct::type>(x1, x2)); Chris@16: vertical(rectangle, construct::type>(y1, y2)); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_move : gtl_yes {}; Chris@16: Chris@16: // move rectangle by delta in orient Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: move(rectangle_type& rectangle, orientation_2d orient, Chris@16: typename coordinate_traits::type>::coordinate_difference delta) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, orient); Chris@16: move(ivl, delta); Chris@16: set(rectangle, orient, ivl); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_convolve : gtl_yes {}; Chris@16: Chris@16: // convolve this with b Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< y_r_convolve, Chris@16: typename is_mutable_rectangle_concept::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: rectangle_type_1>::type & Chris@16: convolve(rectangle_type_1& rectangle, Chris@16: const rectangle_type_2& convolution_rectangle) { Chris@16: typename rectangle_interval_type::type ivl = horizontal(rectangle); Chris@16: horizontal(rectangle, convolve(ivl, horizontal(convolution_rectangle))); Chris@16: ivl = vertical(rectangle); Chris@16: vertical(rectangle, convolve(ivl, vertical(convolution_rectangle))); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_deconvolve : gtl_yes {}; Chris@16: Chris@16: // deconvolve this with b Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_r_deconvolve, Chris@16: typename is_mutable_rectangle_concept::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: rectangle_type_1>::type & Chris@16: deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { Chris@16: typename rectangle_interval_type::type ivl = horizontal(rectangle); Chris@16: horizontal(rectangle, deconvolve(ivl, horizontal(convolution_rectangle))); Chris@16: ivl = vertical(rectangle); Chris@16: vertical(rectangle, deconvolve(ivl, vertical(convolution_rectangle))); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_reconvolve : gtl_yes {}; Chris@16: Chris@16: // reflectedConvolve this with b Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: rectangle_type_1>::type & Chris@16: reflected_convolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { Chris@16: typename rectangle_interval_type::type ivl = horizontal(rectangle); Chris@16: horizontal(rectangle, reflected_convolve(ivl, horizontal(convolution_rectangle))); Chris@16: ivl = vertical(rectangle); Chris@16: vertical(rectangle, reflected_convolve(ivl, vertical(convolution_rectangle))); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_redeconvolve : gtl_yes {}; Chris@16: Chris@16: // reflectedDeconvolve this with b Chris@16: // deconvolve this with b Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: rectangle_type_1>::type & Chris@16: reflected_deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) { Chris@16: typename rectangle_interval_type::type ivl = horizontal(rectangle); Chris@16: horizontal(rectangle, reflected_deconvolve(ivl, horizontal(convolution_rectangle))); Chris@16: ivl = vertical(rectangle); Chris@16: vertical(rectangle, reflected_deconvolve(ivl, vertical(convolution_rectangle))); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_convolve2 : gtl_yes {}; Chris@16: Chris@16: // convolve with point Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: convolve(rectangle_type& rectangle, const point_type& convolution_point) { Chris@16: typename rectangle_interval_type::type ivl = horizontal(rectangle); Chris@16: horizontal(rectangle, convolve(ivl, x(convolution_point))); Chris@16: ivl = vertical(rectangle); Chris@16: vertical(rectangle, convolve(ivl, y(convolution_point))); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_deconvolve2 : gtl_yes {}; Chris@16: Chris@16: // deconvolve with point Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, rectangle_type>::type & Chris@16: deconvolve(rectangle_type& rectangle, const point_type& convolution_point) { Chris@16: typename rectangle_interval_type::type ivl = horizontal(rectangle); Chris@16: horizontal(rectangle, deconvolve(ivl, x(convolution_point))); Chris@16: ivl = vertical(rectangle); Chris@16: vertical(rectangle, deconvolve(ivl, y(convolution_point))); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_delta : gtl_yes {}; Chris@16: Chris@16: // get the magnitude of the interval range depending on orient Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: delta(const rectangle_type& rectangle, orientation_2d orient) { Chris@16: return delta(get(rectangle, orient)); Chris@16: } Chris@16: Chris@16: struct y_r_area : gtl_yes {}; Chris@16: Chris@16: // get the area of the rectangle Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename coordinate_traits::type>::manhattan_area_type>::type Chris@16: area(const rectangle_type& rectangle) { Chris@16: typedef typename coordinate_traits::type>::manhattan_area_type area_type; Chris@16: return (area_type)delta(rectangle, HORIZONTAL) * (area_type)delta(rectangle, VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_r_go : gtl_yes {}; Chris@16: Chris@16: // returns the orientation of the longest side Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: orientation_2d>::type Chris@16: guess_orientation(const rectangle_type& rectangle) { Chris@16: return delta(rectangle, HORIZONTAL) >= delta(rectangle, VERTICAL) ? Chris@16: HORIZONTAL : VERTICAL; Chris@16: } Chris@16: Chris@16: struct y_r_half_p : gtl_yes {}; Chris@16: Chris@16: // get the half perimeter of the rectangle Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: half_perimeter(const rectangle_type& rectangle) { Chris@16: return delta(rectangle, HORIZONTAL) + delta(rectangle, VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_r_perimeter : gtl_yes {}; Chris@16: Chris@16: // get the perimeter of the rectangle Chris@16: template Chris@16: typename enable_if< typename gtl_and::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: perimeter(const rectangle_type& rectangle) { Chris@16: return 2 * half_perimeter(rectangle); Chris@16: } Chris@16: Chris@16: struct y_r_intersects : gtl_yes {}; Chris@16: Chris@16: // check if Rectangle b intersects `this` Rectangle Chris@16: // [in] b Rectangle that will be checked Chris@16: // [in] considerTouch If true, return true even if b touches the boundary Chris@16: // [ret] . true if `t` intersects b Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: intersects(const rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) { Chris@16: return intersects(horizontal(rectangle), horizontal(b), consider_touch) && Chris@16: intersects(vertical(rectangle), vertical(b), consider_touch); Chris@16: } Chris@16: Chris@16: struct y_r_b_intersect : gtl_yes {}; Chris@16: Chris@16: // Check if boundaries of Rectangle b and `this` Rectangle intersect Chris@16: // [in] b Rectangle that will be checked Chris@16: // [in] considerTouch If true, return true even if p is on the foundary Chris@16: // [ret] . true if `t` contains p Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: boundaries_intersect(const rectangle_type_1& rectangle, const rectangle_type_2& b, Chris@16: bool consider_touch = true) { Chris@16: return (intersects(rectangle, b, consider_touch) && Chris@16: !(contains(rectangle, b, !consider_touch)) && Chris@16: !(contains(b, rectangle, !consider_touch))); Chris@16: } Chris@16: Chris@16: struct y_r_b_abuts : gtl_yes {}; Chris@16: Chris@16: // check if b is touching 'this' on the end specified by dir Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, Chris@16: direction_2d dir) { Chris@16: return Chris@16: abuts(get(rectangle, orientation_2d(dir)), Chris@16: get(b, orientation_2d(dir)), Chris@16: direction_1d(dir)) && Chris@16: intersects(get(rectangle, orientation_2d(dir).get_perpendicular()), Chris@16: get(b, orientation_2d(dir).get_perpendicular()), true); Chris@16: } Chris@16: Chris@16: struct y_r_b_abuts2 : gtl_yes {}; Chris@16: Chris@16: // check if they are touching in the given orientation Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b, Chris@16: orientation_2d orient) { Chris@16: return Chris@16: abuts(get(rectangle, orient), get(b, orient)) && Chris@16: intersects(get(rectangle, orient.get_perpendicular()), Chris@16: get(b, orient.get_perpendicular()), true); Chris@16: } Chris@16: Chris@16: struct y_r_b_abuts3 : gtl_yes {}; Chris@16: Chris@16: // check if they are touching but not overlapping Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b) { Chris@16: return abuts(rectangle, b, HORIZONTAL) || abuts(rectangle, b, VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_r_b_intersect2 : gtl_yes {}; Chris@16: Chris@16: // intersect rectangle with interval on orient Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_interval_concept::type>::type>::type, Chris@16: bool>::type Chris@16: intersect(rectangle_type& rectangle, const interval_type& b, Chris@16: orientation_2d orient, bool consider_touch = true) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, orient); Chris@16: if(intersect(ivl, b, consider_touch)) { Chris@16: set(rectangle, orient, ivl); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: struct y_r_b_intersect3 : gtl_yes {}; Chris@16: Chris@16: // clip rectangle to b Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: intersect(rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) { Chris@16: if(intersects(rectangle, b)) { Chris@16: intersect(rectangle, horizontal(b), HORIZONTAL, consider_touch); Chris@16: intersect(rectangle, vertical(b), VERTICAL, consider_touch); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: struct y_r_g_intersect : gtl_yes {}; Chris@16: Chris@16: // Sets this to the generalized intersection of this and the given rectangle Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: rectangle_type_1>::type & Chris@16: generalized_intersect(rectangle_type_1& rectangle, const rectangle_type_2& b) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, HORIZONTAL); Chris@16: generalized_intersect(ivl, horizontal(b)); Chris@16: horizontal(rectangle, ivl); Chris@16: ivl = vertical(rectangle); Chris@16: generalized_intersect(ivl, vertical(b)); Chris@16: vertical(rectangle, ivl); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_bloat : gtl_yes {}; Chris@16: Chris@16: // bloat the interval specified by orient by bloating Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: bloat(rectangle_type& rectangle, orientation_2d orient, Chris@16: typename rectangle_coordinate_type::type bloating) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, orient); Chris@16: bloat(ivl, bloating); Chris@16: set(rectangle, orient, ivl); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_bloat2 : gtl_yes {}; Chris@16: Chris@16: // bloat the Rectangle by bloating Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: bloat(rectangle_type& rectangle, Chris@16: typename rectangle_coordinate_type::type bloating) { Chris@16: bloat(rectangle, HORIZONTAL, bloating); Chris@16: return bloat(rectangle, VERTICAL, bloating); Chris@16: } Chris@16: Chris@16: struct y_r_bloat3 : gtl_yes {}; Chris@16: Chris@16: // bloat the interval cooresponding to orient by bloating in dir direction Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: bloat(rectangle_type& rectangle, direction_2d dir, Chris@16: typename rectangle_coordinate_type::type bloating) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, orientation_2d(dir)); Chris@16: bloat(ivl, direction_1d(dir), bloating); Chris@16: set(rectangle, orientation_2d(dir), ivl); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_shrink : gtl_yes {}; Chris@16: Chris@16: // shrink the interval specified by orient by bloating Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: shrink(rectangle_type& rectangle, orientation_2d orient, Chris@16: typename rectangle_coordinate_type::type shrinking) { Chris@16: return bloat(rectangle, orient, -shrinking); Chris@16: } Chris@16: Chris@16: struct y_r_shrink2 : gtl_yes {}; Chris@16: Chris@16: // shrink the Rectangle by bloating Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: shrink(rectangle_type& rectangle, Chris@16: typename rectangle_coordinate_type::type shrinking) { Chris@16: return bloat(rectangle, -shrinking); Chris@16: } Chris@16: Chris@16: struct y_r_shrink3 : gtl_yes {}; Chris@16: Chris@16: // shrink the interval cooresponding to orient by bloating in dir direction Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: shrink(rectangle_type& rectangle, direction_2d dir, Chris@16: typename rectangle_coordinate_type::type shrinking) { Chris@16: return bloat(rectangle, dir, -shrinking); Chris@16: } Chris@16: Chris@16: struct y_r_encompass : gtl_yes {}; Chris@16: Chris@16: // encompass interval on orient Chris@16: template Chris@16: typename enable_if::type>::type, Chris@16: typename is_interval_concept::type>::type>::type, Chris@16: bool>::type Chris@16: encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) { Chris@16: typename rectangle_interval_type::type ivl = get(rectangle, orient); Chris@16: if(encompass(ivl, b)) { Chris@16: set(rectangle, orient, ivl); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: struct y_r_encompass2 : gtl_yes {}; Chris@16: Chris@16: // enlarge rectangle to encompass the Rectangle b Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< Chris@16: y_r_encompass2, Chris@16: typename is_mutable_rectangle_concept::type>::type, Chris@16: typename is_rectangle_concept::type>::type >::type, Chris@16: bool>::type Chris@16: encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) { Chris@16: //note that operator | is intentional because both should be called regardless Chris@16: return encompass(rectangle, horizontal(b), HORIZONTAL) | Chris@16: encompass(rectangle, vertical(b), VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_r_encompass3 : gtl_yes {}; Chris@16: Chris@16: // enlarge rectangle to encompass the point b Chris@16: template Chris@16: typename enable_if::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: bool>::type Chris@16: encompass(rectangle_type_1& rectangle, const point_type& b) { Chris@16: typename rectangle_interval_type::type hivl, vivl; Chris@16: hivl = horizontal(rectangle); Chris@16: vivl = vertical(rectangle); Chris@16: //note that operator | is intentional because both should be called regardless Chris@16: bool retval = encompass(hivl, x(b)) | encompass(vivl, y(b)); Chris@16: if(retval) { Chris@16: horizontal(rectangle, hivl); Chris@16: vertical(rectangle, vivl); Chris@16: } Chris@16: return retval; Chris@16: } Chris@16: Chris@16: struct y_r_center : gtl_yes {}; Chris@16: Chris@16: // returns the center of the rectangle Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: center(point_type& center_point, const rectangle_type& rectangle) { Chris@16: center_point = construct(center(horizontal(rectangle)), Chris@16: center(vertical(rectangle))); Chris@16: return true; Chris@16: } Chris@16: Chris@16: struct y_r_get_corner : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) { Chris@16: typedef typename rectangle_coordinate_type::type Unit; Chris@16: Unit u1 = get(rectangle, direction_facing); Chris@16: Unit u2 = get(rectangle, direction_facing.turn(direction_turning)); Chris@16: if(orientation_2d(direction_facing).to_int()) std::swap(u1, u2); Chris@16: corner_point = construct(u1, u2); Chris@16: return true; Chris@16: } Chris@16: Chris@16: struct y_r_get_half : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type Chris@16: get_half(const rectangle_type& rectangle, direction_2d dir) { Chris@16: rectangle_type retval(rectangle); Chris@16: set(retval, orientation_2d(dir), get_half(get(rectangle, orientation_2d(dir)), direction_1d(dir))); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: struct y_r_join_with : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) { Chris@16: typedef typename rectangle_interval_type::type Interval1; Chris@16: typedef typename rectangle_interval_type::type Interval2; Chris@16: Interval1 hi1 = get(rectangle, HORIZONTAL); Chris@16: Interval1 vi1 = get(rectangle, VERTICAL); Chris@16: Interval2 hi2 = get(b, HORIZONTAL), vi2 = get(b, VERTICAL); Chris@16: Interval1 temp; Chris@16: if (equivalence(hi1, hi2) && join_with(vi1, vi2)) { Chris@16: vertical(rectangle, vi1); Chris@16: return true; Chris@16: } Chris@16: if (equivalence(vi1, vi2) && join_with(hi1, hi2)) { Chris@16: horizontal(rectangle, hi1); Chris@16: return true; Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@16: struct y_r_eda2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: euclidean_distance(const rectangle_type& lvalue, const point_type& rvalue, orientation_2d orient) { Chris@16: return euclidean_distance(get(lvalue, orient), get(rvalue, orient)); Chris@16: } Chris@16: Chris@16: struct y_r_eda : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue, orientation_2d orient) { Chris@16: return euclidean_distance(get(lvalue, orient), get(rvalue, orient)); Chris@16: } Chris@16: Chris@16: struct y_r_sed : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: square_euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { Chris@16: typename coordinate_traits::type>::coordinate_difference xdist, ydist; Chris@16: xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); Chris@16: ydist = euclidean_distance(lvalue, rvalue, VERTICAL); Chris@16: return (xdist * xdist) + (ydist * ydist); Chris@16: } Chris@16: Chris@16: struct y_r_sed2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept< typename geometry_concept::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: square_euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { Chris@16: typename coordinate_traits::type>::coordinate_difference xdist, ydist; Chris@16: xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); Chris@16: ydist = euclidean_distance(lvalue, rvalue, VERTICAL); Chris@16: return (xdist * xdist) + (ydist * ydist); Chris@16: } Chris@16: Chris@16: struct y_r_edist : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: typename rectangle_distance_type::type>::type Chris@16: euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) { Chris@16: return std::sqrt((double)(square_euclidean_distance(lvalue, rvalue))); Chris@16: } Chris@16: Chris@16: struct y_r_edist2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: typename rectangle_distance_type::type>::type Chris@16: euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { Chris@16: double val = (int)square_euclidean_distance(lvalue, rvalue); Chris@16: return std::sqrt(val); Chris@16: } Chris@16: Chris@16: struct y_r_mdist : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_point_concept::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: manhattan_distance(rectangle_type& lvalue, const point_type& rvalue) { Chris@16: typename coordinate_traits::type>::coordinate_difference xdist, ydist; Chris@16: xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); Chris@16: ydist = euclidean_distance(lvalue, rvalue, VERTICAL); Chris@16: return xdist + ydist; Chris@16: } Chris@16: Chris@16: struct y_r_mdist2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: typename rectangle_difference_type::type>::type Chris@16: manhattan_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { Chris@16: typename coordinate_traits::type>::coordinate_difference xdist, ydist; Chris@16: xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL); Chris@16: ydist = euclidean_distance(lvalue, rvalue, VERTICAL); Chris@16: return xdist + ydist; Chris@16: } Chris@16: Chris@16: struct y_r_scale_up : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: scale_up(rectangle_type& rectangle, Chris@16: typename coordinate_traits::type>::unsigned_area_type factor) { Chris@101: typename rectangle_interval_type::type h = horizontal(rectangle); Chris@101: horizontal(rectangle, scale_up(h, factor)); Chris@101: typename rectangle_interval_type::type v = vertical(rectangle); Chris@101: vertical(rectangle, scale_up(v, factor)); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_scale_down : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: scale_down(rectangle_type& rectangle, Chris@16: typename coordinate_traits::type>::unsigned_area_type factor) { Chris@101: typename rectangle_interval_type::type h = horizontal(rectangle); Chris@101: horizontal(rectangle, scale_down(h, factor)); Chris@101: typename rectangle_interval_type::type v = vertical(rectangle); Chris@101: vertical(rectangle, scale_down(v, factor)); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_scale : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: scale(rectangle_type& rectangle, const scaling_type& scaling) { Chris@16: point_data::type> llp(xl(rectangle), yl(rectangle)); Chris@16: point_data::type> urp(xl(rectangle), yl(rectangle)); Chris@16: scale(llp, scaling); Chris@16: scale(urp, scaling); Chris@16: set_points(rectangle, llp, urp); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: struct y_r_transform : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if::type>::type>::type, Chris@16: rectangle_type>::type & Chris@16: transform(rectangle_type& rectangle, const transformation_type& transformation) { Chris@16: point_data::type> llp(xl(rectangle), yl(rectangle)); Chris@16: point_data::type> urp(xh(rectangle), yh(rectangle)); Chris@16: transform(llp, transformation); Chris@16: transform(urp, transformation); Chris@16: set_points(rectangle, llp, urp); Chris@16: return rectangle; Chris@16: } Chris@16: Chris@16: template Chris@16: class less_rectangle_concept { Chris@16: private: Chris@16: orientation_2d orient_; Chris@16: public: Chris@16: inline less_rectangle_concept(orientation_2d orient = VERTICAL) : orient_(orient) {} Chris@16: typename enable_if< Chris@16: typename gtl_and< typename is_rectangle_concept::type>::type, Chris@16: typename is_rectangle_concept::type>::type>::type, Chris@16: bool>::type Chris@16: operator () (const rectangle_type_1& a, Chris@16: const rectangle_type_2& b) const { Chris@16: typedef typename rectangle_coordinate_type::type Unit; Chris@16: Unit vl1 = get(get(a, orient_), LOW); Chris@16: Unit vl2 = get(get(b, orient_), LOW); Chris@16: if(vl1 > vl2) return false; Chris@16: if(vl1 == vl2) { Chris@16: orientation_2d perp = orient_.get_perpendicular(); Chris@16: Unit hl1 = get(get(a, perp), LOW); Chris@16: Unit hl2 = get(get(b, perp), LOW); Chris@16: if(hl1 > hl2) return false; Chris@16: if(hl1 == hl2) { Chris@16: Unit vh1 = get(get(a, orient_), HIGH); Chris@16: Unit vh2 = get(get(b, orient_), HIGH); Chris@16: if(vh1 > vh2) return false; Chris@16: if(vh1 == vh2) { Chris@16: Unit hh1 = get(get(a, perp), HIGH); Chris@16: Unit hh2 = get(get(b, perp), HIGH); Chris@16: return hh1 < hh2; Chris@16: } Chris@16: } Chris@16: } Chris@16: return true; Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: template Chris@16: template Chris@16: inline void rectangle_data::set(orientation_2d orient, const interval_type_1& interval) { Chris@16: assign(ranges_[orient.to_int()], interval); Chris@16: } Chris@16: Chris@16: template Chris@16: template Chris@16: rectangle_data& rectangle_data::operator=(const T2& rvalue) { Chris@16: assign(*this, rvalue); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: template Chris@16: bool rectangle_data::operator==(const T2& rvalue) const { Chris@16: return equivalence(*this, rvalue); Chris@16: } Chris@16: Chris@16: template Chris@16: struct geometry_concept > { Chris@16: typedef rectangle_concept type; Chris@16: }; Chris@16: } Chris@16: } Chris@16: #endif