diff --git a/Engine.Core/Primitives/Line2D.cs b/Engine.Core/Primitives/Line2D.cs index c89093a..7b9a4cf 100644 --- a/Engine.Core/Primitives/Line2D.cs +++ b/Engine.Core/Primitives/Line2D.cs @@ -167,17 +167,14 @@ public readonly struct Line2D(Vector2D from, Vector2D to) /// public static Vector2D ClosestPointTo(Line2D line, Vector2D point) { - Vector2D edgeVector = line.From.FromTo(line.To); - Vector2D pointVector = point - line.From; + Vector2D lineRelativeVector = line.From.FromTo(line.To); - float t = (pointVector.X * edgeVector.X + pointVector.Y * edgeVector.Y) / (edgeVector.X * edgeVector.X + edgeVector.Y * edgeVector.Y); + Vector2D lineDirection = lineRelativeVector.Normalized; + Vector2D pointVector = line.From.FromTo(point); - t = Math.Max(0, Math.Min(1, t)); + float dot = lineDirection.Dot(pointVector).Clamp(0f, lineRelativeVector.Magnitude); - float closestX = line.From.X + t * edgeVector.X; - float closestY = line.From.Y + t * edgeVector.Y; - - return new Vector2D((float)closestX, (float)closestY); + return lineDirection * dot; } /// @@ -214,6 +211,9 @@ public static class Line2DExtensions /// public static bool Intersects(this Line2D left, Line2D right, [NotNullWhen(returnValue: true)] out Vector2D? point) => Line2D.Intersects(left, right, out point); + /// + public static Vector2D ClosestPointTo(this Line2D line, Vector2D point) => Line2D.ClosestPointTo(line, point); + /// public static bool ApproximatelyEquals(this Line2D left, Line2D right, float epsilon = float.Epsilon) => Line2D.ApproximatelyEquals(left, right, epsilon); }