using System; using System.Collections.Generic; using UnityEngine; namespace BrewMonster.Scripts { public class ARect where T : IComparable { public T left, top, right, bottom; public ARect() { left = default(T); top = default(T); right = default(T); bottom = default(T); } public ARect(ARect rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; } public ARect(T left, T top, T right, T bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } // == and != operator public static bool operator !=(ARect rc1, ARect rc2) { return !(rc1 == rc2); } public static bool operator ==(ARect rc1, ARect rc2) { return EqualityComparer.Default.Equals(rc1.left, rc2.left) && EqualityComparer.Default.Equals(rc1.top, rc2.top) && EqualityComparer.Default.Equals(rc1.right, rc2.right) && EqualityComparer.Default.Equals(rc1.bottom, rc2.bottom); } // + and - operator public static ARect operator +(ARect rc1, ARect rc2) { dynamic l = rc1.left, t = rc1.top, r = rc1.right, b = rc1.bottom; dynamic l2 = rc2.left, t2 = rc2.top, r2 = rc2.right, b2 = rc2.bottom; ARect result = new ARect(l + l2, t + t2, r + r2, b + b2); return result; } public static ARect operator -(ARect rc1, ARect rc2) { return new ARect((dynamic)rc1.left - (dynamic)rc2.left, (dynamic)rc1.top - (dynamic)rc2.top, (dynamic)rc1.right - (dynamic)rc2.right, (dynamic)rc1.bottom - (dynamic)rc2.bottom); } //public static ARect operator +(ARect rc1, APoint pt) //{ // return new ARect((dynamic)rc1.left + (dynamic)pt.x, // (dynamic)rc1.top + (dynamic)pt.y, // (dynamic)rc1.right + (dynamic)pt.x, // (dynamic)rc1.bottom + (dynamic)pt.y); //} //public static ARect operator -(ARect rc1, APoint pt) //{ // return new ARect((dynamic)rc1.left - (dynamic)pt.x, // (dynamic)rc1.top - (dynamic)pt.y, // (dynamic)rc1.right - (dynamic)pt.x, // (dynamic)rc1.bottom - (dynamic)pt.y); //} // &= and |= operator public ARect AndAssign(ARect rc) => this & rc; public ARect OrAssign(ARect rc) => this | rc; public static ARect operator &(ARect rc1, ARect rc2) { if (rc1.IsEmpty() || rc2.IsEmpty()) return new ARect(default, default, default, default); dynamic l1 = rc1.left, r1 = rc1.right, t1 = rc1.top, b1 = rc1.bottom; dynamic l2 = rc2.left, r2 = rc2.right, t2 = rc2.top, b2 = rc2.bottom; if (l1 >= r2 || l2 >= r1 || t1 >= b2 || t2 >= b1) return new ARect(default, default, default, default); return new ARect(l1 > l2 ? l1 : l2, t1 > t2 ? t1 : t2, r1 < r2 ? r1 : r2, b1 < b2 ? b1 : b2); } public static ARect operator |(ARect rc1, ARect rc2) { if (rc1.IsEmpty()) return rc2; if (rc2.IsEmpty()) return rc1; dynamic l1 = rc1.left, r1 = rc1.right, t1 = rc1.top, b1 = rc1.bottom; dynamic l2 = rc2.left, r2 = rc2.right, t2 = rc2.top, b2 = rc2.bottom; return new ARect(l1 < l2 ? l1 : l2, t1 < t2 ? t1 : t2, r1 > r2 ? r1 : r2, b1 > b2 ? b1 : b2); } public static ARect operator +(ARect rc) { return rc; } public static ARect operator -(ARect rc) { return new ARect(-(dynamic)rc.left, -(dynamic)rc.top, -(dynamic)rc.right, -(dynamic)rc.bottom); } // = operator //public static ARect operator = (ARect rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; return *this; } // += and -= operator public ARect AdditionAssign(ARect rc) { left += (dynamic)rc.left; top += (dynamic)rc.top; right += (dynamic)rc.right; bottom += (dynamic)rc.bottom; return this; } public ARect SubtractionAssign(ARect rc) { left -= (dynamic)rc.left; top -= (dynamic)rc.top; right -= (dynamic)rc.right; bottom -= (dynamic)rc.bottom; return this; } //public ARect AdditionAssign(APoint pt) { left += pt.x; top += pt.y; right += pt.x; bottom += pt.y; return this; } //public ARect SubtractionAssign(APoint pt) { left -= pt.x; top -= pt.y; right -= pt.x; bottom -= pt.y; return this; } // Get width of rectangle public T Width() { return (dynamic)right - (dynamic)left; } // Get height of rectangle public T Height() { return (dynamic)bottom - (dynamic)top; } // Get center point of rectangle //public APoint CenterPoint() { return new APoint((left + right) / 2, (top + bottom) / 2); } // Set rectangle value public void SetRect(T _left, T _top, T _right, T _bottom) { left = _left; top = _top; right = _right; bottom = _bottom; } // Point in rectangle public bool PtInRect(T x, T y) { dynamic valueX = x; dynamic valueY = y; return (valueX >= left && valueX < right && valueY >= top && valueY < bottom) ? true : false; } //public bool PtInRect(APoint pt) { return PtInRect(pt.x, pt.y); } // Normalize rectangle. Note: The following CRect member functions require // normalized rectangles in order to work properly: Height, Width, Size, // IsEmpty, PtInRect, SetUnion, SetIntersect, operator ==, operator !=, // operator |, operator |=, operator &, and operator &= void Normalize() { if ((dynamic)left > right) a_Swap(left, right); if ((dynamic)top > bottom) a_Swap(top, bottom); } private void a_Swap(T lhs, T rhs) { T tmp; tmp = lhs; lhs = rhs; rhs = tmp; } // All members are 0 ? public bool IsRectNull() { return ((dynamic)left == 0 && (dynamic)top == 0 && (dynamic)right == 0 && (dynamic)bottom == 0); } // Rectangle is empty ? public bool IsEmpty() { return ((dynamic)Width() == 0 || (dynamic)Height() == 0); } // Set all members to 0 public void Clear() { left = top = right = bottom = default(T); } // Deflate rectangle public void Deflate(T x, T y) { left += (dynamic)x; top += (dynamic)y; right -= (dynamic)x; bottom -= (dynamic)y; } public void Deflate(ARect rc) { left += (dynamic)rc.left; top += (dynamic)rc.top; right -= (dynamic)rc.right; bottom -= (dynamic)rc.bottom; } public void Deflate(T l, T t, T r, T b) { left += (dynamic)l; top += (dynamic)t; right -= (dynamic)r; bottom -= (dynamic)b; } // Inflate rectangle public void Inflate(T x, T y) { left -= (dynamic)x; top -= (dynamic)y; right += (dynamic)x; bottom += (dynamic)y; } public void Inflate(ARect rc) { left -= (dynamic)rc.left; top -= (dynamic)rc.top; right += (dynamic)rc.right; bottom += (dynamic)rc.bottom; } public void Inflate(T l, T t, T r, T b) { left -= (dynamic)l; top -= (dynamic)t; right += (dynamic)r; bottom += (dynamic)b; } // Offset rectangle public void Offset(T x, T y) { left += (dynamic)x; top += (dynamic)y; right += (dynamic)x; bottom += (dynamic)y; } //public void Offset(APoint pt) { this += pt; } // Set rectangle as union result public void SetUnion(ARect rc1, ARect rc2) { var result = rc1 | rc2; left = result.left; right = result.right; bottom = result.bottom; top = result.top; } // Set rectangle as intersect result public void SetIntersect(ARect rc1, ARect rc2) { var result = rc1 & rc2; left = result.left; right = result.right; bottom = result.bottom; top = result.top; } } }