1// Boost.Polygon library point_concept.hpp header file
2
3// Copyright (c) Intel Corporation 2008.
4// Copyright (c) 2008-2012 Simonson Lucanus.
5// Copyright (c) 2012-2012 Andrii Sydorchuk.
6
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)
11
12#ifndef BOOST_POLYGON_POINT_CONCEPT_HPP
13#define BOOST_POLYGON_POINT_CONCEPT_HPP
14
15#include "isotropy.hpp"
16#include "point_traits.hpp"
17
18namespace boost {
19namespace polygon {
20
21struct point_concept {};
22
23template <typename ConceptType>
24struct is_point_concept {
25 typedef gtl_no type;
26};
27
28template <>
29struct is_point_concept<point_concept> {
30 typedef gtl_yes type;
31};
32
33template <typename ConceptType>
34struct is_mutable_point_concept {
35 typedef gtl_no type;
36};
37
38template <>
39struct is_mutable_point_concept<point_concept> {
40 typedef gtl_yes type;
41};
42
43template <typename GeometryType, typename BoolType>
44struct point_coordinate_type_by_concept {
45 typedef void type;
46};
47
48template <typename GeometryType>
49struct point_coordinate_type_by_concept<GeometryType, gtl_yes> {
50 typedef typename point_traits<GeometryType>::coordinate_type type;
51};
52
53template <typename GeometryType>
54struct point_coordinate_type {
55 typedef typename point_coordinate_type_by_concept<
56 GeometryType,
57 typename is_point_concept<
58 typename geometry_concept<GeometryType>::type
59 >::type
60 >::type type;
61};
62
63template <typename GeometryType, typename BoolType>
64struct point_difference_type_by_concept {
65 typedef void type;
66};
67
68template <typename GeometryType>
69struct point_difference_type_by_concept<GeometryType, gtl_yes> {
70 typedef typename coordinate_traits<
71 typename point_traits<GeometryType>::coordinate_type
72 >::coordinate_difference type;
73};
74
75template <typename GeometryType>
76struct point_difference_type {
77 typedef typename point_difference_type_by_concept<
78 GeometryType,
79 typename is_point_concept<
80 typename geometry_concept<GeometryType>::type
81 >::type
82 >::type type;
83};
84
85template <typename GeometryType, typename BoolType>
86struct point_distance_type_by_concept {
87 typedef void type;
88};
89
90template <typename GeometryType>
91struct point_distance_type_by_concept<GeometryType, gtl_yes> {
92 typedef typename coordinate_traits<
93 typename point_coordinate_type<GeometryType>::type
94 >::coordinate_distance type;
95};
96
97template <typename GeometryType>
98struct point_distance_type {
99 typedef typename point_distance_type_by_concept<
100 GeometryType,
101 typename is_point_concept<
102 typename geometry_concept<GeometryType>::type
103 >::type
104 >::type type;
105};
106
107struct y_pt_get : gtl_yes {};
108
109template <typename PointType>
110typename enable_if<
111 typename gtl_and<
112 y_pt_get,
113 typename is_point_concept<
114 typename geometry_concept<PointType>::type
115 >::type
116 >::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);
120}
121
122struct y_pt_set : gtl_yes {};
123
124template <typename PointType>
125typename enable_if<
126 typename gtl_and<
127 y_pt_set,
128 typename is_mutable_point_concept<
129 typename geometry_concept<PointType>::type
130 >::type
131 >::type,
132 void
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);
136}
137
138struct y_pt_construct : gtl_yes {};
139
140template <typename PointType>
141typename enable_if<
142 typename gtl_and<
143 y_pt_construct,
144 typename is_mutable_point_concept<
145 typename geometry_concept<PointType>::type
146 >::type
147 >::type,
148PointType>::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);
152}
153
154struct y_pt_assign : gtl_yes {};
155
156template <typename PointType1, typename PointType2>
157typename enable_if<
158 typename gtl_and_3<
159 y_pt_assign,
160 typename is_mutable_point_concept<
161 typename geometry_concept<PointType1>::type
162 >::type,
163 typename is_point_concept<
164 typename geometry_concept<PointType2>::type
165 >::type
166>::type,
167PointType1>::type& assign(PointType1& lvalue, const PointType2& rvalue) {
168 set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
169 set(lvalue, VERTICAL, get(rvalue, VERTICAL));
170 return lvalue;
171}
172
173struct y_p_x : gtl_yes {};
174
175template <typename PointType>
176typename enable_if<
177 typename gtl_and<
178 y_p_x,
179 typename is_point_concept<
180 typename geometry_concept<PointType>::type
181 >::type
182 >::type,
183 typename point_coordinate_type<PointType>::type
184>::type x(const PointType& point) {
185 return get(point, HORIZONTAL);
186}
187
188struct y_p_y : gtl_yes {};
189
190template <typename PointType>
191typename enable_if<
192 typename gtl_and<
193 y_p_y,
194 typename is_point_concept<
195 typename geometry_concept<PointType>::type
196 >::type
197 >::type,
198 typename point_coordinate_type<PointType>::type
199>::type y(const PointType& point) {
200 return get(point, VERTICAL);
201}
202
203struct y_p_sx : gtl_yes {};
204
205template <typename PointType>
206typename enable_if<
207 typename gtl_and<
208 y_p_sx,
209 typename is_mutable_point_concept<
210 typename geometry_concept<PointType>::type
211 >::type
212 >::type,
213void>::type x(PointType& point,
214 typename point_mutable_traits<PointType>::coordinate_type value) {
215 set(point, HORIZONTAL, value);
216}
217
218struct y_p_sy : gtl_yes {};
219
220template <typename PointType>
221typename enable_if<
222 typename gtl_and<
223 y_p_sy,
224 typename is_mutable_point_concept<
225 typename geometry_concept<PointType>::type
226 >::type
227 >::type,
228void>::type y(PointType& point,
229 typename point_mutable_traits<PointType>::coordinate_type value) {
230 set(point, VERTICAL, value);
231}
232
233struct y_pt_equiv : gtl_yes {};
234
235template <typename PointType1, typename PointType2>
236typename enable_if<
237 typename gtl_and_3<
238 y_pt_equiv,
239 typename is_point_concept<
240 typename geometry_concept<PointType1>::type
241 >::type,
242 typename is_point_concept<
243 typename geometry_concept<PointType2>::type
244 >::type
245 >::type,
246bool>::type equivalence(
247 const PointType1& point1, const PointType2& point2) {
248 return (x(point1) == x(point2)) && (y(point1) == y(point2));
249}
250
251struct y_pt_man_dist : gtl_yes {};
252
253template <typename PointType1, typename PointType2>
254typename enable_if<
255 typename gtl_and_3<
256 y_pt_man_dist,
257 typename is_point_concept<
258 typename geometry_concept<PointType1>::type
259 >::type,
260 typename is_point_concept<
261 typename geometry_concept<PointType2>::type
262 >::type
263 >::type,
264typename point_difference_type<PointType1>::type>::type
265manhattan_distance(const PointType1& point1, const PointType2& point2) {
266 return euclidean_distance(point1, point2, HORIZONTAL) +
267 euclidean_distance(point1, point2, VERTICAL);
268}
269
270struct y_pt_ed1 : gtl_yes {};
271
272template <typename PointType1, typename PointType2>
273typename enable_if<
274 typename gtl_and_3<
275 y_pt_ed1,
276 typename is_point_concept<
277 typename geometry_concept<PointType1>::type
278 >::type,
279 typename is_point_concept<
280 typename geometry_concept<PointType2>::type
281 >::type
282 >::type,
283typename point_difference_type<PointType1>::type>::type
284euclidean_distance(
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;
291}
292
293struct y_pt_eds : gtl_yes {};
294
295template <typename PointType1, typename PointType2>
296typename enable_if<
297 typename gtl_and_3<
298 y_pt_eds,
299 typename is_point_concept<
300 typename geometry_concept<PointType1>::type
301 >::type,
302 typename is_point_concept<
303 typename geometry_concept<PointType2>::type
304 >::type
305 >::type,
306typename point_difference_type<PointType1>::type>::type
307distance_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);
312 dx *= dx;
313 dy *= dy;
314 return dx + dy;
315}
316
317struct y_pt_ed2 : gtl_yes {};
318
319template <typename PointType1, typename PointType2>
320typename enable_if<
321 typename gtl_and_3<
322 y_pt_ed2,
323 typename is_point_concept<
324 typename geometry_concept<PointType1>::type
325 >::type,
326 typename is_point_concept<
327 typename geometry_concept<PointType2>::type
328 >::type
329 >::type,
330typename point_distance_type<PointType1>::type>::type
331euclidean_distance(const PointType1& point1, const PointType2& point2) {
332 return (std::sqrt)(
333 x: static_cast<double>(distance_squared(point1, point2)));
334}
335
336struct y_pt_convolve : gtl_yes {};
337
338template <typename PointType1, typename PointType2>
339typename enable_if<
340 typename gtl_and_3<
341 y_pt_convolve,
342 typename is_mutable_point_concept<
343 typename geometry_concept<PointType1>::type
344 >::type,
345 typename is_point_concept<
346 typename geometry_concept<PointType2>::type
347 >::type
348 >::type,
349PointType1>::type& convolve(PointType1& lvalue, const PointType2& rvalue) {
350 x(lvalue, x(lvalue) + x(rvalue));
351 y(lvalue, y(lvalue) + y(rvalue));
352 return lvalue;
353}
354
355struct y_pt_deconvolve : gtl_yes {};
356
357template <typename PointType1, typename PointType2>
358typename enable_if<
359 typename gtl_and_3<
360 y_pt_deconvolve,
361 typename is_mutable_point_concept<
362 typename geometry_concept<PointType1>::type
363 >::type,
364 typename is_point_concept<
365 typename geometry_concept<PointType2>::type
366 >::type
367 >::type,
368PointType1>::type& deconvolve(PointType1& lvalue, const PointType2& rvalue) {
369 x(lvalue, x(lvalue) - x(rvalue));
370 y(lvalue, y(lvalue) - y(rvalue));
371 return lvalue;
372}
373
374struct y_pt_scale_up : gtl_yes {};
375
376template <typename PointType, typename CType>
377typename enable_if<
378 typename gtl_and<
379 y_pt_scale_up,
380 typename is_mutable_point_concept<
381 typename geometry_concept<PointType>::type
382 >::type
383 >::type,
384PointType>::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);
388 return point;
389}
390
391struct y_pt_scale_down : gtl_yes {};
392
393template <typename PointType, typename CType>
394typename enable_if<
395 typename gtl_and<
396 y_pt_scale_down,
397 typename is_mutable_point_concept<
398 typename geometry_concept<PointType>::type
399 >::type
400 >::type,
401PointType>::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));
406 return point;
407}
408
409struct y_pt_scale : gtl_yes {};
410
411template <typename PointType, typename ScaleType>
412typename enable_if<
413 typename gtl_and<
414 y_pt_scale,
415 typename is_mutable_point_concept<
416 typename geometry_concept<PointType>::type
417 >::type
418 >::type,
419PointType>::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);
424 x(point, x_coord);
425 y(point, y_coord);
426 return point;
427}
428
429struct y_pt_transform : gtl_yes {};
430
431template <typename PointType, typename TransformType>
432typename enable_if<
433 typename gtl_and<
434 y_pt_transform,
435 typename is_mutable_point_concept<
436 typename geometry_concept<PointType>::type
437 >::type
438 >::type,
439PointType>::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);
444 x(point, x_coord);
445 y(point, y_coord);
446 return point;
447}
448
449struct y_pt_move : gtl_yes {};
450
451template <typename PointType>
452typename enable_if<
453 typename gtl_and<
454 y_pt_move,
455 typename is_mutable_point_concept<
456 typename geometry_concept<PointType>::type
457 >::type
458 >::type,
459PointType>::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);
464 return point;
465}
466} // polygon
467} // boost
468
469#endif // BOOST_POLYGON_POINT_CONCEPT_HPP
470

source code of boost/boost/polygon/point_concept.hpp