94 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Engine.Core;
 | 
						|
 | 
						|
namespace Engine.Physics2D;
 | 
						|
 | 
						|
public static class Physics2D
 | 
						|
{
 | 
						|
    public static bool Overlaps(this Shape2D shape, Vector2D point) => Overlaps(shape, point, out float _);
 | 
						|
    public static bool Overlaps(this Shape2D shape, Vector2D point, out float depth)
 | 
						|
    {
 | 
						|
        depth = float.MaxValue;
 | 
						|
        System.Collections.Generic.IReadOnlyList<Vector2D> vertices = shape.Vertices;
 | 
						|
        int count = vertices.Count;
 | 
						|
 | 
						|
        for (int indexProjection = 0; indexProjection < count; indexProjection++)
 | 
						|
        {
 | 
						|
            Vector2D projectionVector = vertices[indexProjection].FromTo(vertices[(indexProjection + 1) % count]).Perpendicular().Normalized;
 | 
						|
 | 
						|
            Projection1D shapeProjection = shape.ToProjection(projectionVector);
 | 
						|
            float projectedPoint = point.Dot(projectionVector);
 | 
						|
 | 
						|
            if (shapeProjection.Max < projectedPoint || shapeProjection.Min > projectedPoint)
 | 
						|
                return false;
 | 
						|
 | 
						|
            depth = Math.Min(depth, Math.Abs(Math.AbsMin(shapeProjection.Max - projectedPoint, shapeProjection.Min - projectedPoint)));
 | 
						|
        }
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    public static bool Overlaps(this Circle left, Circle right)
 | 
						|
    {
 | 
						|
        float distanceSquared = left.Center.FromTo(right.Center).LengthSquared();
 | 
						|
        float radiusSumSquared = left.RadiusSquared + right.RadiusSquared;
 | 
						|
 | 
						|
        return distanceSquared < radiusSumSquared;
 | 
						|
    }
 | 
						|
 | 
						|
    public static bool Overlaps(this Circle left, Circle right, out Vector2D normal, out float depth)
 | 
						|
    {
 | 
						|
        Vector2D distanceVector = left.Center.FromTo(right.Center);
 | 
						|
        float distanceSquared = distanceVector.LengthSquared();
 | 
						|
        float radiusSumSquared = left.RadiusSquared + right.RadiusSquared;
 | 
						|
        bool isOverlapping = distanceSquared < radiusSumSquared;
 | 
						|
 | 
						|
        depth = 0f;
 | 
						|
        normal = distanceVector.Normalized;
 | 
						|
 | 
						|
        if (isOverlapping)
 | 
						|
            depth = Math.Sqrt(radiusSumSquared - distanceSquared);
 | 
						|
 | 
						|
        return isOverlapping;
 | 
						|
    }
 | 
						|
 | 
						|
    public static bool Overlaps(this Circle circle, Vector2D point) => circle.Center.FromTo(point).LengthSquared() <= circle.RadiusSquared;
 | 
						|
    public static bool Overlaps(this Circle circle, Vector2D point, out Vector2D normal, out float depth)
 | 
						|
    {
 | 
						|
        Vector2D distanceVector = circle.Center.FromTo(point);
 | 
						|
        float distanceSquared = distanceVector.LengthSquared();
 | 
						|
        float radiusSquared = circle.RadiusSquared;
 | 
						|
        bool isOverlapping = distanceSquared < radiusSquared;
 | 
						|
 | 
						|
        depth = 0f;
 | 
						|
        normal = distanceVector.Normalized;
 | 
						|
 | 
						|
        if (isOverlapping)
 | 
						|
            depth = Math.Sqrt(radiusSquared - distanceSquared);
 | 
						|
 | 
						|
        return isOverlapping;
 | 
						|
    }
 | 
						|
 | 
						|
    public static bool Overlaps(this AABB2D aabb, Vector2D point)
 | 
						|
        => point.X >= aabb.LowerBoundary.X && point.X <= aabb.UpperBoundary.X &&
 | 
						|
            point.Y >= aabb.LowerBoundary.Y && point.Y <= aabb.UpperBoundary.Y;
 | 
						|
 | 
						|
    public static bool Overlaps(this AABB2D left, AABB2D right)
 | 
						|
        => left.LowerBoundary.X <= right.UpperBoundary.X && left.UpperBoundary.X >= right.LowerBoundary.X &&
 | 
						|
            left.LowerBoundary.Y <= right.UpperBoundary.Y && left.UpperBoundary.Y >= right.LowerBoundary.Y;
 | 
						|
 | 
						|
    public static bool Overlaps(Triangle triangle, Vector2D point)
 | 
						|
    {
 | 
						|
        float originalTriangleArea = triangle.Area;
 | 
						|
 | 
						|
        float pointTriangleArea1 = new Triangle(point, triangle.B, triangle.C).Area;
 | 
						|
        float pointTriangleArea2 = new Triangle(triangle.A, point, triangle.C).Area;
 | 
						|
        float pointTriangleArea3 = new Triangle(triangle.A, triangle.B, point).Area;
 | 
						|
 | 
						|
        float pointTriangleAreasSum = pointTriangleArea1 + pointTriangleArea2 + pointTriangleArea3;
 | 
						|
 | 
						|
        return originalTriangleArea.ApproximatelyEquals(pointTriangleAreasSum, float.Epsilon * 3f);
 | 
						|
    }
 | 
						|
 | 
						|
    public static bool LaysOn(this Vector2D point, Line2D line) => Line2D.Intersects(line, point);
 | 
						|
}
 |