RectangleF.Extensions.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. using Microsoft.Xna.Framework;
  3. namespace MonoGame.Extended;
  4. /// <summary>
  5. /// Provides extension methods for the <see cref="RectangleF"/> structure.
  6. /// </summary>
  7. public static class RectangleFExtensions
  8. {
  9. /// <summary>
  10. /// Gets the corners of the rectangle in a clockwise direction starting at the top left.
  11. /// </summary>
  12. /// <param name="rectangle">The rectangle to get the corners of.</param>
  13. /// <returns>An array of <see cref="Vector2"/> elements representing the corners of the rectangle.</returns>
  14. public static Vector2[] GetCorners(this RectangleF rectangle)
  15. {
  16. var corners = new Vector2[4];
  17. corners[0] = new Vector2(rectangle.Left, rectangle.Top);
  18. corners[1] = new Vector2(rectangle.Right, rectangle.Top);
  19. corners[2] = new Vector2(rectangle.Right, rectangle.Bottom);
  20. corners[3] = new Vector2(rectangle.Left, rectangle.Bottom);
  21. return corners;
  22. }
  23. /// <summary>
  24. /// Converts the specified <see cref="RectangleF"/> to a <see cref="Rectangle"/>.
  25. /// </summary>
  26. /// <param name="rectangle">The rectangle to convert.</param>
  27. /// <returns>The converted <see cref="Rectangle"/>.</returns>
  28. public static Rectangle ToRectangle(this RectangleF rectangle)
  29. {
  30. return new Rectangle((int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height);
  31. }
  32. /// <summary>
  33. /// Clips the specified rectangle against the specified clipping rectangle.
  34. /// </summary>
  35. /// <param name="rectangle">The rectangle to clip.</param>
  36. /// <param name="clippingRectangle">The rectangle to clip against.</param>
  37. /// <returns>The clipped rectangle, or <see cref="RectangleF.Empty"/> if the rectangles do not intersect.</returns>
  38. public static RectangleF Clip(this RectangleF rectangle, RectangleF clippingRectangle)
  39. {
  40. var clip = clippingRectangle;
  41. rectangle.X = clip.X > rectangle.X ? clip.X : rectangle.X;
  42. rectangle.Y = clip.Y > rectangle.Y ? clip.Y : rectangle.Y;
  43. rectangle.Width = rectangle.Right > clip.Right ? clip.Right - rectangle.X : rectangle.Width;
  44. rectangle.Height = rectangle.Bottom > clip.Bottom ? clip.Bottom - rectangle.Y : rectangle.Height;
  45. if (rectangle.Width <= 0 || rectangle.Height <= 0)
  46. return RectangleF.Empty;
  47. return rectangle;
  48. }
  49. /// <summary>
  50. /// Gets a rectangle that is relative to the specified source rectangle, with the specified offsets and dimensions.
  51. /// </summary>
  52. /// <param name="source">The source rectangle.</param>
  53. /// <param name="x">The x-coordinate of the relative rectangle, relative to the source rectangle.</param>
  54. /// <param name="y">The y-coordinate of the relative rectangle, relative to the source rectangle.</param>
  55. /// <param name="width">The width, in pixels, of the relative rectangle.</param>
  56. /// <param name="height">The height, in pixels, of the relative rectangle.</param>
  57. /// <returns>The relative rectangle, clipped to the source rectangle.</returns>
  58. public static RectangleF GetRelativeRectangle(this RectangleF source, float x, float y, float width, float height)
  59. {
  60. float absoluteX = source.X + x;
  61. float absoluteY = source.Y + y;
  62. RectangleF relative;
  63. relative.X = MathHelper.Clamp(absoluteX, source.Left, source.Right);
  64. relative.Y = MathHelper.Clamp(absoluteY, source.Top, source.Bottom);
  65. relative.Width = Math.Max(Math.Min(absoluteX + width, source.Right) - relative.X, 0);
  66. relative.Height = Math.Max(Math.Min(absoluteY + height, source.Bottom) - relative.Y, 0);
  67. return relative;
  68. }
  69. }