From b931abb73542454902825d1ef227db9cba1b8bcb Mon Sep 17 00:00:00 2001 From: Syntriax Date: Tue, 6 Feb 2024 12:06:13 +0300 Subject: [PATCH] feat: Shape to Vector2D Overlap --- Engine.Physics2D/Physics2D.cs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Engine.Physics2D/Physics2D.cs b/Engine.Physics2D/Physics2D.cs index a9f722b..5cc4f7a 100644 --- a/Engine.Physics2D/Physics2D.cs +++ b/Engine.Physics2D/Physics2D.cs @@ -1,13 +1,33 @@ -using System; - using Syntriax.Engine.Core; -using Syntriax.Engine.Physics2D; using Syntriax.Engine.Physics2D.Primitives; namespace Engine.Physics2D; public static partial class Physics2D { + public static bool Overlaps(this Shape shape, Vector2D point) => Overlaps(shape, point, out var _); + public static bool Overlaps(this Shape shape, Vector2D point, out float depth) + { + depth = float.MaxValue; + var 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; + + Projection 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(); @@ -27,7 +47,7 @@ public static partial class Physics2D normal = distanceVector.Normalized; if (isOverlapping) - depth = MathF.Sqrt(radiusSumSquared - distanceSquared); + depth = Math.Sqrt(radiusSumSquared - distanceSquared); return isOverlapping; } @@ -44,7 +64,7 @@ public static partial class Physics2D normal = distanceVector.Normalized; if (isOverlapping) - depth = MathF.Sqrt(radiusSquared - distanceSquared); + depth = Math.Sqrt(radiusSquared - distanceSquared); return isOverlapping; }