public static bool PointToCircle(Vector2 point, Circle circle, out CollisionResult result) { result = new CollisionResult(); // avoid the square root until we actually need it var distanceSquared = Vector2.DistanceSquared(point, circle.Position); var sumOfRadii = 1 + circle.Radius; var collided = distanceSquared < sumOfRadii * sumOfRadii; if (collided) { result.Normal = Vector2.Normalize(point - circle.Position); var depth = sumOfRadii - MathF.Sqrt(distanceSquared); result.MinimumTranslationVector = -depth * result.Normal; result.Point = circle.Position + result.Normal * circle.Radius; return(true); } return(false); }
public static bool CircleToCircle(Circle first, Circle second, out CollisionResult result) { result = new CollisionResult(); // avoid the square root until we actually need it var distanceSquared = Vector2.DistanceSquared(first.Position, second.Position); var sumOfRadii = first.Radius + second.Radius; var collided = distanceSquared < sumOfRadii * sumOfRadii; if (collided) { result.Normal = Vector2.Normalize(first.Position - second.Position); var depth = sumOfRadii - MathF.Sqrt(distanceSquared); result.MinimumTranslationVector = -depth * result.Normal; result.Point = second.Position + result.Normal * second.Radius; return(true); } return(false); }
public static bool CircleToBox(Circle circle, Box box, out CollisionResult result) { result = new CollisionResult(); var closestPointOnBounds = box.BoundingBox.GetClosestPointOnBorderToPoint(circle.Position, out result.Normal); // deal with circles whos center is in the box first since its cheaper to see if we are contained if (box.ContainsPoint(circle.Position)) { result.Point = closestPointOnBounds; // calculate mtv. Find the safe, non-collided position and get the mtv from that. var safePlace = closestPointOnBounds + result.Normal * circle.Radius; result.MinimumTranslationVector = circle.Position - safePlace; return(true); } float sqrDistance = Vector2.DistanceSquared(closestPointOnBounds, circle.Position); // see if the point on the box is less than radius from the circle if (sqrDistance == 0) { result.MinimumTranslationVector = result.Normal * circle.Radius; } else if (sqrDistance <= circle.Radius * circle.Radius) { result.Normal = circle.Position - closestPointOnBounds; var depth = result.Normal.Length() - circle.Radius; result.Point = closestPointOnBounds; Vector2Ext.Normalize(ref result.Normal); result.MinimumTranslationVector = depth * result.Normal; return(true); } return(false); }
public static bool BoxToBox(Box first, Box second, out CollisionResult result) { result = new CollisionResult(); var diff = MinkowskiDifference(first, second); if (diff.Contains(0f, 0f)) { result.MinimumTranslationVector = diff.GetClosestPointOnBoundsToOrigin(); if (result.MinimumTranslationVector == Vector2.Zero) { return(false); } result.Normal = -result.MinimumTranslationVector; result.Normal.Normalize(); return(true); } return(false); }
public static bool PolygonToPolygon(Polygon first, Polygon second, out CollisionResult result) { result = new CollisionResult(); var isIntersecting = true; var firstEdges = first.EdgeNormals; var secondEdges = second.EdgeNormals; var minIntervalDistance = float.PositiveInfinity; var translationAxis = new Vector2(); var polygonOffset = first.Position - second.Position; Vector2 axis; // Loop through all the edges of both polygons for (var edgeIndex = 0; edgeIndex < firstEdges.Length + secondEdges.Length; edgeIndex++) { // 1. Find if the polygons are currently intersecting // Polygons have the normalized axis perpendicular to the current edge cached for us if (edgeIndex < firstEdges.Length) { axis = firstEdges[edgeIndex]; } else { axis = secondEdges[edgeIndex - firstEdges.Length]; } // Find the projection of the polygon on the current axis float minA = 0; float minB = 0; float maxA = 0; float maxB = 0; var intervalDist = 0f; GetInterval(axis, first, ref minA, ref maxA); GetInterval(axis, second, ref minB, ref maxB); // get our interval to be space of the second Polygon. Offset by the difference in Position projected on the axis. Vector2.Dot(ref polygonOffset, ref axis, out float relativeIntervalOffset); minA += relativeIntervalOffset; maxA += relativeIntervalOffset; // check if the polygon projections are currentlty intersecting intervalDist = IntervalDistance(minA, maxA, minB, maxB); if (intervalDist > 0) { isIntersecting = false; } // If the polygons are not intersecting and won't intersect, exit the loop if (!isIntersecting) { return(false); } // Check if the current interval distance is the minimum one. If so store the interval distance and the current distance. // This will be used to calculate the minimum translation vector intervalDist = System.Math.Abs(intervalDist); if (intervalDist < minIntervalDistance) { // If the intervalDist == 0, the two objects are just touching each other, not colliding. //Todo: Fully test. if (intervalDist == 0) { return(false); } minIntervalDistance = intervalDist; translationAxis = axis; if (Vector2.Dot(translationAxis, polygonOffset) < 0) { translationAxis = -translationAxis; } } } // The minimum translation vector can be used to push the polygons appart. result.Normal = translationAxis; result.MinimumTranslationVector = -translationAxis * minIntervalDistance; return(true); }
public override bool CollidesWithShape(Shape other, out CollisionResult result) { result = default(CollisionResult); return(false); }
public override bool CollidesWithPoint(Vector2 point, out CollisionResult result) { result = default(CollisionResult); return(false); }