Rect2.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using System;
  2. using System.Runtime.InteropServices;
  3. #if REAL_T_IS_DOUBLE
  4. using real_t = System.Double;
  5. #else
  6. using real_t = System.Single;
  7. #endif
  8. namespace Godot
  9. {
  10. [StructLayout(LayoutKind.Sequential)]
  11. public struct Rect2 : IEquatable<Rect2>
  12. {
  13. private Vector2 _position;
  14. private Vector2 _size;
  15. public Vector2 Position
  16. {
  17. get { return _position; }
  18. set { _position = value; }
  19. }
  20. public Vector2 Size
  21. {
  22. get { return _size; }
  23. set { _size = value; }
  24. }
  25. public Vector2 End
  26. {
  27. get { return _position + _size; }
  28. set { _size = value - _position; }
  29. }
  30. public real_t Area
  31. {
  32. get { return GetArea(); }
  33. }
  34. public Rect2 Abs()
  35. {
  36. Vector2 end = End;
  37. Vector2 topLeft = new Vector2(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y));
  38. return new Rect2(topLeft, _size.Abs());
  39. }
  40. public Rect2 Clip(Rect2 b)
  41. {
  42. var newRect = b;
  43. if (!Intersects(newRect))
  44. return new Rect2();
  45. newRect._position.x = Mathf.Max(b._position.x, _position.x);
  46. newRect._position.y = Mathf.Max(b._position.y, _position.y);
  47. Vector2 bEnd = b._position + b._size;
  48. Vector2 end = _position + _size;
  49. newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x;
  50. newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y;
  51. return newRect;
  52. }
  53. public bool Encloses(Rect2 b)
  54. {
  55. return b._position.x >= _position.x && b._position.y >= _position.y &&
  56. b._position.x + b._size.x < _position.x + _size.x &&
  57. b._position.y + b._size.y < _position.y + _size.y;
  58. }
  59. public Rect2 Expand(Vector2 to)
  60. {
  61. var expanded = this;
  62. Vector2 begin = expanded._position;
  63. Vector2 end = expanded._position + expanded._size;
  64. if (to.x < begin.x)
  65. begin.x = to.x;
  66. if (to.y < begin.y)
  67. begin.y = to.y;
  68. if (to.x > end.x)
  69. end.x = to.x;
  70. if (to.y > end.y)
  71. end.y = to.y;
  72. expanded._position = begin;
  73. expanded._size = end - begin;
  74. return expanded;
  75. }
  76. public real_t GetArea()
  77. {
  78. return _size.x * _size.y;
  79. }
  80. public Rect2 Grow(real_t by)
  81. {
  82. var g = this;
  83. g._position.x -= by;
  84. g._position.y -= by;
  85. g._size.x += by * 2;
  86. g._size.y += by * 2;
  87. return g;
  88. }
  89. public Rect2 GrowIndividual(real_t left, real_t top, real_t right, real_t bottom)
  90. {
  91. var g = this;
  92. g._position.x -= left;
  93. g._position.y -= top;
  94. g._size.x += left + right;
  95. g._size.y += top + bottom;
  96. return g;
  97. }
  98. public Rect2 GrowMargin(Margin margin, real_t by)
  99. {
  100. var g = this;
  101. g.GrowIndividual(Margin.Left == margin ? by : 0,
  102. Margin.Top == margin ? by : 0,
  103. Margin.Right == margin ? by : 0,
  104. Margin.Bottom == margin ? by : 0);
  105. return g;
  106. }
  107. public bool HasNoArea()
  108. {
  109. return _size.x <= 0 || _size.y <= 0;
  110. }
  111. public bool HasPoint(Vector2 point)
  112. {
  113. if (point.x < _position.x)
  114. return false;
  115. if (point.y < _position.y)
  116. return false;
  117. if (point.x >= _position.x + _size.x)
  118. return false;
  119. if (point.y >= _position.y + _size.y)
  120. return false;
  121. return true;
  122. }
  123. public bool Intersects(Rect2 b)
  124. {
  125. if (_position.x > b._position.x + b._size.x)
  126. return false;
  127. if (_position.x + _size.x < b._position.x)
  128. return false;
  129. if (_position.y > b._position.y + b._size.y)
  130. return false;
  131. if (_position.y + _size.y < b._position.y)
  132. return false;
  133. return true;
  134. }
  135. public Rect2 Merge(Rect2 b)
  136. {
  137. Rect2 newRect;
  138. newRect._position.x = Mathf.Min(b._position.x, _position.x);
  139. newRect._position.y = Mathf.Min(b._position.y, _position.y);
  140. newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x);
  141. newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y);
  142. newRect._size = newRect._size - newRect._position; // Make relative again
  143. return newRect;
  144. }
  145. // Constructors
  146. public Rect2(Vector2 position, Vector2 size)
  147. {
  148. _position = position;
  149. _size = size;
  150. }
  151. public Rect2(Vector2 position, real_t width, real_t height)
  152. {
  153. _position = position;
  154. _size = new Vector2(width, height);
  155. }
  156. public Rect2(real_t x, real_t y, Vector2 size)
  157. {
  158. _position = new Vector2(x, y);
  159. _size = size;
  160. }
  161. public Rect2(real_t x, real_t y, real_t width, real_t height)
  162. {
  163. _position = new Vector2(x, y);
  164. _size = new Vector2(width, height);
  165. }
  166. public static bool operator ==(Rect2 left, Rect2 right)
  167. {
  168. return left.Equals(right);
  169. }
  170. public static bool operator !=(Rect2 left, Rect2 right)
  171. {
  172. return !left.Equals(right);
  173. }
  174. public override bool Equals(object obj)
  175. {
  176. if (obj is Rect2)
  177. {
  178. return Equals((Rect2)obj);
  179. }
  180. return false;
  181. }
  182. public bool Equals(Rect2 other)
  183. {
  184. return _position.Equals(other._position) && _size.Equals(other._size);
  185. }
  186. public override int GetHashCode()
  187. {
  188. return _position.GetHashCode() ^ _size.GetHashCode();
  189. }
  190. public override string ToString()
  191. {
  192. return String.Format("({0}, {1})", new object[]
  193. {
  194. _position.ToString(),
  195. _size.ToString()
  196. });
  197. }
  198. public string ToString(string format)
  199. {
  200. return String.Format("({0}, {1})", new object[]
  201. {
  202. _position.ToString(format),
  203. _size.ToString(format)
  204. });
  205. }
  206. }
  207. }