1 // Boost.Polygon library point_concept.hpp header file
3 // Copyright (c) Intel Corporation 2008.
4 // Copyright (c) 2008-2012 Simonson Lucanus.
5 // Copyright (c) 2012-2012 Andrii Sydorchuk.
7 // See http://www.boost.org for updates, documentation, and revision history.
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
12 #ifndef BOOST_POLYGON_POINT_CONCEPT_HPP
13 #define BOOST_POLYGON_POINT_CONCEPT_HPP
15 #include "isotropy.hpp"
16 #include "point_traits.hpp"
21 struct point_concept {};
23 template <typename ConceptType>
24 struct is_point_concept {
29 struct is_point_concept<point_concept> {
33 template <typename ConceptType>
34 struct is_mutable_point_concept {
39 struct is_mutable_point_concept<point_concept> {
43 template <typename GeometryType, typename BoolType>
44 struct point_coordinate_type_by_concept {
48 template <typename GeometryType>
49 struct point_coordinate_type_by_concept<GeometryType, gtl_yes> {
50 typedef typename point_traits<GeometryType>::coordinate_type type;
53 template <typename GeometryType>
54 struct point_coordinate_type {
55 typedef typename point_coordinate_type_by_concept<
57 typename is_point_concept<
58 typename geometry_concept<GeometryType>::type
63 template <typename GeometryType, typename BoolType>
64 struct point_difference_type_by_concept {
68 template <typename GeometryType>
69 struct point_difference_type_by_concept<GeometryType, gtl_yes> {
70 typedef typename coordinate_traits<
71 typename point_traits<GeometryType>::coordinate_type
72 >::coordinate_difference type;
75 template <typename GeometryType>
76 struct point_difference_type {
77 typedef typename point_difference_type_by_concept<
79 typename is_point_concept<
80 typename geometry_concept<GeometryType>::type
85 template <typename GeometryType, typename BoolType>
86 struct point_distance_type_by_concept {
90 template <typename GeometryType>
91 struct point_distance_type_by_concept<GeometryType, gtl_yes> {
92 typedef typename coordinate_traits<
93 typename point_coordinate_type<GeometryType>::type
94 >::coordinate_distance type;
97 template <typename GeometryType>
98 struct point_distance_type {
99 typedef typename point_distance_type_by_concept<
101 typename is_point_concept<
102 typename geometry_concept<GeometryType>::type
107 struct y_pt_get : gtl_yes {};
109 template <typename PointType>
113 typename is_point_concept<
114 typename geometry_concept<PointType>::type
117 typename point_coordinate_type<PointType>::type
118 >::type get(const PointType& point, orientation_2d orient) {
119 return point_traits<PointType>::get(point, orient);
122 struct y_pt_set : gtl_yes {};
124 template <typename PointType>
128 typename is_mutable_point_concept<
129 typename geometry_concept<PointType>::type
133 >::type set(PointType& point, orientation_2d orient,
134 typename point_mutable_traits<PointType>::coordinate_type value) {
135 point_mutable_traits<PointType>::set(point, orient, value);
138 struct y_pt_construct : gtl_yes {};
140 template <typename PointType>
144 typename is_mutable_point_concept<
145 typename geometry_concept<PointType>::type
148 PointType>::type construct(
149 typename point_mutable_traits<PointType>::coordinate_type x,
150 typename point_mutable_traits<PointType>::coordinate_type y) {
151 return point_mutable_traits<PointType>::construct(x, y);
154 struct y_pt_assign : gtl_yes {};
156 template <typename PointType1, typename PointType2>
160 typename is_mutable_point_concept<
161 typename geometry_concept<PointType1>::type
163 typename is_point_concept<
164 typename geometry_concept<PointType2>::type
167 PointType1>::type& assign(PointType1& lvalue, const PointType2& rvalue) {
168 set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
169 set(lvalue, VERTICAL, get(rvalue, VERTICAL));
173 struct y_p_x : gtl_yes {};
175 template <typename PointType>
179 typename is_point_concept<
180 typename geometry_concept<PointType>::type
183 typename point_coordinate_type<PointType>::type
184 >::type x(const PointType& point) {
185 return get(point, HORIZONTAL);
188 struct y_p_y : gtl_yes {};
190 template <typename PointType>
194 typename is_point_concept<
195 typename geometry_concept<PointType>::type
198 typename point_coordinate_type<PointType>::type
199 >::type y(const PointType& point) {
200 return get(point, VERTICAL);
203 struct y_p_sx : gtl_yes {};
205 template <typename PointType>
209 typename is_mutable_point_concept<
210 typename geometry_concept<PointType>::type
213 void>::type x(PointType& point,
214 typename point_mutable_traits<PointType>::coordinate_type value) {
215 set(point, HORIZONTAL, value);
218 struct y_p_sy : gtl_yes {};
220 template <typename PointType>
224 typename is_mutable_point_concept<
225 typename geometry_concept<PointType>::type
228 void>::type y(PointType& point,
229 typename point_mutable_traits<PointType>::coordinate_type value) {
230 set(point, VERTICAL, value);
233 struct y_pt_equiv : gtl_yes {};
235 template <typename PointType1, typename PointType2>
239 typename is_point_concept<
240 typename geometry_concept<PointType1>::type
242 typename is_point_concept<
243 typename geometry_concept<PointType2>::type
246 bool>::type equivalence(
247 const PointType1& point1, const PointType2& point2) {
248 return (x(point1) == x(point2)) && (y(point1) == y(point2));
251 struct y_pt_man_dist : gtl_yes {};
253 template <typename PointType1, typename PointType2>
257 typename is_point_concept<
258 typename geometry_concept<PointType1>::type
260 typename is_point_concept<
261 typename geometry_concept<PointType2>::type
264 typename point_difference_type<PointType1>::type>::type
265 manhattan_distance(const PointType1& point1, const PointType2& point2) {
266 return euclidean_distance(point1, point2, HORIZONTAL) +
267 euclidean_distance(point1, point2, VERTICAL);
270 struct y_pt_ed1 : gtl_yes {};
272 template <typename PointType1, typename PointType2>
276 typename is_point_concept<
277 typename geometry_concept<PointType1>::type
279 typename is_point_concept<
280 typename geometry_concept<PointType2>::type
283 typename point_difference_type<PointType1>::type>::type
285 const PointType1& point1,
286 const PointType2& point2,
287 orientation_2d orient) {
288 typename point_difference_type<PointType1>::type dif =
289 get(point1, orient) - get(point2, orient);
290 return (dif < 0) ? -dif : dif;
293 struct y_pt_eds : gtl_yes {};
295 template <typename PointType1, typename PointType2>
299 typename is_point_concept<
300 typename geometry_concept<PointType1>::type
302 typename is_point_concept<
303 typename geometry_concept<PointType2>::type
306 typename point_difference_type<PointType1>::type>::type
307 distance_squared(const PointType1& point1, const PointType2& point2) {
308 typename point_difference_type<PointType1>::type dx =
309 euclidean_distance(point1, point2, HORIZONTAL);
310 typename point_difference_type<PointType1>::type dy =
311 euclidean_distance(point1, point2, VERTICAL);
317 struct y_pt_ed2 : gtl_yes {};
319 template <typename PointType1, typename PointType2>
323 typename is_point_concept<
324 typename geometry_concept<PointType1>::type
326 typename is_point_concept<
327 typename geometry_concept<PointType2>::type
330 typename point_distance_type<PointType1>::type>::type
331 euclidean_distance(const PointType1& point1, const PointType2& point2) {
333 static_cast<double>(distance_squared(point1, point2)));
336 struct y_pt_convolve : gtl_yes {};
338 template <typename PointType1, typename PointType2>
342 typename is_mutable_point_concept<
343 typename geometry_concept<PointType1>::type
345 typename is_point_concept<
346 typename geometry_concept<PointType2>::type
349 PointType1>::type& convolve(PointType1& lvalue, const PointType2& rvalue) {
350 x(lvalue, x(lvalue) + x(rvalue));
351 y(lvalue, y(lvalue) + y(rvalue));
355 struct y_pt_deconvolve : gtl_yes {};
357 template <typename PointType1, typename PointType2>
361 typename is_mutable_point_concept<
362 typename geometry_concept<PointType1>::type
364 typename is_point_concept<
365 typename geometry_concept<PointType2>::type
368 PointType1>::type& deconvolve(PointType1& lvalue, const PointType2& rvalue) {
369 x(lvalue, x(lvalue) - x(rvalue));
370 y(lvalue, y(lvalue) - y(rvalue));
374 struct y_pt_scale_up : gtl_yes {};
376 template <typename PointType, typename CType>
380 typename is_mutable_point_concept<
381 typename geometry_concept<PointType>::type
384 PointType>::type& scale_up(PointType& point, CType factor) {
385 typedef typename point_coordinate_type<PointType>::type Unit;
386 x(point, x(point) * (Unit)factor);
387 y(point, y(point) * (Unit)factor);
391 struct y_pt_scale_down : gtl_yes {};
393 template <typename PointType, typename CType>
397 typename is_mutable_point_concept<
398 typename geometry_concept<PointType>::type
401 PointType>::type& scale_down(PointType& point, CType factor) {
402 typedef typename point_coordinate_type<PointType>::type Unit;
403 typedef typename coordinate_traits<Unit>::coordinate_distance dt;
404 x(point, scaling_policy<Unit>::round((dt)(x(point)) / (dt)factor));
405 y(point, scaling_policy<Unit>::round((dt)(y(point)) / (dt)factor));
409 struct y_pt_scale : gtl_yes {};
411 template <typename PointType, typename ScaleType>
415 typename is_mutable_point_concept<
416 typename geometry_concept<PointType>::type
419 PointType>::type& scale(PointType& point, const ScaleType& scaling) {
420 typedef typename point_coordinate_type<PointType>::type Unit;
421 Unit x_coord(x(point));
422 Unit y_coord(y(point));
423 scaling.scale(x_coord, y_coord);
429 struct y_pt_transform : gtl_yes {};
431 template <typename PointType, typename TransformType>
435 typename is_mutable_point_concept<
436 typename geometry_concept<PointType>::type
439 PointType>::type& transform(PointType& point, const TransformType& transform) {
440 typedef typename point_coordinate_type<PointType>::type Unit;
441 Unit x_coord(x(point));
442 Unit y_coord(y(point));
443 transform.transform(x_coord, y_coord);
449 struct y_pt_move : gtl_yes {};
451 template <typename PointType>
455 typename is_mutable_point_concept<
456 typename geometry_concept<PointType>::type
459 PointType>::type& move(PointType& point, orientation_2d orient,
460 typename point_coordinate_type<PointType>::type displacement) {
461 typedef typename point_coordinate_type<PointType>::type Unit;
462 Unit coord = get(point, orient);
463 set(point, orient, coord + displacement);
469 #endif // BOOST_POLYGON_POINT_CONCEPT_HPP