IntRect.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using UnityEngine;
  2. namespace PF
  3. {
  4. /** Integer Rectangle.
  5. * Works almost like UnityEngine.Rect but with integer coordinates
  6. */
  7. [System.Serializable]
  8. public struct IntRect {
  9. public int xmin, ymin, xmax, ymax;
  10. public IntRect (int xmin, int ymin, int xmax, int ymax) {
  11. this.xmin = xmin;
  12. this.xmax = xmax;
  13. this.ymin = ymin;
  14. this.ymax = ymax;
  15. }
  16. public bool Contains (int x, int y) {
  17. return !(x < xmin || y < ymin || x > xmax || y > ymax);
  18. }
  19. public int Width {
  20. get {
  21. return xmax-xmin+1;
  22. }
  23. }
  24. public int Height {
  25. get {
  26. return ymax-ymin+1;
  27. }
  28. }
  29. /** Returns if this rectangle is valid.
  30. * An invalid rect could have e.g xmin > xmax.
  31. * Rectamgles with a zero area area invalid.
  32. */
  33. public bool IsValid () {
  34. return xmin <= xmax && ymin <= ymax;
  35. }
  36. public static bool operator == (IntRect a, IntRect b) {
  37. return a.xmin == b.xmin && a.xmax == b.xmax && a.ymin == b.ymin && a.ymax == b.ymax;
  38. }
  39. public static bool operator != (IntRect a, IntRect b) {
  40. return a.xmin != b.xmin || a.xmax != b.xmax || a.ymin != b.ymin || a.ymax != b.ymax;
  41. }
  42. public override bool Equals (System.Object obj) {
  43. var rect = (IntRect)obj;
  44. return xmin == rect.xmin && xmax == rect.xmax && ymin == rect.ymin && ymax == rect.ymax;
  45. }
  46. public override int GetHashCode () {
  47. return xmin*131071 ^ xmax*3571 ^ ymin*3109 ^ ymax*7;
  48. }
  49. /** Returns the intersection rect between the two rects.
  50. * The intersection rect is the area which is inside both rects.
  51. * If the rects do not have an intersection, an invalid rect is returned.
  52. * \see IsValid
  53. */
  54. public static IntRect Intersection (IntRect a, IntRect b) {
  55. return new IntRect(
  56. System.Math.Max(a.xmin, b.xmin),
  57. System.Math.Max(a.ymin, b.ymin),
  58. System.Math.Min(a.xmax, b.xmax),
  59. System.Math.Min(a.ymax, b.ymax)
  60. );
  61. }
  62. /** Returns if the two rectangles intersect each other
  63. */
  64. public static bool Intersects (IntRect a, IntRect b) {
  65. return !(a.xmin > b.xmax || a.ymin > b.ymax || a.xmax < b.xmin || a.ymax < b.ymin);
  66. }
  67. /** Returns a new rect which contains both input rects.
  68. * This rectangle may contain areas outside both input rects as well in some cases.
  69. */
  70. public static IntRect Union (IntRect a, IntRect b) {
  71. return new IntRect(
  72. System.Math.Min(a.xmin, b.xmin),
  73. System.Math.Min(a.ymin, b.ymin),
  74. System.Math.Max(a.xmax, b.xmax),
  75. System.Math.Max(a.ymax, b.ymax)
  76. );
  77. }
  78. /** Returns a new IntRect which is expanded to contain the point */
  79. public IntRect ExpandToContain (int x, int y) {
  80. return new IntRect(
  81. System.Math.Min(xmin, x),
  82. System.Math.Min(ymin, y),
  83. System.Math.Max(xmax, x),
  84. System.Math.Max(ymax, y)
  85. );
  86. }
  87. /** Returns a new rect which is expanded by \a range in all directions.
  88. * \param range How far to expand. Negative values are permitted.
  89. */
  90. public IntRect Expand (int range) {
  91. return new IntRect(xmin-range,
  92. ymin-range,
  93. xmax+range,
  94. ymax+range
  95. );
  96. }
  97. /** Matrices for rotation.
  98. * Each group of 4 elements is a 2x2 matrix.
  99. * The XZ position is multiplied by this.
  100. * So
  101. * \code
  102. * //A rotation by 90 degrees clockwise, second matrix in the array
  103. * (5,2) * ((0, 1), (-1, 0)) = (2,-5)
  104. * \endcode
  105. */
  106. private static readonly int[] Rotations = {
  107. 1, 0, //Identity matrix
  108. 0, 1,
  109. 0, 1,
  110. -1, 0,
  111. -1, 0,
  112. 0, -1,
  113. 0, -1,
  114. 1, 0
  115. };
  116. /** Returns a new rect rotated around the origin 90*r degrees.
  117. * Ensures that a valid rect is returned.
  118. */
  119. public IntRect Rotate (int r) {
  120. int mx1 = Rotations[r*4+0];
  121. int mx2 = Rotations[r*4+1];
  122. int my1 = Rotations[r*4+2];
  123. int my2 = Rotations[r*4+3];
  124. int p1x = mx1*xmin + mx2*ymin;
  125. int p1y = my1*xmin + my2*ymin;
  126. int p2x = mx1*xmax + mx2*ymax;
  127. int p2y = my1*xmax + my2*ymax;
  128. return new IntRect(
  129. System.Math.Min(p1x, p2x),
  130. System.Math.Min(p1y, p2y),
  131. System.Math.Max(p1x, p2x),
  132. System.Math.Max(p1y, p2y)
  133. );
  134. }
  135. /** Returns a new rect which is offset by the specified amount.
  136. */
  137. public IntRect Offset (Int2 offset) {
  138. return new IntRect(xmin+offset.x, ymin + offset.y, xmax + offset.x, ymax + offset.y);
  139. }
  140. /** Returns a new rect which is offset by the specified amount.
  141. */
  142. public IntRect Offset (int x, int y) {
  143. return new IntRect(xmin+x, ymin + y, xmax + x, ymax + y);
  144. }
  145. public override string ToString () {
  146. return "[x: "+xmin+"..."+xmax+", y: " + ymin +"..."+ymax+"]";
  147. }
  148. #if !SERVER
  149. /** Draws some debug lines representing the rect */
  150. public void DebugDraw (GraphTransform transform, UnityEngine.Color color) {
  151. Vector3 p1 = transform.Transform(new Vector3(xmin, 0, ymin));
  152. Vector3 p2 = transform.Transform(new Vector3(xmin, 0, ymax));
  153. Vector3 p3 = transform.Transform(new Vector3(xmax, 0, ymax));
  154. Vector3 p4 = transform.Transform(new Vector3(xmax, 0, ymin));
  155. UnityEngine.Debug.DrawLine(p1, p2, color);
  156. UnityEngine.Debug.DrawLine(p2, p3, color);
  157. UnityEngine.Debug.DrawLine(p3, p4, color);
  158. UnityEngine.Debug.DrawLine(p4, p1, color);
  159. }
  160. #endif
  161. }
  162. }