123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- // MIT License - Copyright (C) The Mono.Xna Team
- // This file is subject to the terms and conditions defined in
- // file 'LICENSE.txt', which is part of this source code package.
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- namespace CommonLang.Geometry
- {
- /// <summary>
- /// Describes a 2D-rectangle.
- /// </summary>
-
-
- public struct Rectangle : IEquatable<Rectangle>
- {
- #region Private Fields
- private static Rectangle emptyRectangle = new Rectangle();
- #endregion
- #region Public Fields
- /// <summary>
- /// The x coordinate of the top-left corner of this <see cref="Rectangle"/>.
- /// </summary>
-
- public int X;
- /// <summary>
- /// The y coordinate of the top-left corner of this <see cref="Rectangle"/>.
- /// </summary>
-
- public int Y;
- /// <summary>
- /// The width of this <see cref="Rectangle"/>.
- /// </summary>
-
- public int Width;
- /// <summary>
- /// The height of this <see cref="Rectangle"/>.
- /// </summary>
-
- public int Height;
- #endregion
- #region Public Properties
- /// <summary>
- /// Returns a <see cref="Rectangle"/> with X=0, Y=0, Width=0, Height=0.
- /// </summary>
- public static Rectangle Empty
- {
- get { return emptyRectangle; }
- }
- /// <summary>
- /// Returns the x coordinate of the left edge of this <see cref="Rectangle"/>.
- /// </summary>
- public int Left
- {
- get { return this.X; }
- }
- /// <summary>
- /// Returns the x coordinate of the right edge of this <see cref="Rectangle"/>.
- /// </summary>
- public int Right
- {
- get { return (this.X + this.Width); }
- }
- /// <summary>
- /// Returns the y coordinate of the top edge of this <see cref="Rectangle"/>.
- /// </summary>
- public int Top
- {
- get { return this.Y; }
- }
- /// <summary>
- /// Returns the y coordinate of the bottom edge of this <see cref="Rectangle"/>.
- /// </summary>
- public int Bottom
- {
- get { return (this.Y + this.Height); }
- }
- /// <summary>
- /// Whether or not this <see cref="Rectangle"/> has a <see cref="Width"/> and
- /// <see cref="Height"/> of 0, and a <see cref="Location"/> of (0, 0).
- /// </summary>
- public bool IsEmpty
- {
- get
- {
- return ((((this.Width == 0) && (this.Height == 0)) && (this.X == 0)) && (this.Y == 0));
- }
- }
- /// <summary>
- /// The top-left coordinates of this <see cref="Rectangle"/>.
- /// </summary>
- public Point Location
- {
- get
- {
- return new Point(this.X, this.Y);
- }
- set
- {
- X = value.X;
- Y = value.Y;
- }
- }
- /// <summary>
- /// The width-height coordinates of this <see cref="Rectangle"/>.
- /// </summary>
- public Point Size
- {
- get
- {
- return new Point(this.Width,this.Height);
- }
- set
- {
- Width = value.X;
- Height = value.Y;
- }
- }
- /// <summary>
- /// A <see cref="Point"/> located in the center of this <see cref="Rectangle"/>.
- /// </summary>
- /// <remarks>
- /// If <see cref="Width"/> or <see cref="Height"/> is an odd number,
- /// the center point will be rounded down.
- /// </remarks>
- public Point Center
- {
- get
- {
- return new Point(this.X + (this.Width / 2), this.Y + (this.Height / 2));
- }
- }
- #endregion
- #region Internal Properties
- internal string DebugDisplayString
- {
- get
- {
- return string.Concat(
- this.X, " ",
- this.Y, " ",
- this.Width, " ",
- this.Height
- );
- }
- }
- #endregion
- #region Constructors
- /// <summary>
- /// Creates a new instance of <see cref="Rectangle"/> struct, with the specified
- /// position, width, and height.
- /// </summary>
- /// <param name="x">The x coordinate of the top-left corner of the created <see cref="Rectangle"/>.</param>
- /// <param name="y">The y coordinate of the top-left corner of the created <see cref="Rectangle"/>.</param>
- /// <param name="width">The width of the created <see cref="Rectangle"/>.</param>
- /// <param name="height">The height of the created <see cref="Rectangle"/>.</param>
- public Rectangle(int x, int y, int width, int height)
- {
- this.X = x;
- this.Y = y;
- this.Width = width;
- this.Height = height;
- }
- /// <summary>
- /// Creates a new instance of <see cref="Rectangle"/> struct, with the specified
- /// location and size.
- /// </summary>
- /// <param name="location">The x and y coordinates of the top-left corner of the created <see cref="Rectangle"/>.</param>
- /// <param name="size">The width and height of the created <see cref="Rectangle"/>.</param>
- public Rectangle(Point location,Point size)
- {
- this.X = location.X;
- this.Y = location.Y;
- this.Width = size.X;
- this.Height = size.Y;
- }
- #endregion
- #region Operators
- /// <summary>
- /// Compares whether two <see cref="Rectangle"/> instances are equal.
- /// </summary>
- /// <param name="a"><see cref="Rectangle"/> instance on the left of the equal sign.</param>
- /// <param name="b"><see cref="Rectangle"/> instance on the right of the equal sign.</param>
- /// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
- 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));
- }
- /// <summary>
- /// Compares whether two <see cref="Rectangle"/> instances are not equal.
- /// </summary>
- /// <param name="a"><see cref="Rectangle"/> instance on the left of the not equal sign.</param>
- /// <param name="b"><see cref="Rectangle"/> instance on the right of the not equal sign.</param>
- /// <returns><c>true</c> if the instances are not equal; <c>false</c> otherwise.</returns>
- public static bool operator !=(Rectangle a, Rectangle b)
- {
- return !(a == b);
- }
- #endregion
- #region Public Methods
-
- /// <summary>
- /// Gets whether or not the provided coordinates lie within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="x">The x coordinate of the point to check for containment.</param>
- /// <param name="y">The y coordinate of the point to check for containment.</param>
- /// <returns><c>true</c> if the provided coordinates lie inside this <see cref="Rectangle"/>; <c>false</c> otherwise.</returns>
- public bool Contains(int x, int y)
- {
- return ((((this.X <= x) && (x < (this.X + this.Width))) && (this.Y <= y)) && (y < (this.Y + this.Height)));
- }
- /// <summary>
- /// Gets whether or not the provided coordinates lie within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="x">The x coordinate of the point to check for containment.</param>
- /// <param name="y">The y coordinate of the point to check for containment.</param>
- /// <returns><c>true</c> if the provided coordinates lie inside this <see cref="Rectangle"/>; <c>false</c> otherwise.</returns>
- public bool Contains(float x, float y)
- {
- return ((((this.X <= x) && (x < (this.X + this.Width))) && (this.Y <= y)) && (y < (this.Y + this.Height)));
- }
-
- /// <summary>
- /// Gets whether or not the provided <see cref="Point"/> lies within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">The coordinates to check for inclusion in this <see cref="Rectangle"/>.</param>
- /// <returns><c>true</c> if the provided <see cref="Point"/> lies inside this <see cref="Rectangle"/>; <c>false</c> otherwise.</returns>
- 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)));
- }
- /// <summary>
- /// Gets whether or not the provided <see cref="Point"/> lies within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">The coordinates to check for inclusion in this <see cref="Rectangle"/>.</param>
- /// <param name="result"><c>true</c> if the provided <see cref="Point"/> lies inside this <see cref="Rectangle"/>; <c>false</c> otherwise. As an output parameter.</param>
- 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)));
- }
- /// <summary>
- /// Gets whether or not the provided <see cref="Vector2"/> lies within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">The coordinates to check for inclusion in this <see cref="Rectangle"/>.</param>
- /// <returns><c>true</c> if the provided <see cref="Vector2"/> lies inside this <see cref="Rectangle"/>; <c>false</c> otherwise.</returns>
- public bool Contains(Vector2 value)
- {
- return ((((this.X <= value.X) && (value.X < (this.X + this.Width))) && (this.Y <= value.Y)) && (value.Y < (this.Y + this.Height)));
- }
- /// <summary>
- /// Gets whether or not the provided <see cref="Vector2"/> lies within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">The coordinates to check for inclusion in this <see cref="Rectangle"/>.</param>
- /// <param name="result"><c>true</c> if the provided <see cref="Vector2"/> lies inside this <see cref="Rectangle"/>; <c>false</c> otherwise. As an output parameter.</param>
- public void Contains(ref Vector2 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)));
- }
- /// <summary>
- /// Gets whether or not the provided <see cref="Rectangle"/> lies within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">The <see cref="Rectangle"/> to check for inclusion in this <see cref="Rectangle"/>.</param>
- /// <returns><c>true</c> if the provided <see cref="Rectangle"/>'s bounds lie entirely inside this <see cref="Rectangle"/>; <c>false</c> otherwise.</returns>
- 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)));
- }
- /// <summary>
- /// Gets whether or not the provided <see cref="Rectangle"/> lies within the bounds of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">The <see cref="Rectangle"/> to check for inclusion in this <see cref="Rectangle"/>.</param>
- /// <param name="result"><c>true</c> if the provided <see cref="Rectangle"/>'s bounds lie entirely inside this <see cref="Rectangle"/>; <c>false</c> otherwise. As an output parameter.</param>
- public void Contains(ref Rectangle value,out bool result)
- {
- result = ((((this.X <= value.X) && ((value.X + value.Width) <= (this.X + this.Width))) && (this.Y <= value.Y)) && ((value.Y + value.Height) <= (this.Y + this.Height)));
- }
- /// <summary>
- /// Compares whether current instance is equal to specified <see cref="Object"/>.
- /// </summary>
- /// <param name="obj">The <see cref="Object"/> to compare.</param>
- /// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
- public override bool Equals(object obj)
- {
- return (obj is Rectangle) && this == ((Rectangle)obj);
- }
- /// <summary>
- /// Compares whether current instance is equal to specified <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="other">The <see cref="Rectangle"/> to compare.</param>
- /// <returns><c>true</c> if the instances are equal; <c>false</c> otherwise.</returns>
- public bool Equals(Rectangle other)
- {
- return this == other;
- }
- /// <summary>
- /// Gets the hash code of this <see cref="Rectangle"/>.
- /// </summary>
- /// <returns>Hash code of this <see cref="Rectangle"/>.</returns>
- public override int GetHashCode()
- {
- return (X ^ Y ^ Width ^ Height);
- }
- /// <summary>
- /// Adjusts the edges of this <see cref="Rectangle"/> by specified horizontal and vertical amounts.
- /// </summary>
- /// <param name="horizontalAmount">Value to adjust the left and right edges.</param>
- /// <param name="verticalAmount">Value to adjust the top and bottom edges.</param>
- public void Inflate(int horizontalAmount, int verticalAmount)
- {
- X -= horizontalAmount;
- Y -= verticalAmount;
- Width += horizontalAmount * 2;
- Height += verticalAmount * 2;
- }
- /// <summary>
- /// Adjusts the edges of this <see cref="Rectangle"/> by specified horizontal and vertical amounts.
- /// </summary>
- /// <param name="horizontalAmount">Value to adjust the left and right edges.</param>
- /// <param name="verticalAmount">Value to adjust the top and bottom edges.</param>
- public void Inflate(float horizontalAmount, float verticalAmount)
- {
- X -= (int)horizontalAmount;
- Y -= (int)verticalAmount;
- Width += (int)horizontalAmount * 2;
- Height += (int)verticalAmount * 2;
- }
- /// <summary>
- /// Gets whether or not a specified <see cref="Rectangle"/> intersects with this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">Other <see cref="Rectangle"/>.</param>
- /// <returns><c>true</c> if other <see cref="Rectangle"/> intersects with this <see cref="Rectangle"/>; <c>false</c> otherwise.</returns>
- public bool Intersects(Rectangle value)
- {
- return value.Left < Right &&
- Left < value.Right &&
- value.Top < Bottom &&
- Top < value.Bottom;
- }
- /// <summary>
- /// Gets whether or not a specified <see cref="Rectangle"/> intersects with this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="value">Other <see cref="Rectangle"/>.</param>
- /// <param name="result"><c>true</c> if other <see cref="Rectangle"/> intersects with this <see cref="Rectangle"/>; <c>false</c> otherwise. As an output parameter.</param>
- public void Intersects(ref Rectangle value, out bool result)
- {
- result = value.Left < Right &&
- Left < value.Right &&
- value.Top < Bottom &&
- Top < value.Bottom;
- }
- /// <summary>
- /// Creates a new <see cref="Rectangle"/> that contains overlapping region of two other rectangles.
- /// </summary>
- /// <param name="value1">The first <see cref="Rectangle"/>.</param>
- /// <param name="value2">The second <see cref="Rectangle"/>.</param>
- /// <returns>Overlapping region of the two rectangles.</returns>
- public static Rectangle Intersect(Rectangle value1, Rectangle value2)
- {
- Rectangle rectangle;
- Intersect(ref value1, ref value2, out rectangle);
- return rectangle;
- }
- /// <summary>
- /// Creates a new <see cref="Rectangle"/> that contains overlapping region of two other rectangles.
- /// </summary>
- /// <param name="value1">The first <see cref="Rectangle"/>.</param>
- /// <param name="value2">The second <see cref="Rectangle"/>.</param>
- /// <param name="result">Overlapping region of the two rectangles as an output parameter.</param>
- 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);
- }
- }
- /// <summary>
- /// Changes the <see cref="Location"/> of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="offsetX">The x coordinate to add to this <see cref="Rectangle"/>.</param>
- /// <param name="offsetY">The y coordinate to add to this <see cref="Rectangle"/>.</param>
- public void Offset(int offsetX, int offsetY)
- {
- X += offsetX;
- Y += offsetY;
- }
- /// <summary>
- /// Changes the <see cref="Location"/> of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="offsetX">The x coordinate to add to this <see cref="Rectangle"/>.</param>
- /// <param name="offsetY">The y coordinate to add to this <see cref="Rectangle"/>.</param>
- public void Offset(float offsetX, float offsetY)
- {
- X += (int)offsetX;
- Y += (int)offsetY;
- }
- /// <summary>
- /// Changes the <see cref="Location"/> of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="amount">The x and y components to add to this <see cref="Rectangle"/>.</param>
- public void Offset(Point amount)
- {
- X += amount.X;
- Y += amount.Y;
- }
- /// <summary>
- /// Changes the <see cref="Location"/> of this <see cref="Rectangle"/>.
- /// </summary>
- /// <param name="amount">The x and y components to add to this <see cref="Rectangle"/>.</param>
- public void Offset(Vector2 amount)
- {
- X += (int)amount.X;
- Y += (int)amount.Y;
- }
- /// <summary>
- /// Returns a <see cref="String"/> representation of this <see cref="Rectangle"/> in the format:
- /// {X:[<see cref="X"/>] Y:[<see cref="Y"/>] Width:[<see cref="Width"/>] Height:[<see cref="Height"/>]}
- /// </summary>
- /// <returns><see cref="String"/> representation of this <see cref="Rectangle"/>.</returns>
- public override string ToString()
- {
- return "{X:" + X + " Y:" + Y + " Width:" + Width + " Height:" + Height + "}";
- }
- /// <summary>
- /// Creates a new <see cref="Rectangle"/> that completely contains two other rectangles.
- /// </summary>
- /// <param name="value1">The first <see cref="Rectangle"/>.</param>
- /// <param name="value2">The second <see cref="Rectangle"/>.</param>
- /// <returns>The union of the two rectangles.</returns>
- 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);
- }
- /// <summary>
- /// Creates a new <see cref="Rectangle"/> that completely contains two other rectangles.
- /// </summary>
- /// <param name="value1">The first <see cref="Rectangle"/>.</param>
- /// <param name="value2">The second <see cref="Rectangle"/>.</param>
- /// <param name="result">The union of the two rectangles as an output parameter.</param>
- 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
- }
- }
|