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