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 | |
26 | namespace 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 | |