Chris@16: // Boost.Polygon library point_concept.hpp header file Chris@16: Chris@16: // Copyright (c) Intel Corporation 2008. Chris@16: // Copyright (c) 2008-2012 Simonson Lucanus. Chris@16: // Copyright (c) 2012-2012 Andrii Sydorchuk. Chris@16: Chris@16: // See http://www.boost.org for updates, documentation, and revision history. Chris@16: // Use, modification and distribution is 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_POINT_CONCEPT_HPP Chris@16: #define BOOST_POLYGON_POINT_CONCEPT_HPP Chris@16: Chris@16: #include "isotropy.hpp" Chris@16: #include "point_traits.hpp" Chris@16: Chris@16: namespace boost { Chris@16: namespace polygon { Chris@16: Chris@16: struct point_concept {}; Chris@16: Chris@16: template Chris@16: struct is_point_concept { Chris@16: typedef gtl_no type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct is_point_concept { Chris@16: typedef gtl_yes type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_mutable_point_concept { Chris@16: typedef gtl_no type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct is_mutable_point_concept { Chris@16: typedef gtl_yes type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_coordinate_type_by_concept { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_coordinate_type_by_concept { Chris@16: typedef typename point_traits::coordinate_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_coordinate_type { Chris@16: typedef typename point_coordinate_type_by_concept< Chris@16: GeometryType, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_difference_type_by_concept { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_difference_type_by_concept { Chris@16: typedef typename coordinate_traits< Chris@16: typename point_traits::coordinate_type Chris@16: >::coordinate_difference type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_difference_type { Chris@16: typedef typename point_difference_type_by_concept< Chris@16: GeometryType, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_distance_type_by_concept { Chris@16: typedef void type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_distance_type_by_concept { Chris@16: typedef typename coordinate_traits< Chris@16: typename point_coordinate_type::type Chris@16: >::coordinate_distance type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct point_distance_type { Chris@16: typedef typename point_distance_type_by_concept< Chris@16: GeometryType, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: struct y_pt_get : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_get, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_coordinate_type::type Chris@16: >::type get(const PointType& point, orientation_2d orient) { Chris@16: return point_traits::get(point, orient); Chris@16: } Chris@16: Chris@16: struct y_pt_set : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_set, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: void Chris@16: >::type set(PointType& point, orientation_2d orient, Chris@16: typename point_mutable_traits::coordinate_type value) { Chris@16: point_mutable_traits::set(point, orient, value); Chris@16: } Chris@16: Chris@16: struct y_pt_construct : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_construct, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType>::type construct( Chris@16: typename point_mutable_traits::coordinate_type x, Chris@16: typename point_mutable_traits::coordinate_type y) { Chris@16: return point_mutable_traits::construct(x, y); Chris@16: } Chris@16: Chris@16: struct y_pt_assign : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_assign, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType1>::type& assign(PointType1& lvalue, const PointType2& 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_p_x : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_p_x, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_coordinate_type::type Chris@16: >::type x(const PointType& point) { Chris@16: return get(point, HORIZONTAL); Chris@16: } Chris@16: Chris@16: struct y_p_y : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_p_y, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_coordinate_type::type Chris@16: >::type y(const PointType& point) { Chris@16: return get(point, VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_p_sx : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_p_sx, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: void>::type x(PointType& point, Chris@16: typename point_mutable_traits::coordinate_type value) { Chris@16: set(point, HORIZONTAL, value); Chris@16: } Chris@16: Chris@16: struct y_p_sy : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_p_sy, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: void>::type y(PointType& point, Chris@16: typename point_mutable_traits::coordinate_type value) { Chris@16: set(point, VERTICAL, value); Chris@16: } Chris@16: Chris@16: struct y_pt_equiv : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_equiv, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: bool>::type equivalence( Chris@16: const PointType1& point1, const PointType2& point2) { Chris@16: return (x(point1) == x(point2)) && (y(point1) == y(point2)); Chris@16: } Chris@16: Chris@16: struct y_pt_man_dist : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_man_dist, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_difference_type::type>::type Chris@16: manhattan_distance(const PointType1& point1, const PointType2& point2) { Chris@16: return euclidean_distance(point1, point2, HORIZONTAL) + Chris@16: euclidean_distance(point1, point2, VERTICAL); Chris@16: } Chris@16: Chris@16: struct y_pt_ed1 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_ed1, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_difference_type::type>::type Chris@16: euclidean_distance( Chris@16: const PointType1& point1, Chris@16: const PointType2& point2, Chris@16: orientation_2d orient) { Chris@16: typename point_difference_type::type dif = Chris@16: get(point1, orient) - get(point2, orient); Chris@16: return (dif < 0) ? -dif : dif; Chris@16: } Chris@16: Chris@16: struct y_pt_eds : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_eds, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_difference_type::type>::type Chris@16: distance_squared(const PointType1& point1, const PointType2& point2) { Chris@16: typename point_difference_type::type dx = Chris@16: euclidean_distance(point1, point2, HORIZONTAL); Chris@16: typename point_difference_type::type dy = Chris@16: euclidean_distance(point1, point2, VERTICAL); Chris@16: dx *= dx; Chris@16: dy *= dy; Chris@16: return dx + dy; Chris@16: } Chris@16: Chris@16: struct y_pt_ed2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_ed2, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: typename point_distance_type::type>::type Chris@16: euclidean_distance(const PointType1& point1, const PointType2& point2) { Chris@16: return (std::sqrt)( Chris@16: static_cast(distance_squared(point1, point2))); Chris@16: } Chris@16: Chris@16: struct y_pt_convolve : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_convolve, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType1>::type& convolve(PointType1& lvalue, const PointType2& rvalue) { Chris@16: x(lvalue, x(lvalue) + x(rvalue)); Chris@16: y(lvalue, y(lvalue) + y(rvalue)); Chris@16: return lvalue; Chris@16: } Chris@16: Chris@16: struct y_pt_deconvolve : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< Chris@16: y_pt_deconvolve, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type, Chris@16: typename is_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType1>::type& deconvolve(PointType1& lvalue, const PointType2& rvalue) { Chris@16: x(lvalue, x(lvalue) - x(rvalue)); Chris@16: y(lvalue, y(lvalue) - y(rvalue)); Chris@16: return lvalue; Chris@16: } Chris@16: Chris@16: struct y_pt_scale_up : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_scale_up, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType>::type& scale_up(PointType& point, CType factor) { Chris@16: typedef typename point_coordinate_type::type Unit; Chris@16: x(point, x(point) * (Unit)factor); Chris@16: y(point, y(point) * (Unit)factor); Chris@16: return point; Chris@16: } Chris@16: Chris@16: struct y_pt_scale_down : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_scale_down, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType>::type& scale_down(PointType& point, CType factor) { Chris@16: typedef typename point_coordinate_type::type Unit; Chris@16: typedef typename coordinate_traits::coordinate_distance dt; Chris@16: x(point, scaling_policy::round((dt)(x(point)) / (dt)factor)); Chris@16: y(point, scaling_policy::round((dt)(y(point)) / (dt)factor)); Chris@16: return point; Chris@16: } Chris@16: Chris@16: struct y_pt_scale : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_scale, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType>::type& scale(PointType& point, const ScaleType& scaling) { Chris@16: typedef typename point_coordinate_type::type Unit; Chris@16: Unit x_coord(x(point)); Chris@16: Unit y_coord(y(point)); Chris@16: scaling.scale(x_coord, y_coord); Chris@16: x(point, x_coord); Chris@16: y(point, y_coord); Chris@16: return point; Chris@16: } Chris@16: Chris@16: struct y_pt_transform : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_transform, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType>::type& transform(PointType& point, const TransformType& transform) { Chris@16: typedef typename point_coordinate_type::type Unit; Chris@16: Unit x_coord(x(point)); Chris@16: Unit y_coord(y(point)); Chris@16: transform.transform(x_coord, y_coord); Chris@16: x(point, x_coord); Chris@16: y(point, y_coord); Chris@16: return point; Chris@16: } Chris@16: Chris@16: struct y_pt_move : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and< Chris@16: y_pt_move, Chris@16: typename is_mutable_point_concept< Chris@16: typename geometry_concept::type Chris@16: >::type Chris@16: >::type, Chris@16: PointType>::type& move(PointType& point, orientation_2d orient, Chris@16: typename point_coordinate_type::type displacement) { Chris@16: typedef typename point_coordinate_type::type Unit; Chris@16: Unit coord = get(point, orient); Chris@16: set(point, orient, coord + displacement); Chris@16: return point; Chris@16: } Chris@16: } // polygon Chris@16: } // boost Chris@16: Chris@16: #endif // BOOST_POLYGON_POINT_CONCEPT_HPP