| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- using System;
- using Microsoft.Xna.Framework;
- namespace MonoGame.Extended;
- /// <summary>
- /// Provides extension methods for the <see cref="Rectangle"/> structure.
- /// </summary>
- public static class RectangleExtensions
- {
- /// <summary>
- /// Gets the corners of the rectangle in a clockwise direction starting at the top left.
- /// </summary>
- /// <param name="rectangle">The rectangle to get the corners of.</param>
- /// <returns>An array of <see cref="Point"/> elements representing the corners of the rectangle.</returns>
- public static Point[] GetCorners(this Rectangle rectangle)
- {
- var corners = new Point[4];
- corners[0] = new Point(rectangle.Left, rectangle.Top);
- corners[1] = new Point(rectangle.Right, rectangle.Top);
- corners[2] = new Point(rectangle.Right, rectangle.Bottom);
- corners[3] = new Point(rectangle.Left, rectangle.Bottom);
- return corners;
- }
- /// <summary>
- /// Converts the specified <see cref="Rectangle"/> to a <see cref="RectangleF"/>.
- /// </summary>
- /// <param name="rectangle">The rectangle to convert.</param>
- /// <returns>The converted <see cref="RectangleF"/>.</returns>
- public static RectangleF ToRectangleF(this Rectangle rectangle)
- {
- return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- }
- /// <summary>
- /// Clips the specified rectangle against the specified clipping rectangle.
- /// </summary>
- /// <param name="rectangle">The rectangle to clip.</param>
- /// <param name="clippingRectangle">The rectangle to clip against.</param>
- /// <returns>The clipped rectangle, or <see cref="Rectangle.Empty"/> if the rectangles do not intersect.</returns>
- public static Rectangle Clip(this Rectangle rectangle, Rectangle clippingRectangle)
- {
- int left = Math.Max(rectangle.Left, clippingRectangle.Left);
- int top = Math.Max(rectangle.Top, clippingRectangle.Top);
- int right = Math.Min(rectangle.Right, clippingRectangle.Right);
- int bottom = Math.Min(rectangle.Bottom, clippingRectangle.Bottom);
- int width = right - left;
- int height = bottom - top;
- if (width <= 0 || height <= 0)
- return Rectangle.Empty;
- return new Rectangle(left, top, width, height);
- }
- /// <summary>
- /// Gets a rectangle that is relative to the specified source rectangle, with the specified offsets and dimensions.
- /// </summary>
- /// <param name="source">The source rectangle.</param>
- /// <param name="x">The x-coordinate of the relative rectangle, relative to the source rectangle.</param>
- /// <param name="y">The y-coordinate of the relative rectangle, relative to the source rectangle.</param>
- /// <param name="width">The width, in pixels, of the relative rectangle.</param>
- /// <param name="height">The height, in pixels, of the relative rectangle.</param>
- /// <returns>The relative rectangle, clipped to the source rectangle.</returns>
- public static Rectangle GetRelativeRectangle(this Rectangle source, int x, int y, int width, int height)
- {
- int absoluteX = source.X + x;
- int absoluteY = source.Y + y;
- Rectangle relative;
- relative.X = (int)MathHelper.Clamp(absoluteX, source.Left, source.Right);
- relative.Y = (int)MathHelper.Clamp(absoluteY, source.Top, source.Bottom);
- relative.Width = Math.Max(Math.Min(absoluteX + width, source.Right) - relative.X, 0);
- relative.Height = Math.Max(Math.Min(absoluteY + height, source.Bottom) - relative.Y, 0);
- return relative;
- }
- #if FNA
- // MomoGame compatibility layer
- /// <summary>
- /// Deconstruction method for Rectangle.
- /// </summary>
- public static void Deconstruct(this Rectangle rectangle, out int x, out int y, out int width, out int height)
- {
- x = rectangle.X;
- y = rectangle.Y;
- width = rectangle.Width;
- height = rectangle.Height;
- }
- #endif
- /// <summary>
- /// Normalizes the specified <see cref="Rectangle"/> so that the <see cref="Rectangle.Width"/> and
- /// <see cref="Rectangle.Height"/> are positive without changing the location of the rectangle.
- /// </summary>
- /// <param name="rectangle">The <see cref="Rectangle"/> to normalize.</param>
- /// <returns>A <see cref="Rectangle"/> with positive width and height.</returns>
- public static Rectangle Normalize(Rectangle rectangle)
- {
- if (rectangle.Width < 0)
- {
- rectangle.X += rectangle.Width;
- rectangle.Width = -rectangle.Width;
- }
- if (rectangle.Height < 0)
- {
- rectangle.Y += rectangle.Height;
- rectangle.Height = -rectangle.Height;
- }
- return rectangle;
- }
- /// <summary>
- /// Normalizes a <see cref="Rectangle"/> so that the <see cref="Rectangle.Width"/> and
- /// <see cref="Rectangle.Height"/> are positive without changing the location of the rectangle.
- /// </summary>
- /// <param name="rectangle">The source <see cref="Rectangle"/>.</param>
- /// <param name="result">
- /// When this method returns, contains the a normalized <see cref="Rectangle"/> with positive width and height.
- /// </param>
- public static void Normalize(ref this Rectangle rectangle, out Rectangle result)
- {
- result.X = rectangle.X;
- result.Width = rectangle.Width;
- if (result.Width < 0)
- {
- result.X += result.Width;
- result.Width = -result.Width;
- }
- result.Y = rectangle.Y;
- result.Height = rectangle.Height;
- if (result.Height < 0)
- {
- result.Y += result.Height;
- result.Height = -result.Height;
- }
- }
- }
|