mRect.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MRECT_H_
  23. #define _MRECT_H_
  24. //Includes
  25. #ifndef _MPOINT_H_
  26. #include "math/mPoint.h"
  27. #endif
  28. class RectI
  29. {
  30. public:
  31. Point2I point;
  32. Point2I extent;
  33. public:
  34. RectI() { }
  35. RectI(const Point2I& in_rMin,
  36. const Point2I& in_rExtent);
  37. RectI(const S32 in_left, const S32 in_top,
  38. const S32 in_width, const S32 in_height);
  39. void set(const Point2I& in_rMin, const Point2I& in_rExtent);
  40. void set(const S32 in_left, const S32 in_top,
  41. const S32 in_width, const S32 in_height);
  42. bool intersect(const RectI& clipRect);
  43. bool pointInRect(const Point2I& pt) const;
  44. S32 distanceToRect(const Point2I& pt) const;
  45. bool contains(const RectI& R) const;
  46. bool overlaps(RectI R) const;
  47. void inset(S32 x, S32 y);
  48. void unionRects(const RectI&);
  49. Point2I centre( void ) const;
  50. S32 len_x() const;
  51. S32 len_y() const;
  52. bool operator==(const RectI&) const;
  53. bool operator!=(const RectI&) const;
  54. bool isValidRect() const { return (extent.x > 0 && extent.y > 0); }
  55. };
  56. class RectF
  57. {
  58. public:
  59. Point2F point;
  60. Point2F extent;
  61. public:
  62. RectF() { }
  63. RectF(const Point2F& in_rMin,
  64. const Point2F& in_rExtent);
  65. RectF(const F32 in_left, const F32 in_top,
  66. const F32 in_width, const F32 in_height);
  67. void inset(F32 x, F32 y);
  68. bool intersect(const RectF& clipRect);
  69. bool overlaps(const RectF&) const;
  70. Point2F centre( void ) const;
  71. F32 len_x() const;
  72. F32 len_y() const;
  73. bool isValidRect() const { return (extent.x > 0 && extent.y > 0); }
  74. };
  75. class RectD
  76. {
  77. public:
  78. Point2D point;
  79. Point2D extent;
  80. public:
  81. RectD() { }
  82. RectD(const Point2D& in_rMin,
  83. const Point2D& in_rExtent);
  84. RectD(const F64 in_left, const F64 in_top,
  85. const F64 in_width, const F64 in_height);
  86. void inset(F64 x, F64 y);
  87. bool intersect(const RectD& clipRect);
  88. Point2D centre( void ) const;
  89. F64 len_x() const;
  90. F64 len_y() const;
  91. bool isValidRect() const { return (extent.x > 0 && extent.y > 0); }
  92. };
  93. //------------------------------------------------------------------------------
  94. //-------------------------------------- INLINES (RectI)
  95. //
  96. inline
  97. RectI::RectI(const Point2I& in_rMin,
  98. const Point2I& in_rExtent)
  99. : point(in_rMin),
  100. extent(in_rExtent)
  101. {
  102. //
  103. }
  104. inline
  105. RectI::RectI(const S32 in_left, const S32 in_top,
  106. const S32 in_width, const S32 in_height)
  107. : point(in_left, in_top),
  108. extent(in_width, in_height)
  109. {
  110. //
  111. }
  112. inline void RectI::set(const Point2I& in_rMin, const Point2I& in_rExtent)
  113. {
  114. point = in_rMin;
  115. extent = in_rExtent;
  116. }
  117. inline void RectI::set(const S32 in_left, const S32 in_top,
  118. const S32 in_width, const S32 in_height)
  119. {
  120. point.set(in_left, in_top);
  121. extent.set(in_width, in_height);
  122. }
  123. inline bool RectI::intersect(const RectI& clipRect)
  124. {
  125. Point2I bottomL;
  126. bottomL.x = getMin(point.x + extent.x - 1, clipRect.point.x + clipRect.extent.x - 1);
  127. bottomL.y = getMin(point.y + extent.y - 1, clipRect.point.y + clipRect.extent.y - 1);
  128. point.x = getMax(point.x, clipRect.point.x);
  129. point.y = getMax(point.y, clipRect.point.y);
  130. extent.x = bottomL.x - point.x + 1;
  131. extent.y = bottomL.y - point.y + 1;
  132. return isValidRect();
  133. }
  134. inline bool RectI::pointInRect(const Point2I &pt) const
  135. {
  136. return (pt.x >= point.x && pt.x < point.x + extent.x && pt.y >= point.y && pt.y < point.y + extent.y);
  137. }
  138. inline S32 RectI::distanceToRect(const Point2I& pt) const
  139. {
  140. if (pointInRect(pt))
  141. {
  142. return 0;
  143. }
  144. S32 x = pt.x < point.x ? point.x - pt.x : pt.x - (point.x + extent.x);
  145. S32 y = pt.y < point.y ? point.y - pt.y : pt.y - (point.y + extent.y);
  146. return getMax(x, y);
  147. }
  148. inline bool RectI::contains(const RectI& R) const
  149. {
  150. if (point.x <= R.point.x && point.y <= R.point.y)
  151. if (R.point.x + R.extent.x <= point.x + extent.x)
  152. if (R.point.y + R.extent.y <= point.y + extent.y)
  153. return true;
  154. return false;
  155. }
  156. inline bool RectI::overlaps(RectI R) const
  157. {
  158. return R.intersect (* this);
  159. }
  160. inline void RectI::inset(S32 x, S32 y)
  161. {
  162. point.x += x;
  163. point.y += y;
  164. extent.x -= 2 * x;
  165. extent.y -= 2 * y;
  166. }
  167. inline void RectF::inset(F32 x, F32 y)
  168. {
  169. point.x += x;
  170. point.y += y;
  171. extent.x -= 2 * x;
  172. extent.y -= 2 * y;
  173. }
  174. inline void RectD::inset(F64 x, F64 y)
  175. {
  176. point.x += x;
  177. point.y += y;
  178. extent.x -= 2 * x;
  179. extent.y -= 2 * y;
  180. }
  181. inline void RectI::unionRects(const RectI& u)
  182. {
  183. S32 minx = point.x < u.point.x ? point.x : u.point.x;
  184. S32 miny = point.y < u.point.y ? point.y : u.point.y;
  185. S32 maxx = (point.x + extent.x) > (u.point.x + u.extent.x) ? (point.x + extent.x) : (u.point.x + u.extent.x);
  186. S32 maxy = (point.y + extent.y) > (u.point.y + u.extent.y) ? (point.y + extent.y) : (u.point.y + u.extent.y);
  187. point.x = minx;
  188. point.y = miny;
  189. extent.x = maxx - minx;
  190. extent.y = maxy - miny;
  191. }
  192. inline Point2I RectI::centre( void ) const
  193. {
  194. return Point2I( point.x + (S32)(extent.x * 0.5f), point.y + (S32)(extent.y * 0.5f) );
  195. }
  196. inline S32
  197. RectI::len_x() const
  198. {
  199. return extent.x;
  200. }
  201. inline S32
  202. RectI::len_y() const
  203. {
  204. return extent.y;
  205. }
  206. inline bool
  207. RectI::operator==(const RectI& in_rCompare) const
  208. {
  209. return (point == in_rCompare.point) && (extent == in_rCompare.extent);
  210. }
  211. inline bool
  212. RectI::operator!=(const RectI& in_rCompare) const
  213. {
  214. return (operator==(in_rCompare) == false);
  215. }
  216. //------------------------------------------------------------------------------
  217. //-------------------------------------- INLINES (RectF)
  218. //
  219. inline
  220. RectF::RectF(const Point2F& in_rMin,
  221. const Point2F& in_rExtent)
  222. : point(in_rMin),
  223. extent(in_rExtent)
  224. {
  225. //
  226. }
  227. inline
  228. RectF::RectF(const F32 in_left, const F32 in_top,
  229. const F32 in_width, const F32 in_height)
  230. : point(in_left, in_top),
  231. extent(in_width, in_height)
  232. {
  233. //
  234. }
  235. inline Point2F RectF::centre( void ) const
  236. {
  237. return Point2F( point.x + (extent.x * 0.5f), point.y + (extent.y * 0.5f) );
  238. }
  239. inline F32
  240. RectF::len_x() const
  241. {
  242. return extent.x;
  243. }
  244. inline F32
  245. RectF::len_y() const
  246. {
  247. return extent.y;
  248. }
  249. inline bool RectF::intersect(const RectF& clipRect)
  250. {
  251. Point2F bottomL;
  252. bottomL.x = getMin(point.x + extent.x, clipRect.point.x + clipRect.extent.x);
  253. bottomL.y = getMin(point.y + extent.y, clipRect.point.y + clipRect.extent.y);
  254. point.x = getMax(point.x, clipRect.point.x);
  255. point.y = getMax(point.y, clipRect.point.y);
  256. extent.x = bottomL.x - point.x;
  257. extent.y = bottomL.y - point.y;
  258. return isValidRect();
  259. }
  260. inline bool RectF::overlaps(const RectF& clipRect) const
  261. {
  262. RectF test = *this;
  263. return test.intersect(clipRect);
  264. }
  265. //------------------------------------------------------------------------------
  266. //-------------------------------------- INLINES (RectD)
  267. //
  268. inline
  269. RectD::RectD(const Point2D& in_rMin,
  270. const Point2D& in_rExtent)
  271. : point(in_rMin),
  272. extent(in_rExtent)
  273. {
  274. //
  275. }
  276. inline
  277. RectD::RectD(const F64 in_left, const F64 in_top,
  278. const F64 in_width, const F64 in_height)
  279. : point(in_left, in_top),
  280. extent(in_width, in_height)
  281. {
  282. //
  283. }
  284. inline Point2D RectD::centre( void ) const
  285. {
  286. return Point2D( point.x + (F64)(extent.x * 0.5), point.y + (F64)(extent.y * 0.5) );
  287. }
  288. inline F64
  289. RectD::len_x() const
  290. {
  291. return extent.x;
  292. }
  293. inline F64
  294. RectD::len_y() const
  295. {
  296. return extent.y;
  297. }
  298. inline bool RectD::intersect(const RectD& clipRect)
  299. {
  300. Point2D bottomL;
  301. bottomL.x = getMin(point.x + extent.x, clipRect.point.x + clipRect.extent.x);
  302. bottomL.y = getMin(point.y + extent.y, clipRect.point.y + clipRect.extent.y);
  303. point.x = getMax(point.x, clipRect.point.x);
  304. point.y = getMax(point.y, clipRect.point.y);
  305. extent.x = bottomL.x - point.x;
  306. extent.y = bottomL.y - point.y;
  307. return isValidRect();
  308. }
  309. #endif //_RECT_H_