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);
}
}
}