282 lines
9.3 KiB
C#
282 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
public class ARect<T> where T : IComparable<T>
|
|
{
|
|
public T left, top, right, bottom;
|
|
|
|
public ARect()
|
|
{
|
|
left = default(T);
|
|
top = default(T);
|
|
right = default(T);
|
|
bottom = default(T);
|
|
}
|
|
|
|
public ARect(ARect<T> 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<T> rc1, ARect<T> rc2)
|
|
{
|
|
return !(rc1 == rc2);
|
|
}
|
|
public static bool operator ==(ARect<T> rc1, ARect<T> rc2)
|
|
{
|
|
return EqualityComparer<T>.Default.Equals(rc1.left, rc2.left) &&
|
|
EqualityComparer<T>.Default.Equals(rc1.top, rc2.top) &&
|
|
EqualityComparer<T>.Default.Equals(rc1.right, rc2.right) &&
|
|
EqualityComparer<T>.Default.Equals(rc1.bottom, rc2.bottom);
|
|
}
|
|
|
|
// + and - operator
|
|
public static ARect<T> operator +(ARect<T> rc1, ARect<T> 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<T> result = new ARect<T>(l + l2, t + t2, r + r2, b + b2);
|
|
return result;
|
|
}
|
|
public static ARect<T> operator -(ARect<T> rc1, ARect<T> rc2)
|
|
{
|
|
return new ARect<T>((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<T> operator +(ARect<T> rc1, APoint<T> pt)
|
|
//{
|
|
// return new ARect<T>((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<T> operator -(ARect<T> rc1, APoint<T> pt)
|
|
//{
|
|
// return new ARect<T>((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<T> AndAssign(ARect<T> rc) => this & rc;
|
|
public ARect<T> OrAssign(ARect<T> rc) => this | rc;
|
|
|
|
public static ARect<T> operator &(ARect<T> rc1, ARect<T> rc2)
|
|
{
|
|
if (rc1.IsEmpty() || rc2.IsEmpty())
|
|
return new ARect<T>(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<T>(default, default, default, default);
|
|
|
|
return new ARect<T>(l1 > l2 ? l1 : l2,
|
|
t1 > t2 ? t1 : t2,
|
|
r1 < r2 ? r1 : r2,
|
|
b1 < b2 ? b1 : b2);
|
|
}
|
|
|
|
public static ARect<T> operator |(ARect<T> rc1, ARect<T> 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<T>(l1 < l2 ? l1 : l2,
|
|
t1 < t2 ? t1 : t2,
|
|
r1 > r2 ? r1 : r2,
|
|
b1 > b2 ? b1 : b2);
|
|
}
|
|
|
|
public static ARect<T> operator +(ARect<T> rc) { return rc; }
|
|
public static ARect<T> operator -(ARect<T> rc)
|
|
{
|
|
return new ARect<T>(-(dynamic)rc.left, -(dynamic)rc.top, -(dynamic)rc.right, -(dynamic)rc.bottom);
|
|
}
|
|
|
|
// = operator
|
|
//public static ARect<T> operator = (ARect<T> rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; return *this; }
|
|
|
|
// += and -= operator
|
|
public ARect<T> AdditionAssign(ARect<T> rc)
|
|
{
|
|
left += (dynamic)rc.left;
|
|
top += (dynamic)rc.top;
|
|
right += (dynamic)rc.right;
|
|
bottom += (dynamic)rc.bottom;
|
|
return this;
|
|
}
|
|
public ARect<T> SubtractionAssign(ARect<T> rc)
|
|
{
|
|
left -= (dynamic)rc.left;
|
|
top -= (dynamic)rc.top;
|
|
right -= (dynamic)rc.right;
|
|
bottom -= (dynamic)rc.bottom;
|
|
return this;
|
|
}
|
|
//public ARect<T> AdditionAssign(APoint<T> pt) { left += pt.x; top += pt.y; right += pt.x; bottom += pt.y; return this; }
|
|
//public ARect<T> SubtractionAssign(APoint<T> 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<T> CenterPoint() { return new APoint<T>((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<T> 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<T> 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<T> 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<T> pt) { this += pt; }
|
|
// Set rectangle as union result
|
|
public void SetUnion(ARect<T> rc1, ARect<T> 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<T> rc1, ARect<T> rc2)
|
|
{
|
|
var result = rc1 & rc2;
|
|
left = result.left;
|
|
right = result.right;
|
|
bottom = result.bottom;
|
|
top = result.top;
|
|
}
|
|
}
|
|
}
|