From dbf04dbbc8f11c587a95997e13a65b7af514d0f7 Mon Sep 17 00:00:00 2001 From: derped Date: Tue, 3 Sep 2024 12:50:31 +0200 Subject: [PATCH] Implement circle projection and fix circle mtv. --- shape.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/shape.go b/shape.go index 75d3e61..a4840ad 100755 --- a/shape.go +++ b/shape.go @@ -687,6 +687,12 @@ func (cp *ConvexPolygon) calculateMTV(contactSet *ContactSet, otherShape IShape) smallest = Vector{center.X - verts[0].X, center.Y - verts[0].Y} smallest = smallest.Unit().Scale(smallest.Magnitude() - other.radius) + // If the direction from target to source points opposite to the separation, invert the separation vector + // and set its magnitude to the diameter minus the original magnitude + if cp.Center().Sub(other.position).Dot(smallest.Unit()) < 0 { + smallest = smallest.Unit().Scale(-other.radius * 2 + smallest.Magnitude()) + } + } delta.X = smallest.X @@ -835,6 +841,21 @@ func (circle *Circle) Bounds() (Vector, Vector) { return Vector{circle.position.X - circle.radius, circle.position.Y - circle.radius}, Vector{circle.position.X + circle.radius, circle.position.Y + circle.radius} } +func (circle *Circle) Project(axis Vector) Projection { + axis = axis.Unit() + projectedCenter := axis.Dot(circle.position) + projectedRadius := axis.Magnitude() * circle.radius * circle.scale + + min := projectedCenter - projectedRadius + max := projectedCenter + projectedRadius + + if min > max { + min, max = max, min + } + + return Projection{min, max} +} + // Intersection tests to see if a Circle intersects with the other given Shape. dx and dy are delta movement variables indicating // movement to be applied before the intersection check (thereby allowing you to see if a Shape would collide with another if it // were in a different relative location). If an Intersection is found, a ContactSet will be returned, giving information regarding