using UnityEngine; namespace PF { /** Integer Rectangle. * Works almost like UnityEngine.Rect but with integer coordinates */ [System.Serializable] public struct IntRect { public int xmin, ymin, xmax, ymax; public IntRect (int xmin, int ymin, int xmax, int ymax) { this.xmin = xmin; this.xmax = xmax; this.ymin = ymin; this.ymax = ymax; } public bool Contains (int x, int y) { return !(x < xmin || y < ymin || x > xmax || y > ymax); } public int Width { get { return xmax-xmin+1; } } public int Height { get { return ymax-ymin+1; } } /** Returns if this rectangle is valid. * An invalid rect could have e.g xmin > xmax. * Rectamgles with a zero area area invalid. */ public bool IsValid () { return xmin <= xmax && ymin <= ymax; } public static bool operator == (IntRect a, IntRect b) { return a.xmin == b.xmin && a.xmax == b.xmax && a.ymin == b.ymin && a.ymax == b.ymax; } public static bool operator != (IntRect a, IntRect b) { return a.xmin != b.xmin || a.xmax != b.xmax || a.ymin != b.ymin || a.ymax != b.ymax; } public override bool Equals (System.Object obj) { var rect = (IntRect)obj; return xmin == rect.xmin && xmax == rect.xmax && ymin == rect.ymin && ymax == rect.ymax; } public override int GetHashCode () { return xmin*131071 ^ xmax*3571 ^ ymin*3109 ^ ymax*7; } /** Returns the intersection rect between the two rects. * The intersection rect is the area which is inside both rects. * If the rects do not have an intersection, an invalid rect is returned. * \see IsValid */ public static IntRect Intersection (IntRect a, IntRect b) { return new IntRect( System.Math.Max(a.xmin, b.xmin), System.Math.Max(a.ymin, b.ymin), System.Math.Min(a.xmax, b.xmax), System.Math.Min(a.ymax, b.ymax) ); } /** Returns if the two rectangles intersect each other */ public static bool Intersects (IntRect a, IntRect b) { return !(a.xmin > b.xmax || a.ymin > b.ymax || a.xmax < b.xmin || a.ymax < b.ymin); } /** Returns a new rect which contains both input rects. * This rectangle may contain areas outside both input rects as well in some cases. */ public static IntRect Union (IntRect a, IntRect b) { return new IntRect( System.Math.Min(a.xmin, b.xmin), System.Math.Min(a.ymin, b.ymin), System.Math.Max(a.xmax, b.xmax), System.Math.Max(a.ymax, b.ymax) ); } /** Returns a new IntRect which is expanded to contain the point */ public IntRect ExpandToContain (int x, int y) { return new IntRect( System.Math.Min(xmin, x), System.Math.Min(ymin, y), System.Math.Max(xmax, x), System.Math.Max(ymax, y) ); } /** Returns a new rect which is expanded by \a range in all directions. * \param range How far to expand. Negative values are permitted. */ public IntRect Expand (int range) { return new IntRect(xmin-range, ymin-range, xmax+range, ymax+range ); } /** Matrices for rotation. * Each group of 4 elements is a 2x2 matrix. * The XZ position is multiplied by this. * So * \code * //A rotation by 90 degrees clockwise, second matrix in the array * (5,2) * ((0, 1), (-1, 0)) = (2,-5) * \endcode */ private static readonly int[] Rotations = { 1, 0, //Identity matrix 0, 1, 0, 1, -1, 0, -1, 0, 0, -1, 0, -1, 1, 0 }; /** Returns a new rect rotated around the origin 90*r degrees. * Ensures that a valid rect is returned. */ public IntRect Rotate (int r) { int mx1 = Rotations[r*4+0]; int mx2 = Rotations[r*4+1]; int my1 = Rotations[r*4+2]; int my2 = Rotations[r*4+3]; int p1x = mx1*xmin + mx2*ymin; int p1y = my1*xmin + my2*ymin; int p2x = mx1*xmax + mx2*ymax; int p2y = my1*xmax + my2*ymax; return new IntRect( System.Math.Min(p1x, p2x), System.Math.Min(p1y, p2y), System.Math.Max(p1x, p2x), System.Math.Max(p1y, p2y) ); } /** Returns a new rect which is offset by the specified amount. */ public IntRect Offset (Int2 offset) { return new IntRect(xmin+offset.x, ymin + offset.y, xmax + offset.x, ymax + offset.y); } /** Returns a new rect which is offset by the specified amount. */ public IntRect Offset (int x, int y) { return new IntRect(xmin+x, ymin + y, xmax + x, ymax + y); } public override string ToString () { return "[x: "+xmin+"..."+xmax+", y: " + ymin +"..."+ymax+"]"; } #if !SERVER /** Draws some debug lines representing the rect */ public void DebugDraw (GraphTransform transform, UnityEngine.Color color) { Vector3 p1 = transform.Transform(new Vector3(xmin, 0, ymin)); Vector3 p2 = transform.Transform(new Vector3(xmin, 0, ymax)); Vector3 p3 = transform.Transform(new Vector3(xmax, 0, ymax)); Vector3 p4 = transform.Transform(new Vector3(xmax, 0, ymin)); UnityEngine.Debug.DrawLine(p1, p2, color); UnityEngine.Debug.DrawLine(p2, p3, color); UnityEngine.Debug.DrawLine(p3, p4, color); UnityEngine.Debug.DrawLine(p4, p1, color); } #endif } }