IntRect.cs 5.0 KB

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