rectangle_concept.hpp 50 KB

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