]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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(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((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(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 |