Rect2.cs 6.2 KB

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