#region License
/* FNA - XNA4 Reimplementation for Desktop Platforms
* Copyright 2009-2016 Ethan Lee and the MonoGame Team
*
* Released under the Microsoft Public License.
* See LICENSE for details.
*/
/* Derived from code by the Mono.Xna Team (Copyright 2006).
* Released under the MIT License. See monoxna.LICENSE for details.
*/
#endregion
#region Using Statements
using System;
using System.ComponentModel;
using System.Diagnostics;
using Microsoft.Xna.Framework.Design;
#endregion
namespace Microsoft.Xna.Framework
{
///
/// Describes a 2D-rectangle.
///
[Serializable]
[TypeConverter(typeof(RectangleConverter))]
[DebuggerDisplay("{DebugDisplayString,nq}")]
public struct Rectangle : IEquatable
{
#region Public Properties
///
/// Returns the x coordinate of the left edge of this .
///
public int Left
{
get
{
return X;
}
}
///
/// Returns the x coordinate of the right edge of this .
///
public int Right
{
get
{
return (X + Width);
}
}
///
/// Returns the y coordinate of the top edge of this .
///
public int Top
{
get
{
return Y;
}
}
///
/// Returns the y coordinate of the bottom edge of this .
///
public int Bottom
{
get
{
return (Y + Height);
}
}
///
/// The top-left coordinates of this .
///
public Point Location
{
get
{
return new Point(X, Y);
}
set
{
X = value.X;
Y = value.Y;
}
}
///
/// A located in the center of this 's bounds.
///
///
/// If or is an odd number,
/// the center point will be rounded down.
///
public Point Center
{
get
{
return new Point(
X + (Width / 2),
Y + (Height / 2)
);
}
}
///
/// Whether or not this has a width and
/// height of 0, and a position of (0, 0).
///
public bool IsEmpty
{
get
{
return ( (Width == 0) &&
(Height == 0) &&
(X == 0) &&
(Y == 0) );
}
}
#endregion
#region Public Static Properties
///
/// Returns a with X=0, Y=0, Width=0, and Height=0.
///
public static Rectangle Empty
{
get
{
return emptyRectangle;
}
}
#endregion
#region Internal Properties
internal string DebugDisplayString
{
get
{
return string.Concat(
X.ToString(), " ",
Y.ToString(), " ",
Width.ToString(), " ",
Height.ToString()
);
}
}
#endregion
#region Public Fields
///
/// The x coordinate of the top-left corner of this .
///
public int X;
///
/// The y coordinate of the top-left corner of this .
///
public int Y;
///
/// The width of this .
///
public int Width;
///
/// The height of this .
///
public int Height;
#endregion
#region Private Static Fields
private static Rectangle emptyRectangle = new Rectangle();
#endregion
#region Public Constructors
///
/// Creates a with the specified
/// position, width, and height.
///
/// The x coordinate of the top-left corner of the created .
/// The y coordinate of the top-left corner of the created .
/// The width of the created .
/// The height of the created .
public Rectangle(int x, int y, int width, int height)
{
X = x;
Y = y;
Width = width;
Height = height;
}
#endregion
#region Public Methods
///
/// Gets whether or not the provided coordinates lie within the bounds of this .
///
/// The x coordinate of the point to check for containment.
/// The y coordinate of the point to check for containment.
/// true if the provided coordinates lie inside this . false otherwise.
public bool Contains(int x, int y)
{
return ( (this.X <= x) &&
(x < (this.X + this.Width)) &&
(this.Y <= y) &&
(y < (this.Y + this.Height)) );
}
///
/// Gets whether or not the provided lies within the bounds of this .
///
/// The coordinates to check for inclusion in this .
/// true if the provided lies inside this . false otherwise.
public bool Contains(Point value)
{
return ( (this.X <= value.X) &&
(value.X < (this.X + this.Width)) &&
(this.Y <= value.Y) &&
(value.Y < (this.Y + this.Height)) );
}
///
/// Gets whether or not the provided lies within the bounds of this .
///
/// The to check for inclusion in this .
/// true if the provided 's bounds lie entirely inside this . false otherwise.
public bool Contains(Rectangle value)
{
return ( (this.X <= value.X) &&
((value.X + value.Width) <= (this.X + this.Width)) &&
(this.Y <= value.Y) &&
((value.Y + value.Height) <= (this.Y + this.Height)) );
}
public void Contains(ref Point value, out bool result)
{
result = ( (this.X <= value.X) &&
(value.X < (this.X + this.Width)) &&
(this.Y <= value.Y) &&
(value.Y < (this.Y + this.Height)) );
}
public void Contains(ref Rectangle value, out bool result)
{
result = ( (this.X <= value.X) &&
(value.X < (this.X + this.Width)) &&
(this.Y <= value.Y) &&
(value.Y < (this.Y + this.Height)) );
}
///
/// Increments this 's by the
/// x and y components of the provided .
///
/// The x and y components to add to this 's .
public void Offset(Point offset)
{
X += offset.X;
Y += offset.Y;
}
///
/// Increments this 's by the
/// provided x and y coordinates.
///
/// The x coordinate to add to this 's .
/// The y coordinate to add to this 's .
public void Offset(int offsetX, int offsetY)
{
X += offsetX;
Y += offsetY;
}
public void Inflate(int horizontalValue, int verticalValue)
{
X -= horizontalValue;
Y -= verticalValue;
Width += horizontalValue * 2;
Height += verticalValue * 2;
}
///
/// Checks whether or not this is equivalent
/// to a provided .
///
/// The to test for equality.
///
/// true if this 's x coordinate, y coordinate, width, and height
/// match the values for the provided . false otherwise.
///
public bool Equals(Rectangle other)
{
return this == other;
}
///
/// Checks whether or not this is equivalent
/// to a provided object.
///
/// The to test for equality.
///
/// true if the provided object is a , and this
/// 's x coordinate, y coordinate, width, and height
/// match the values for the provided . false otherwise.
///
public override bool Equals(object obj)
{
return (obj is Rectangle) && this == ((Rectangle) obj);
}
public override string ToString()
{
return (
"{X:" + X.ToString() +
" Y:" + Y.ToString() +
" Width:" + Width.ToString() +
" Height:" + Height.ToString() +
"}"
);
}
public override int GetHashCode()
{
return (this.X ^ this.Y ^ this.Width ^ this.Height);
}
///
/// Gets whether or not the other intersects with this rectangle.
///
/// The other rectangle for testing.
/// true if other intersects with this rectangle; false otherwise.
public bool Intersects(Rectangle value)
{
return ( value.Left < Right &&
Left < value.Right &&
value.Top < Bottom &&
Top < value.Bottom );
}
///
/// Gets whether or not the other intersects with this rectangle.
///
/// The other rectangle for testing.
/// true if other intersects with this rectangle; false otherwise. As an output parameter.
public void Intersects(ref Rectangle value, out bool result)
{
result = ( value.Left < Right &&
Left < value.Right &&
value.Top < Bottom &&
Top < value.Bottom );
}
#endregion
#region Public Static Methods
public static bool operator ==(Rectangle a, Rectangle b)
{
return ( (a.X == b.X) &&
(a.Y == b.Y) &&
(a.Width == b.Width) &&
(a.Height == b.Height) );
}
public static bool operator !=(Rectangle a, Rectangle b)
{
return !(a == b);
}
public static Rectangle Intersect(Rectangle value1, Rectangle value2)
{
Rectangle rectangle;
Intersect(ref value1, ref value2, out rectangle);
return rectangle;
}
public static void Intersect(
ref Rectangle value1,
ref Rectangle value2,
out Rectangle result
) {
if (value1.Intersects(value2))
{
int right_side = Math.Min(
value1.X + value1.Width,
value2.X + value2.Width
);
int left_side = Math.Max(value1.X, value2.X);
int top_side = Math.Max(value1.Y, value2.Y);
int bottom_side = Math.Min(
value1.Y + value1.Height,
value2.Y + value2.Height
);
result = new Rectangle(
left_side,
top_side,
right_side - left_side,
bottom_side - top_side
);
}
else
{
result = new Rectangle(0, 0, 0, 0);
}
}
public static Rectangle Union(Rectangle value1, Rectangle value2)
{
int x = Math.Min(value1.X, value2.X);
int y = Math.Min(value1.Y, value2.Y);
return new Rectangle(
x,
y,
Math.Max(value1.Right, value2.Right) - x,
Math.Max(value1.Bottom, value2.Bottom) - y
);
}
public static void Union(ref Rectangle value1, ref Rectangle value2, out Rectangle result)
{
result.X = Math.Min(value1.X, value2.X);
result.Y = Math.Min(value1.Y, value2.Y);
result.Width = Math.Max(value1.Right, value2.Right) - result.X;
result.Height = Math.Max(value1.Bottom, value2.Bottom) - result.Y;
}
#endregion
}
}