You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
458 lines
15 KiB
458 lines
15 KiB
// Rect
|
|
using System;
|
|
|
|
|
|
/// <summary>
|
|
/// <para>A 2D Rectangle defined by X and Y position, width and height.</para>
|
|
/// </summary>
|
|
namespace Sog
|
|
{
|
|
[Serializable]
|
|
public struct Fixed64Rect
|
|
{
|
|
private Fixed64 m_XMin;
|
|
|
|
private Fixed64 m_YMin;
|
|
|
|
private Fixed64 m_Width;
|
|
|
|
private Fixed64 m_Height;
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// <para>Shorthand for writing new Rect(0,0,0,0).</para>
|
|
/// </summary>
|
|
public static Fixed64Rect zero
|
|
{
|
|
get
|
|
{
|
|
return new Fixed64Rect(0f, 0f, 0f, 0f);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The X coordinate of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64 x
|
|
{
|
|
get
|
|
{
|
|
return m_XMin;
|
|
}
|
|
set
|
|
{
|
|
m_XMin = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The Y coordinate of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64 y
|
|
{
|
|
get
|
|
{
|
|
return m_YMin;
|
|
}
|
|
set
|
|
{
|
|
m_YMin = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The X and Y position of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64Vector2 position
|
|
{
|
|
get
|
|
{
|
|
return new Fixed64Vector2(m_XMin, m_YMin);
|
|
}
|
|
set
|
|
{
|
|
m_XMin = value.x;
|
|
m_YMin = value.y;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The position of the center of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64Vector2 center
|
|
{
|
|
get
|
|
{
|
|
return new Fixed64Vector2(x + m_Width / 2f, y + m_Height / 2f);
|
|
}
|
|
set
|
|
{
|
|
m_XMin = value.x - m_Width / 2f;
|
|
m_YMin = value.y - m_Height / 2f;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The position of the minimum corner of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64Vector2 min
|
|
{
|
|
get
|
|
{
|
|
return new Fixed64Vector2(xMin, yMin);
|
|
}
|
|
set
|
|
{
|
|
xMin = value.x;
|
|
yMin = value.y;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The position of the maximum corner of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64Vector2 max
|
|
{
|
|
get
|
|
{
|
|
return new Fixed64Vector2(xMax, yMax);
|
|
}
|
|
set
|
|
{
|
|
xMax = value.x;
|
|
yMax = value.y;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The width of the rectangle, measured from the X position.</para>
|
|
/// </summary>
|
|
public Fixed64 width
|
|
{
|
|
get
|
|
{
|
|
return m_Width;
|
|
}
|
|
set
|
|
{
|
|
m_Width = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The height of the rectangle, measured from the Y position.</para>
|
|
/// </summary>
|
|
public Fixed64 height
|
|
{
|
|
get
|
|
{
|
|
return m_Height;
|
|
}
|
|
set
|
|
{
|
|
m_Height = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The width and height of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64Vector2 size
|
|
{
|
|
get
|
|
{
|
|
return new Fixed64Vector2(m_Width, m_Height);
|
|
}
|
|
set
|
|
{
|
|
m_Width = value.x;
|
|
m_Height = value.y;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The minimum X coordinate of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64 xMin
|
|
{
|
|
get
|
|
{
|
|
return m_XMin;
|
|
}
|
|
set
|
|
{
|
|
Fixed64 xMax = this.xMax;
|
|
m_XMin = value;
|
|
m_Width = xMax - m_XMin;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The minimum Y coordinate of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64 yMin
|
|
{
|
|
get
|
|
{
|
|
return m_YMin;
|
|
}
|
|
set
|
|
{
|
|
Fixed64 yMax = this.yMax;
|
|
m_YMin = value;
|
|
m_Height = yMax - m_YMin;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The maximum X coordinate of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64 xMax
|
|
{
|
|
get
|
|
{
|
|
return m_Width + m_XMin;
|
|
}
|
|
set
|
|
{
|
|
m_Width = value - m_XMin;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>The maximum Y coordinate of the rectangle.</para>
|
|
/// </summary>
|
|
public Fixed64 yMax
|
|
{
|
|
get
|
|
{
|
|
return m_Height + m_YMin;
|
|
}
|
|
set
|
|
{
|
|
m_Height = value - m_YMin;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <para>Creates a new rectangle.</para>
|
|
/// </summary>
|
|
/// <param name="x">The X value the rect is measured from.</param>
|
|
/// <param name="y">The Y value the rect is measured from.</param>
|
|
/// <param name="width">The width of the rectangle.</param>
|
|
/// <param name="height">The height of the rectangle.</param>
|
|
public Fixed64Rect(Fixed64 x, Fixed64 y, Fixed64 width, Fixed64 height)
|
|
{
|
|
m_XMin = x;
|
|
m_YMin = y;
|
|
m_Width = width;
|
|
m_Height = height;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Creates a rectangle given a size and position.</para>
|
|
/// </summary>
|
|
/// <param name="position">The position of the minimum corner of the rect.</param>
|
|
/// <param name="size">The width and height of the rect.</param>
|
|
public Fixed64Rect(Fixed64Vector2 position, Fixed64Vector2 size)
|
|
{
|
|
m_XMin = position.x;
|
|
m_YMin = position.y;
|
|
m_Width = size.x;
|
|
m_Height = size.y;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para></para>
|
|
/// </summary>
|
|
/// <param name="source"></param>
|
|
public Fixed64Rect(Fixed64Rect source)
|
|
{
|
|
m_XMin = source.m_XMin;
|
|
m_YMin = source.m_YMin;
|
|
m_Width = source.m_Width;
|
|
m_Height = source.m_Height;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Creates a rectangle from min/max coordinate values.</para>
|
|
/// </summary>
|
|
/// <param name="xmin">The minimum X coordinate.</param>
|
|
/// <param name="ymin">The minimum Y coordinate.</param>
|
|
/// <param name="xmax">The maximum X coordinate.</param>
|
|
/// <param name="ymax">The maximum Y coordinate.</param>
|
|
/// <returns>
|
|
/// <para>A rectangle matching the specified coordinates.</para>
|
|
/// </returns>
|
|
public static Fixed64Rect MinMaxRect(Fixed64 xmin, Fixed64 ymin, Fixed64 xmax, Fixed64 ymax)
|
|
{
|
|
return new Fixed64Rect(xmin, ymin, xmax - xmin, ymax - ymin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Set components of an existing Rect.</para>
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <param name="y"></param>
|
|
/// <param name="width"></param>
|
|
/// <param name="height"></param>
|
|
public void Set(Fixed64 x, Fixed64 y, Fixed64 width, Fixed64 height)
|
|
{
|
|
m_XMin = x;
|
|
m_YMin = y;
|
|
m_Width = width;
|
|
m_Height = height;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns true if the x and y components of point is a point inside this rectangle. If allowInverse is present and true, the width and height of the Rect are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.</para>
|
|
/// </summary>
|
|
/// <param name="point">Point to test.</param>
|
|
/// <param name="allowInverse">Does the test allow the Rect's width and height to be negative?</param>
|
|
/// <returns>
|
|
/// <para>True if the point lies within the specified rectangle.</para>
|
|
/// </returns>
|
|
public bool Contains(Fixed64Vector2 point)
|
|
{
|
|
return point.x >= xMin && point.x < xMax && point.y >= yMin && point.y < yMax;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns true if the x and y components of point is a point inside this rectangle. If allowInverse is present and true, the width and height of the Rect are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.</para>
|
|
/// </summary>
|
|
/// <param name="point">Point to test.</param>
|
|
/// <param name="allowInverse">Does the test allow the Rect's width and height to be negative?</param>
|
|
/// <returns>
|
|
/// <para>True if the point lies within the specified rectangle.</para>
|
|
/// </returns>
|
|
public bool Contains(Fixed64Vector3 point)
|
|
{
|
|
return point.x >= xMin && point.x < xMax && point.y >= yMin && point.y < yMax;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns true if the x and y components of point is a point inside this rectangle. If allowInverse is present and true, the width and height of the Rect are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.</para>
|
|
/// </summary>
|
|
/// <param name="point">Point to test.</param>
|
|
/// <param name="allowInverse">Does the test allow the Rect's width and height to be negative?</param>
|
|
/// <returns>
|
|
/// <para>True if the point lies within the specified rectangle.</para>
|
|
/// </returns>
|
|
public bool Contains(Fixed64Vector3 point, bool allowInverse)
|
|
{
|
|
if (!allowInverse)
|
|
{
|
|
return Contains(point);
|
|
}
|
|
bool flag = false;
|
|
if ((width < 0f && point.x <= xMin && point.x > xMax) || (width >= 0f && point.x >= xMin && point.x < xMax))
|
|
{
|
|
flag = true;
|
|
}
|
|
if (flag && ((height < 0f && point.y <= yMin && point.y > yMax) || (height >= 0f && point.y >= yMin && point.y < yMax)))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static Fixed64Rect OrderMinMax(Fixed64Rect rect)
|
|
{
|
|
if (rect.xMin > rect.xMax)
|
|
{
|
|
Fixed64 xMin = rect.xMin;
|
|
rect.xMin = rect.xMax;
|
|
rect.xMax = xMin;
|
|
}
|
|
if (rect.yMin > rect.yMax)
|
|
{
|
|
Fixed64 yMin = rect.yMin;
|
|
rect.yMin = rect.yMax;
|
|
rect.yMax = yMin;
|
|
}
|
|
return rect;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns true if the other rectangle overlaps this one. If allowInverse is present and true, the widths and heights of the Rects are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.</para>
|
|
/// </summary>
|
|
/// <param name="other">Other rectangle to test overlapping with.</param>
|
|
/// <param name="allowInverse">Does the test allow the widths and heights of the Rects to be negative?</param>
|
|
public bool Overlaps(Fixed64Rect other)
|
|
{
|
|
return other.xMax > xMin && other.xMin < xMax && other.yMax > yMin && other.yMin < yMax;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns true if the other rectangle overlaps this one. If allowInverse is present and true, the widths and heights of the Rects are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.</para>
|
|
/// </summary>
|
|
/// <param name="other">Other rectangle to test overlapping with.</param>
|
|
/// <param name="allowInverse">Does the test allow the widths and heights of the Rects to be negative?</param>
|
|
public bool Overlaps(Fixed64Rect other, bool allowInverse)
|
|
{
|
|
Fixed64Rect rect = this;
|
|
if (allowInverse)
|
|
{
|
|
rect = OrderMinMax(rect);
|
|
other = OrderMinMax(other);
|
|
}
|
|
return rect.Overlaps(other);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns a point inside a rectangle, given normalized coordinates.</para>
|
|
/// </summary>
|
|
/// <param name="rectangle">Rectangle to get a point inside.</param>
|
|
/// <param name="normalizedRectCoordinates">Normalized coordinates to get a point for.</param>
|
|
public static Fixed64Vector2 NormalizedToPoint(Fixed64Rect rectangle, Fixed64Vector2 normalizedRectCoordinates)
|
|
{
|
|
return new Fixed64Vector2(FixedMath.Lerp(rectangle.x, rectangle.xMax, normalizedRectCoordinates.x), FixedMath.Lerp(rectangle.y, rectangle.yMax, normalizedRectCoordinates.y));
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns the normalized coordinates cooresponding the the point.</para>
|
|
/// </summary>
|
|
/// <param name="rectangle">Rectangle to get normalized coordinates inside.</param>
|
|
/// <param name="point">A point inside the rectangle to get normalized coordinates for.</param>
|
|
public static Fixed64Vector2 PointToNormalized(Fixed64Rect rectangle, Fixed64Vector2 point)
|
|
{
|
|
return new Fixed64Vector2(FixedMath.InverseLerp(rectangle.x, rectangle.xMax, point.x), FixedMath.InverseLerp(rectangle.y, rectangle.yMax, point.y));
|
|
}
|
|
|
|
public static bool operator !=(Fixed64Rect lhs, Fixed64Rect rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
public static bool operator ==(Fixed64Rect lhs, Fixed64Rect rhs)
|
|
{
|
|
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return x.GetHashCode() ^ (width.GetHashCode() << 2) ^ (y.GetHashCode() >> 2) ^ (height.GetHashCode() >> 1);
|
|
}
|
|
|
|
public override bool Equals(object other)
|
|
{
|
|
if (!(other is Fixed64Rect))
|
|
{
|
|
return false;
|
|
}
|
|
Fixed64Rect rect = (Fixed64Rect)other;
|
|
return x.Equals(rect.x) && y.Equals(rect.y) && width.Equals(rect.width) && height.Equals(rect.height);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>Returns a nicely formatted string for this Rect.</para>
|
|
/// </summary>
|
|
/// <param name="format"></param>
|
|
public override string ToString()
|
|
{
|
|
return string.Format("(x:{0}, y:{1}, width:{2}, height:{3})", x, y, width, height);
|
|
}
|
|
}
|
|
}
|
|
|