1/*
2 Copyright 2008 Intel Corporation
3
4 Use, modification and distribution are subject to the Boost Software License,
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7*/
8#ifndef BOOST_POLYGON_RECTANGLE_CONCEPT_HPP
9#define BOOST_POLYGON_RECTANGLE_CONCEPT_HPP
10
11#include "isotropy.hpp"
12
13//point
14#include "point_data.hpp"
15#include "point_traits.hpp"
16#include "point_concept.hpp"
17
18//interval
19#include "interval_data.hpp"
20#include "interval_traits.hpp"
21#include "interval_concept.hpp"
22
23#include "rectangle_data.hpp"
24#include "rectangle_traits.hpp"
25
26namespace boost { namespace polygon{
27 struct rectangle_concept {};
28
29 template <typename T>
30 struct is_rectangle_concept { typedef gtl_no type; };
31 template <>
32 struct is_rectangle_concept<rectangle_concept> { typedef gtl_yes type; };
33
34 template <typename T>
35 struct is_mutable_rectangle_concept { typedef gtl_no type; };
36 template <>
37 struct is_mutable_rectangle_concept<rectangle_concept> { typedef gtl_yes type; };
38
39 template <>
40 struct geometry_domain<rectangle_concept> { typedef manhattan_domain type; };
41
42 template <typename T, typename CT>
43 struct rectangle_interval_type_by_concept { typedef void type; };
44 template <typename T>
45 struct rectangle_interval_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::interval_type type; };
46
47 template <typename T>
48 struct rectangle_interval_type {
49 typedef typename rectangle_interval_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
50 };
51
52 template <typename T, typename CT>
53 struct rectangle_coordinate_type_by_concept { typedef void type; };
54 template <typename T>
55 struct rectangle_coordinate_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::coordinate_type type; };
56
57 template <typename T>
58 struct rectangle_coordinate_type {
59 typedef typename rectangle_coordinate_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
60 };
61
62 template <typename T, typename CT>
63 struct rectangle_difference_type_by_concept { typedef void type; };
64 template <typename T>
65 struct rectangle_difference_type_by_concept<T, gtl_yes> {
66 typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_difference type; };
67
68 template <typename T>
69 struct rectangle_difference_type {
70 typedef typename rectangle_difference_type_by_concept<
71 T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
72 };
73
74 template <typename T, typename CT>
75 struct rectangle_distance_type_by_concept { typedef void type; };
76 template <typename T>
77 struct rectangle_distance_type_by_concept<T, gtl_yes> {
78 typedef typename coordinate_traits<typename rectangle_coordinate_type<T>::type>::coordinate_distance type; };
79
80 template <typename T>
81 struct rectangle_distance_type {
82 typedef typename rectangle_distance_type_by_concept<
83 T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
84 };
85
86 struct y_r_get_interval : gtl_yes {};
87
88 template <typename T>
89 typename enable_if< typename gtl_and<y_r_get_interval, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
90 typename rectangle_interval_type<T>::type>::type
91 get(const T& rectangle, orientation_2d orient) {
92 return rectangle_traits<T>::get(rectangle, orient);
93 }
94
95 struct y_r_h : gtl_yes {};
96
97 template <typename T>
98 typename enable_if< typename gtl_and<y_r_h, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
99 typename rectangle_interval_type<T>::type>::type
100 horizontal(const T& rectangle) {
101 return rectangle_traits<T>::get(rectangle, HORIZONTAL);
102 }
103
104 struct y_r_v : gtl_yes {};
105
106 template <typename T>
107 typename enable_if< typename gtl_and<y_r_v, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
108 typename rectangle_interval_type<T>::type>::type
109 vertical(const T& rectangle) {
110 return rectangle_traits<T>::get(rectangle, VERTICAL);
111 }
112
113 struct y_r_set : gtl_yes {};
114
115 template <orientation_2d_enum orient, typename T, typename T2>
116 typename enable_if< typename gtl_and_3<y_r_set, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
117 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
118 void>::type
119 set(T& rectangle, const T2& interval) {
120 rectangle_mutable_traits<T>::set(rectangle, orient, interval);
121 }
122
123 struct y_r_set2 : gtl_yes {};
124
125 template <typename T, typename T2>
126 typename enable_if< typename gtl_and_3<y_r_set2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
127 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
128 void>::type
129 set(T& rectangle, orientation_2d orient, const T2& interval) {
130 rectangle_mutable_traits<T>::set(rectangle, orient, interval);
131 }
132
133 struct y_r_h2 : gtl_yes {};
134
135 template <typename T, typename T2>
136 typename enable_if< typename gtl_and_3<y_r_h2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
137 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
138 void>::type
139 horizontal(T& rectangle, const T2& interval) {
140 rectangle_mutable_traits<T>::set(rectangle, HORIZONTAL, interval);
141 }
142
143 struct y_r_v2 : gtl_yes {};
144
145 template <typename T, typename T2>
146 typename enable_if<
147 typename gtl_and_3<y_r_v2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
148 typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, void>::type
149 vertical(T& rectangle, const T2& interval) {
150 rectangle_mutable_traits<T>::set(rectangle, VERTICAL, interval);
151 }
152
153 struct y_r_construct : gtl_yes {};
154
155 template <typename T, typename T2, typename T3>
156 typename enable_if< typename gtl_and<y_r_construct, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
157 T>::type
158 construct(const T2& interval_horizontal,
159 const T3& interval_vertical) {
160 return rectangle_mutable_traits<T>::construct(interval_horizontal, interval_vertical); }
161
162 struct y_r_construct2 : gtl_yes {};
163
164 template <typename T, typename coord_type>
165 typename enable_if< typename gtl_and<y_r_construct2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
166 T>::type
167 construct(coord_type xl, coord_type yl, coord_type xh, coord_type yh) {
168 return rectangle_mutable_traits<T>::construct(interval_data<coord_type>(xl, xh),
169 interval_data<coord_type>(yl, yh));
170 }
171
172 struct y_r_cconstruct : gtl_yes {};
173
174 template <typename T, typename T2>
175 typename enable_if<
176 typename gtl_and_3<y_r_cconstruct,
177 typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
178 typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type,
179 T>::type
180 copy_construct(const T2& rectangle) {
181 return construct<T> (get(rectangle, HORIZONTAL), get(rectangle, VERTICAL));
182 }
183
184 struct y_r_assign : gtl_yes {};
185
186 template <typename rectangle_type_1, typename rectangle_type_2>
187 typename enable_if<
188 typename gtl_and_3< y_r_assign,
189 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
190 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
191 rectangle_type_1>::type &
192 assign(rectangle_type_1& lvalue, const rectangle_type_2& rvalue) {
193 set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
194 set(lvalue, VERTICAL, get(rvalue, VERTICAL));
195 return lvalue;
196 }
197
198 struct y_r_equiv : gtl_yes {};
199
200 template <typename T, typename T2>
201 typename enable_if<
202 typename gtl_and_3< y_r_equiv,
203 typename is_rectangle_concept<typename geometry_concept<T>::type>::type,
204 typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type,
205 bool>::type
206 equivalence(const T& rect1, const T2& rect2) {
207 return equivalence(get(rect1, HORIZONTAL), get(rect2, HORIZONTAL)) &&
208 equivalence(get(rect1, VERTICAL), get(rect2, VERTICAL));
209 }
210
211 struct y_r_get : gtl_yes {};
212
213 template <typename rectangle_type>
214 typename enable_if< typename gtl_and<y_r_get, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
215 typename rectangle_coordinate_type<rectangle_type>::type>::type
216 get(const rectangle_type& rectangle, orientation_2d orient, direction_1d dir) {
217 return get(rectangle_traits<rectangle_type>::get(rectangle, orient), dir);
218 }
219
220 struct y_r_set3 : gtl_yes {};
221
222 template <typename rectangle_type>
223 typename enable_if<typename gtl_and<y_r_set3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
224 set(rectangle_type& rectangle, orientation_2d orient, direction_1d dir,
225 typename rectangle_coordinate_type<rectangle_type>::type value) {
226 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
227 set(ivl, dir, value);
228 set(rectangle, orient, ivl);
229 }
230
231 struct y_r_xl : gtl_yes {};
232
233 template <typename rectangle_type>
234 typename enable_if< typename gtl_and<y_r_xl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
235 typename rectangle_coordinate_type<rectangle_type>::type>::type
236 xl(const rectangle_type& rectangle) {
237 return get(rectangle, HORIZONTAL, LOW);
238 }
239
240 struct y_r_xl2 : gtl_yes {};
241
242 template <typename rectangle_type>
243 typename enable_if<typename gtl_and<y_r_xl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
244 xl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
245 return set(rectangle, HORIZONTAL, LOW, value);
246 }
247
248 struct y_r_xh : gtl_yes {};
249
250 template <typename rectangle_type>
251 typename enable_if< typename gtl_and<y_r_xh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
252 typename rectangle_coordinate_type<rectangle_type>::type>::type
253 xh(const rectangle_type& rectangle) {
254 return get(rectangle, HORIZONTAL, HIGH);
255 }
256
257 struct y_r_xh2 : gtl_yes {};
258
259 template <typename rectangle_type>
260 typename enable_if<typename gtl_and<y_r_xh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
261 xh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
262 return set(rectangle, HORIZONTAL, HIGH, value);
263 }
264
265 struct y_r_yl : gtl_yes {};
266
267 template <typename rectangle_type>
268 typename enable_if< typename gtl_and<y_r_yl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
269 typename rectangle_coordinate_type<rectangle_type>::type>::type
270 yl(const rectangle_type& rectangle) {
271 return get(rectangle, VERTICAL, LOW);
272 }
273
274 struct y_r_yl2 : gtl_yes {};
275
276 template <typename rectangle_type>
277 typename enable_if<typename gtl_and<y_r_yl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
278 yl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
279 return set(rectangle, VERTICAL, LOW, value);
280 }
281
282 struct y_r_yh : gtl_yes {};
283
284 template <typename rectangle_type>
285 typename enable_if< typename gtl_and<y_r_yh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
286 typename rectangle_coordinate_type<rectangle_type>::type>::type
287 yh(const rectangle_type& rectangle) {
288 return get(rectangle, VERTICAL, HIGH);
289 }
290
291 struct y_r_yh2 : gtl_yes {};
292
293 template <typename rectangle_type>
294 typename enable_if<typename gtl_and<y_r_yh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
295 yh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
296 return set(rectangle, VERTICAL, HIGH, value);
297 }
298
299 struct y_r_ll : gtl_yes {};
300
301 template <typename rectangle_type>
302 typename enable_if<typename gtl_and<y_r_ll, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
303 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
304 ll(const rectangle_type& rectangle) {
305 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yl(rectangle));
306 }
307
308 struct y_r_lr : gtl_yes {};
309
310 template <typename rectangle_type>
311 typename enable_if<typename gtl_and<y_r_lr, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
312 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
313 lr(const rectangle_type& rectangle) {
314 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yl(rectangle));
315 }
316
317 struct y_r_ul : gtl_yes {};
318
319 template <typename rectangle_type>
320 typename enable_if<typename gtl_and<y_r_ul, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
321 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
322 ul(const rectangle_type& rectangle) {
323 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yh(rectangle));
324 }
325
326 struct y_r_ur : gtl_yes {};
327
328 template <typename rectangle_type>
329 typename enable_if<typename gtl_and<y_r_ur, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
330 point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
331 ur(const rectangle_type& rectangle) {
332 return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yh(rectangle));
333 }
334
335 struct y_r_contains : gtl_yes {};
336
337 template <typename rectangle_type, typename rectangle_type_2>
338 typename enable_if< typename gtl_and_3<y_r_contains, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
339 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
340 bool>::type
341 contains(const rectangle_type& rectangle, const rectangle_type_2 rectangle_contained,
342 bool consider_touch = true) {
343 return contains(horizontal(rectangle), horizontal(rectangle_contained), consider_touch) &&
344 contains(vertical(rectangle), vertical(rectangle_contained), consider_touch);
345 }
346
347 struct y_r_contains2 : gtl_yes {};
348
349 template <typename rectangle_type, typename point_type>
350 typename enable_if< typename gtl_and_3<y_r_contains2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
351 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type
352 contains(const rectangle_type& rectangle, const point_type point_contained,
353 bool consider_touch = true) {
354 return contains(horizontal(rectangle), x(point_contained), consider_touch) &&
355 contains(vertical(rectangle), y(point_contained), consider_touch);
356 }
357
358 struct y_r_set_points : gtl_yes {};
359
360 // set all four coordinates based upon two points
361 template <typename rectangle_type, typename point_type_1, typename point_type_2>
362 typename enable_if< typename gtl_and_4< y_r_set_points,
363 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
364 typename is_point_concept<typename geometry_concept<point_type_1>::type>::type,
365 typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
366 rectangle_type>::type &
367 set_points(rectangle_type& rectangle, const point_type_1& p1,
368 const point_type_2& p2) {
369 typedef typename rectangle_coordinate_type<rectangle_type>::type Unit;
370 Unit x1(x(p1));
371 Unit x2(x(p2));
372 Unit y1(y(p1));
373 Unit y2(y(p2));
374 horizontal(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(x1, x2));
375 vertical(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(y1, y2));
376 return rectangle;
377 }
378
379 struct y_r_move : gtl_yes {};
380
381 // move rectangle by delta in orient
382 template <typename rectangle_type>
383 typename enable_if< typename gtl_and<y_r_move, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
384 rectangle_type>::type &
385 move(rectangle_type& rectangle, orientation_2d orient,
386 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference delta) {
387 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
388 move(ivl, delta);
389 set(rectangle, orient, ivl);
390 return rectangle;
391 }
392
393 struct y_r_convolve : gtl_yes {};
394
395 // convolve this with b
396 template <typename rectangle_type_1, typename rectangle_type_2>
397 typename enable_if<
398 typename gtl_and_3< y_r_convolve,
399 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
400 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
401 rectangle_type_1>::type &
402 convolve(rectangle_type_1& rectangle,
403 const rectangle_type_2& convolution_rectangle) {
404 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
405 horizontal(rectangle, convolve(ivl, horizontal(convolution_rectangle)));
406 ivl = vertical(rectangle);
407 vertical(rectangle, convolve(ivl, vertical(convolution_rectangle)));
408 return rectangle;
409 }
410
411 struct y_r_deconvolve : gtl_yes {};
412
413 // deconvolve this with b
414 template <typename rectangle_type_1, typename rectangle_type_2>
415 typename enable_if< typename gtl_and_3< y_r_deconvolve,
416 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
417 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
418 rectangle_type_1>::type &
419 deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
420 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
421 horizontal(rectangle, deconvolve(ivl, horizontal(convolution_rectangle)));
422 ivl = vertical(rectangle);
423 vertical(rectangle, deconvolve(ivl, vertical(convolution_rectangle)));
424 return rectangle;
425 }
426
427 struct y_r_reconvolve : gtl_yes {};
428
429 // reflectedConvolve this with b
430 template <typename rectangle_type_1, typename rectangle_type_2>
431 typename enable_if<
432 typename gtl_and_3<y_r_reconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
433 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
434 rectangle_type_1>::type &
435 reflected_convolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
436 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
437 horizontal(rectangle, reflected_convolve(ivl, horizontal(convolution_rectangle)));
438 ivl = vertical(rectangle);
439 vertical(rectangle, reflected_convolve(ivl, vertical(convolution_rectangle)));
440 return rectangle;
441 }
442
443 struct y_r_redeconvolve : gtl_yes {};
444
445 // reflectedDeconvolve this with b
446 // deconvolve this with b
447 template <typename rectangle_type_1, typename rectangle_type_2>
448 typename enable_if<
449 typename gtl_and_3<y_r_redeconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
450 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
451 rectangle_type_1>::type &
452 reflected_deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
453 typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
454 horizontal(rectangle, reflected_deconvolve(ivl, horizontal(convolution_rectangle)));
455 ivl = vertical(rectangle);
456 vertical(rectangle, reflected_deconvolve(ivl, vertical(convolution_rectangle)));
457 return rectangle;
458 }
459
460 struct y_r_convolve2 : gtl_yes {};
461
462 // convolve with point
463 template <typename rectangle_type, typename point_type>
464 typename enable_if< typename gtl_and_3<y_r_convolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
465 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
466 rectangle_type>::type &
467 convolve(rectangle_type& rectangle, const point_type& convolution_point) {
468 typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle);
469 horizontal(rectangle, convolve(ivl, x(convolution_point)));
470 ivl = vertical(rectangle);
471 vertical(rectangle, convolve(ivl, y(convolution_point)));
472 return rectangle;
473 }
474
475 struct y_r_deconvolve2 : gtl_yes {};
476
477 // deconvolve with point
478 template <typename rectangle_type, typename point_type>
479 typename enable_if<
480 typename gtl_and_3<y_r_deconvolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
481 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type &
482 deconvolve(rectangle_type& rectangle, const point_type& convolution_point) {
483 typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle);
484 horizontal(rectangle, deconvolve(ivl, x(convolution_point)));
485 ivl = vertical(rectangle);
486 vertical(rectangle, deconvolve(ivl, y(convolution_point)));
487 return rectangle;
488 }
489
490 struct y_r_delta : gtl_yes {};
491
492 // get the magnitude of the interval range depending on orient
493 template <typename rectangle_type>
494 typename enable_if< typename gtl_and<y_r_delta, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
495 typename rectangle_difference_type<rectangle_type>::type>::type
496 delta(const rectangle_type& rectangle, orientation_2d orient) {
497 return delta(get(rectangle, orient));
498 }
499
500 struct y_r_area : gtl_yes {};
501
502 // get the area of the rectangle
503 template <typename rectangle_type>
504 typename enable_if< typename gtl_and<y_r_area, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
505 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type>::type
506 area(const rectangle_type& rectangle) {
507 typedef typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type area_type;
508 return (area_type)delta(rectangle, HORIZONTAL) * (area_type)delta(rectangle, VERTICAL);
509 }
510
511 struct y_r_go : gtl_yes {};
512
513 // returns the orientation of the longest side
514 template <typename rectangle_type>
515 typename enable_if<typename gtl_and<y_r_go, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
516 orientation_2d>::type
517 guess_orientation(const rectangle_type& rectangle) {
518 return delta(rectangle, HORIZONTAL) >= delta(rectangle, VERTICAL) ?
519 HORIZONTAL : VERTICAL;
520 }
521
522 struct y_r_half_p : gtl_yes {};
523
524 // get the half perimeter of the rectangle
525 template <typename rectangle_type>
526 typename enable_if< typename gtl_and<y_r_half_p, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
527 typename rectangle_difference_type<rectangle_type>::type>::type
528 half_perimeter(const rectangle_type& rectangle) {
529 return delta(rectangle, HORIZONTAL) + delta(rectangle, VERTICAL);
530 }
531
532 struct y_r_perimeter : gtl_yes {};
533
534 // get the perimeter of the rectangle
535 template <typename rectangle_type>
536 typename enable_if< typename gtl_and<y_r_perimeter, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
537 typename rectangle_difference_type<rectangle_type>::type>::type
538 perimeter(const rectangle_type& rectangle) {
539 return 2 * half_perimeter(rectangle);
540 }
541
542 struct y_r_intersects : gtl_yes {};
543
544 // check if Rectangle b intersects `this` Rectangle
545 // [in] b Rectangle that will be checked
546 // [in] considerTouch If true, return true even if b touches the boundary
547 // [ret] . true if `t` intersects b
548 template <typename rectangle_type_1, typename rectangle_type_2>
549 typename enable_if<
550 typename gtl_and_3<y_r_intersects, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
551 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
552 bool>::type
553 intersects(const rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) {
554 return intersects(horizontal(rectangle), horizontal(b), consider_touch) &&
555 intersects(vertical(rectangle), vertical(b), consider_touch);
556 }
557
558 struct y_r_b_intersect : gtl_yes {};
559
560 // Check if boundaries of Rectangle b and `this` Rectangle intersect
561 // [in] b Rectangle that will be checked
562 // [in] considerTouch If true, return true even if p is on the foundary
563 // [ret] . true if `t` contains p
564 template <typename rectangle_type_1, typename rectangle_type_2>
565 typename enable_if<
566 typename gtl_and_3<y_r_b_intersect, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
567 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
568 bool>::type
569 boundaries_intersect(const rectangle_type_1& rectangle, const rectangle_type_2& b,
570 bool consider_touch = true) {
571 return (intersects(rectangle, b, consider_touch) &&
572 !(contains(rectangle, b, !consider_touch)) &&
573 !(contains(b, rectangle, !consider_touch)));
574 }
575
576 struct y_r_b_abuts : gtl_yes {};
577
578 // check if b is touching 'this' on the end specified by dir
579 template <typename rectangle_type_1, typename rectangle_type_2>
580 typename enable_if< typename gtl_and_3<y_r_b_abuts, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
581 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
582 bool>::type
583 abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b,
584 direction_2d dir) {
585 return
586 abuts(get(rectangle, orientation_2d(dir)),
587 get(b, orientation_2d(dir)),
588 direction_1d(dir)) &&
589 intersects(get(rectangle, orientation_2d(dir).get_perpendicular()),
590 get(b, orientation_2d(dir).get_perpendicular()), true);
591 }
592
593 struct y_r_b_abuts2 : gtl_yes {};
594
595 // check if they are touching in the given orientation
596 template <typename rectangle_type_1, typename rectangle_type_2>
597 typename enable_if< typename gtl_and_3<y_r_b_abuts2, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
598 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
599 bool>::type
600 abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b,
601 orientation_2d orient) {
602 return
603 abuts(get(rectangle, orient), get(b, orient)) &&
604 intersects(get(rectangle, orient.get_perpendicular()),
605 get(b, orient.get_perpendicular()), true);
606 }
607
608 struct y_r_b_abuts3 : gtl_yes {};
609
610 // check if they are touching but not overlapping
611 template <typename rectangle_type_1, typename rectangle_type_2>
612 typename enable_if< typename gtl_and_3<y_r_b_abuts3, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
613 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
614 bool>::type
615 abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b) {
616 return abuts(rectangle, b, HORIZONTAL) || abuts(rectangle, b, VERTICAL);
617 }
618
619 struct y_r_b_intersect2 : gtl_yes {};
620
621 // intersect rectangle with interval on orient
622 template <typename rectangle_type, typename interval_type>
623 typename enable_if<
624 typename gtl_and_3<y_r_b_intersect2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
625 typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
626 bool>::type
627 intersect(rectangle_type& rectangle, const interval_type& b,
628 orientation_2d orient, bool consider_touch = true) {
629 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
630 if(intersect(ivl, b, consider_touch)) {
631 set(rectangle, orient, ivl);
632 return true;
633 }
634 return false;
635 }
636
637 struct y_r_b_intersect3 : gtl_yes {};
638
639 // clip rectangle to b
640 template <typename rectangle_type_1, typename rectangle_type_2>
641 typename enable_if< typename gtl_and_3<y_r_b_intersect3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
642 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
643 bool>::type
644 intersect(rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) {
645 if(intersects(rectangle, b)) {
646 intersect(rectangle, horizontal(b), HORIZONTAL, consider_touch);
647 intersect(rectangle, vertical(b), VERTICAL, consider_touch);
648 return true;
649 }
650 return false;
651 }
652
653 struct y_r_g_intersect : gtl_yes {};
654
655 // Sets this to the generalized intersection of this and the given rectangle
656 template <typename rectangle_type_1, typename rectangle_type_2>
657 typename enable_if< typename gtl_and_3<y_r_g_intersect,
658 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
659 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
660 rectangle_type_1>::type &
661 generalized_intersect(rectangle_type_1& rectangle, const rectangle_type_2& b) {
662 typename rectangle_interval_type<rectangle_type_1>::type ivl = get(rectangle, HORIZONTAL);
663 generalized_intersect(ivl, horizontal(b));
664 horizontal(rectangle, ivl);
665 ivl = vertical(rectangle);
666 generalized_intersect(ivl, vertical(b));
667 vertical(rectangle, ivl);
668 return rectangle;
669 }
670
671 struct y_r_bloat : gtl_yes {};
672
673 // bloat the interval specified by orient by bloating
674 template <typename rectangle_type>
675 typename enable_if<typename gtl_and<y_r_bloat, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
676 rectangle_type>::type &
677 bloat(rectangle_type& rectangle, orientation_2d orient,
678 typename rectangle_coordinate_type<rectangle_type>::type bloating) {
679 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
680 bloat(ivl, bloating);
681 set(rectangle, orient, ivl);
682 return rectangle;
683 }
684
685 struct y_r_bloat2 : gtl_yes {};
686
687 // bloat the Rectangle by bloating
688 template <typename rectangle_type>
689 typename enable_if<typename gtl_and<y_r_bloat2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
690 rectangle_type>::type &
691 bloat(rectangle_type& rectangle,
692 typename rectangle_coordinate_type<rectangle_type>::type bloating) {
693 bloat(rectangle, HORIZONTAL, bloating);
694 return bloat(rectangle, VERTICAL, bloating);
695 }
696
697 struct y_r_bloat3 : gtl_yes {};
698
699 // bloat the interval cooresponding to orient by bloating in dir direction
700 template <typename rectangle_type>
701 typename enable_if<typename gtl_and<y_r_bloat3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
702 rectangle_type>::type &
703 bloat(rectangle_type& rectangle, direction_2d dir,
704 typename rectangle_coordinate_type<rectangle_type>::type bloating) {
705 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orientation_2d(dir));
706 bloat(ivl, direction_1d(dir), bloating);
707 set(rectangle, orientation_2d(dir), ivl);
708 return rectangle;
709 }
710
711 struct y_r_shrink : gtl_yes {};
712
713 // shrink the interval specified by orient by bloating
714 template <typename rectangle_type>
715 typename enable_if<typename gtl_and<y_r_shrink, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
716 rectangle_type>::type &
717 shrink(rectangle_type& rectangle, orientation_2d orient,
718 typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
719 return bloat(rectangle, orient, -shrinking);
720 }
721
722 struct y_r_shrink2 : gtl_yes {};
723
724 // shrink the Rectangle by bloating
725 template <typename rectangle_type>
726 typename enable_if<typename gtl_and<y_r_shrink2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
727 rectangle_type>::type &
728 shrink(rectangle_type& rectangle,
729 typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
730 return bloat(rectangle, -shrinking);
731 }
732
733 struct y_r_shrink3 : gtl_yes {};
734
735 // shrink the interval cooresponding to orient by bloating in dir direction
736 template <typename rectangle_type>
737 typename enable_if<typename gtl_and<y_r_shrink3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
738 rectangle_type>::type &
739 shrink(rectangle_type& rectangle, direction_2d dir,
740 typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
741 return bloat(rectangle, dir, -shrinking);
742 }
743
744 struct y_r_encompass : gtl_yes {};
745
746 // encompass interval on orient
747 template <typename rectangle_type, typename interval_type>
748 typename enable_if<typename gtl_and_3<
749 y_r_encompass,
750 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
751 typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
752 bool>::type
753 encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) {
754 typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
755 if(encompass(ivl, b)) {
756 set(rectangle, orient, ivl);
757 return true;
758 }
759 return false;
760 }
761
762 struct y_r_encompass2 : gtl_yes {};
763
764 // enlarge rectangle to encompass the Rectangle b
765 template <typename rectangle_type_1, typename rectangle_type_2>
766 typename enable_if< typename gtl_and_3<
767 y_r_encompass2,
768 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
769 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type,
770 bool>::type
771 encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) {
772 //note that operator | is intentional because both should be called regardless
773 return encompass(rectangle, horizontal(b), HORIZONTAL) |
774 encompass(rectangle, vertical(b), VERTICAL);
775 }
776
777 struct y_r_encompass3 : gtl_yes {};
778
779 // enlarge rectangle to encompass the point b
780 template <typename rectangle_type_1, typename point_type>
781 typename enable_if<typename gtl_and_3<
782 y_r_encompass3,
783 typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
784 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
785 bool>::type
786 encompass(rectangle_type_1& rectangle, const point_type& b) {
787 typename rectangle_interval_type<rectangle_type_1>::type hivl, vivl;
788 hivl = horizontal(rectangle);
789 vivl = vertical(rectangle);
790 //note that operator | is intentional because both should be called regardless
791 bool retval = encompass(hivl, x(b)) | encompass(vivl, y(b));
792 if(retval) {
793 horizontal(rectangle, hivl);
794 vertical(rectangle, vivl);
795 }
796 return retval;
797 }
798
799 struct y_r_center : gtl_yes {};
800
801 // returns the center of the rectangle
802 template <typename point_type, typename rectangle_type>
803 typename enable_if<
804 typename gtl_and_3<y_r_center, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type,
805 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
806 bool>::type
807 center(point_type& center_point, const rectangle_type& rectangle) {
808 center_point = construct<point_type>(center(horizontal(rectangle)),
809 center(vertical(rectangle)));
810 return true;
811 }
812
813 struct y_r_get_corner : gtl_yes {};
814
815 template <typename point_type, typename rectangle_type>
816 typename enable_if<
817 typename gtl_and_3<y_r_get_corner, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type,
818 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
819 bool>::type
820 get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) {
821 typedef typename rectangle_coordinate_type<rectangle_type>::type Unit;
822 Unit u1 = get(rectangle, direction_facing);
823 Unit u2 = get(rectangle, direction_facing.turn(t: direction_turning));
824 if(orientation_2d(direction_facing).to_int()) std::swap(u1, u2);
825 corner_point = construct<point_type>(u1, u2);
826 return true;
827 }
828
829 struct y_r_get_half : gtl_yes {};
830
831 template <typename rectangle_type>
832 typename enable_if<typename gtl_and<y_r_get_half, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
833 rectangle_type>::type
834 get_half(const rectangle_type& rectangle, direction_2d dir) {
835 rectangle_type retval(rectangle);
836 set(retval, orientation_2d(dir), get_half(get(rectangle, orientation_2d(dir)), direction_1d(dir)));
837 return retval;
838 }
839
840 struct y_r_join_with : gtl_yes {};
841
842 template <typename rectangle_type_1, typename rectangle_type_2>
843 typename enable_if< typename gtl_and_3<y_r_join_with, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
844 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
845 bool>::type
846 join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) {
847 typedef typename rectangle_interval_type<rectangle_type_1>::type Interval1;
848 typedef typename rectangle_interval_type<rectangle_type_2>::type Interval2;
849 Interval1 hi1 = get(rectangle, HORIZONTAL);
850 Interval1 vi1 = get(rectangle, VERTICAL);
851 Interval2 hi2 = get(b, HORIZONTAL), vi2 = get(b, VERTICAL);
852 Interval1 temp;
853 if (equivalence(hi1, hi2) && join_with(vi1, vi2)) {
854 vertical(rectangle, vi1);
855 return true;
856 }
857 if (equivalence(vi1, vi2) && join_with(hi1, hi2)) {
858 horizontal(rectangle, hi1);
859 return true;
860 }
861 return false;
862 }
863
864 struct y_r_eda2 : gtl_yes {};
865
866 template <typename rectangle_type, typename point_type>
867 typename enable_if< typename gtl_and_3<y_r_eda2,
868 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
869 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
870 typename rectangle_difference_type<rectangle_type>::type>::type
871 euclidean_distance(const rectangle_type& lvalue, const point_type& rvalue, orientation_2d orient) {
872 return euclidean_distance(get(lvalue, orient), get(rvalue, orient));
873 }
874
875 struct y_r_eda : gtl_yes {};
876
877 template <typename rectangle_type, typename rectangle_type_2>
878 typename enable_if<
879 typename gtl_and_3<y_r_eda,
880 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
881 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
882 typename rectangle_difference_type<rectangle_type>::type>::type
883 euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue, orientation_2d orient) {
884 return euclidean_distance(get(lvalue, orient), get(rvalue, orient));
885 }
886
887 struct y_r_sed : gtl_yes {};
888
889 template <typename rectangle_type, typename point_type>
890 typename enable_if< typename gtl_and_3<y_r_sed,
891 typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
892 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
893 typename rectangle_difference_type<rectangle_type>::type>::type
894 square_euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) {
895 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
896 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
897 ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
898 return (xdist * xdist) + (ydist * ydist);
899 }
900
901 struct y_r_sed2 : gtl_yes {};
902
903 template <typename rectangle_type, typename rectangle_type_2>
904 typename enable_if<
905 typename gtl_and_3<y_r_sed2, typename is_rectangle_concept< typename geometry_concept<rectangle_type>::type>::type,
906 typename is_rectangle_concept< typename geometry_concept<rectangle_type_2>::type>::type>::type,
907 typename rectangle_difference_type<rectangle_type>::type>::type
908 square_euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
909 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
910 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
911 ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
912 return (xdist * xdist) + (ydist * ydist);
913 }
914
915 struct y_r_edist : gtl_yes {};
916
917 template <typename rectangle_type, typename point_type>
918 typename enable_if< typename gtl_and_3<y_r_edist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
919 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
920 typename rectangle_distance_type<rectangle_type>::type>::type
921 euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) {
922 return std::sqrt(x: (double)(square_euclidean_distance(lvalue, rvalue)));
923 }
924
925 struct y_r_edist2 : gtl_yes {};
926
927 template <typename rectangle_type, typename rectangle_type_2>
928 typename enable_if< typename gtl_and_3<y_r_edist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
929 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
930 typename rectangle_distance_type<rectangle_type>::type>::type
931 euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
932 double val = (int)square_euclidean_distance(lvalue, rvalue);
933 return std::sqrt(x: val);
934 }
935
936 struct y_r_mdist : gtl_yes {};
937
938 template <typename rectangle_type, typename point_type>
939 typename enable_if<
940 typename gtl_and_3<y_r_mdist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
941 typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
942 typename rectangle_difference_type<rectangle_type>::type>::type
943 manhattan_distance(rectangle_type& lvalue, const point_type& rvalue) {
944 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
945 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
946 ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
947 return xdist + ydist;
948 }
949
950 struct y_r_mdist2 : gtl_yes {};
951
952 template <typename rectangle_type, typename rectangle_type_2>
953 typename enable_if<
954 typename gtl_and_3<y_r_mdist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
955 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
956 typename rectangle_difference_type<rectangle_type>::type>::type
957 manhattan_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
958 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
959 xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
960 ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
961 return xdist + ydist;
962 }
963
964 struct y_r_scale_up : gtl_yes {};
965
966 template <typename rectangle_type>
967 typename enable_if<typename gtl_and<y_r_scale_up, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
968 rectangle_type>::type &
969 scale_up(rectangle_type& rectangle,
970 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) {
971 typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle);
972 horizontal(rectangle, scale_up(h, factor));
973 typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle);
974 vertical(rectangle, scale_up(v, factor));
975 return rectangle;
976 }
977
978 struct y_r_scale_down : gtl_yes {};
979
980 template <typename rectangle_type>
981 typename enable_if<typename gtl_and<y_r_scale_down, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
982 rectangle_type>::type &
983 scale_down(rectangle_type& rectangle,
984 typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) {
985 typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle);
986 horizontal(rectangle, scale_down(h, factor));
987 typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle);
988 vertical(rectangle, scale_down(v, factor));
989 return rectangle;
990 }
991
992 struct y_r_scale : gtl_yes {};
993
994 template <typename rectangle_type, typename scaling_type>
995 typename enable_if<typename gtl_and<y_r_scale, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
996 rectangle_type>::type &
997 scale(rectangle_type& rectangle, const scaling_type& scaling) {
998 point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle));
999 point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xl(rectangle), yl(rectangle));
1000 scale(llp, scaling);
1001 scale(urp, scaling);
1002 set_points(rectangle, llp, urp);
1003 return rectangle;
1004 }
1005
1006 struct y_r_transform : gtl_yes {};
1007
1008 template <typename rectangle_type, typename transformation_type>
1009 typename enable_if<typename gtl_and<y_r_transform, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
1010 rectangle_type>::type &
1011 transform(rectangle_type& rectangle, const transformation_type& transformation) {
1012 point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle));
1013 point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xh(rectangle), yh(rectangle));
1014 transform(llp, transformation);
1015 transform(urp, transformation);
1016 set_points(rectangle, llp, urp);
1017 return rectangle;
1018 }
1019
1020 template <typename rectangle_type_1, typename rectangle_type_2>
1021 class less_rectangle_concept {
1022 private:
1023 orientation_2d orient_;
1024 public:
1025 inline less_rectangle_concept(orientation_2d orient = VERTICAL) : orient_(orient) {}
1026 typename enable_if<
1027 typename gtl_and< typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
1028 typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
1029 bool>::type
1030 operator () (const rectangle_type_1& a,
1031 const rectangle_type_2& b) const {
1032 typedef typename rectangle_coordinate_type<rectangle_type_1>::type Unit;
1033 Unit vl1 = get(get(a, orient_), LOW);
1034 Unit vl2 = get(get(b, orient_), LOW);
1035 if(vl1 > vl2) return false;
1036 if(vl1 == vl2) {
1037 orientation_2d perp = orient_.get_perpendicular();
1038 Unit hl1 = get(get(a, perp), LOW);
1039 Unit hl2 = get(get(b, perp), LOW);
1040 if(hl1 > hl2) return false;
1041 if(hl1 == hl2) {
1042 Unit vh1 = get(get(a, orient_), HIGH);
1043 Unit vh2 = get(get(b, orient_), HIGH);
1044 if(vh1 > vh2) return false;
1045 if(vh1 == vh2) {
1046 Unit hh1 = get(get(a, perp), HIGH);
1047 Unit hh2 = get(get(b, perp), HIGH);
1048 return hh1 < hh2;
1049 }
1050 }
1051 }
1052 return true;
1053 }
1054
1055 };
1056
1057 template <typename T>
1058 template <typename interval_type_1>
1059 inline void rectangle_data<T>::set(orientation_2d orient, const interval_type_1& interval) {
1060 assign(ranges_[orient.to_int()], interval);
1061 }
1062
1063 template <class T>
1064 template <class T2>
1065 rectangle_data<T>& rectangle_data<T>::operator=(const T2& rvalue) {
1066 assign(*this, rvalue);
1067 return *this;
1068 }
1069
1070 template <class T>
1071 template <class T2>
1072 bool rectangle_data<T>::operator==(const T2& rvalue) const {
1073 return equivalence(*this, rvalue);
1074 }
1075
1076 template <typename T>
1077 struct geometry_concept<rectangle_data<T> > {
1078 typedef rectangle_concept type;
1079 };
1080}
1081}
1082#endif
1083

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