using System; using Microsoft.Xna.Framework; namespace MonoGame.Extended { /// /// Base class for shapes. /// /// /// Created to allow checking intersection between shapes of different types. /// public interface IShapeF { /// /// Gets or sets the position of the shape. /// Vector2 Position { get; set; } /// /// Gets escribed rectangle, which lying outside the shape /// RectangleF BoundingRectangle { get; } } /// /// Class that implements methods for shared methods. /// public static class Shape { /// /// Check if two shapes intersect. /// /// The first shape. /// The second shape. /// True if the two shapes intersect. public static bool Intersects(this IShapeF a, IShapeF b) { return a switch { CircleF circleA when b is CircleF circleB => circleA.Intersects(circleB), CircleF circleA when b is RectangleF rectangleB => circleA.Intersects(rectangleB), CircleF circleA when b is OrientedRectangle orientedRectangleB => Intersects(circleA, orientedRectangleB), RectangleF rectangleA when b is CircleF circleB => Intersects(circleB, rectangleA), RectangleF rectangleA when b is RectangleF rectangleB => rectangleA.Intersects(rectangleB), RectangleF rectangleA when b is OrientedRectangle orientedRectangleB => Intersects(rectangleA, orientedRectangleB).Intersects, OrientedRectangle orientedRectangleA when b is CircleF circleB => Intersects(circleB, orientedRectangleA), OrientedRectangle orientedRectangleA when b is RectangleF rectangleB => Intersects(rectangleB, orientedRectangleA).Intersects, OrientedRectangle orientedRectangleA when b is OrientedRectangle orientedRectangleB => OrientedRectangle.Intersects(orientedRectangleA, orientedRectangleB).Intersects, _ => throw new ArgumentOutOfRangeException(nameof(a)) }; } /// /// Checks if a circle and rectangle intersect. /// /// Circle to check intersection with rectangle. /// Rectangle to check intersection with circle. /// True if the circle and rectangle intersect. public static bool Intersects(CircleF circle, RectangleF rectangle) { var closestPoint = rectangle.ClosestPointTo(circle.Center); return circle.Contains(closestPoint); } /// /// Checks whether a and intersects. /// /// to use in intersection test. /// to use in intersection test. /// True if the circle and oriented bounded rectangle intersects, otherwise false. public static bool Intersects(CircleF circle, OrientedRectangle orientedRectangle) { var rotation = Matrix3x2.CreateRotationZ(orientedRectangle.Orientation.Rotation); var circleCenterInRectangleSpace = rotation.Transform(circle.Center - orientedRectangle.Center); var circleInRectangleSpace = new CircleF(circleCenterInRectangleSpace, circle.Radius); var boundingRectangle = new BoundingRectangle(new Vector2(), orientedRectangle.Radii); return circleInRectangleSpace.Intersects(boundingRectangle); } /// /// Checks if a and intersects. /// /// /// /// True if objects are intersecting, otherwise false. public static (bool Intersects, Vector2 MinimumTranslationVector) Intersects(RectangleF rectangleF, OrientedRectangle orientedRectangle) { return OrientedRectangle.Intersects(orientedRectangle, (OrientedRectangle)rectangleF); } } }