public static bool CircleToPolygon(Circle circle, Polygon polygon, out CollisionResult result) { result = new CollisionResult(); // circle position in the polygons coordinates var poly2Circle = circle.position - polygon.position; // first, we need to find the closest distance from the circle to the polygon float distanceSquared; var closestPoint = Polygon.GetClosestPointOnPolygonToPoint(polygon.Points, poly2Circle, out distanceSquared, out result.Normal); // make sure the squared distance is less than our radius squared else we are not colliding. Note that if the Circle is fully // contained in the Polygon the distance could be larger than the radius. Because of that we also make sure the circle position // is not inside the poly. var circleCenterInsidePoly = polygon.ContainsPoint(circle.position); if (distanceSquared > circle.Radius * circle.Radius && !circleCenterInsidePoly) { return(false); } // figure out the mtv. We have to be careful to deal with circles fully contained in the polygon or with their center contained. Vector2 mtv; if (circleCenterInsidePoly) { mtv = result.Normal * (Mathf.Sqrt(distanceSquared) - circle.Radius); } else { // if we have no distance that means the circle center is on the polygon edge. Move it only by its radius if (distanceSquared == 0) { mtv = result.Normal * circle.Radius; } else { var distance = Mathf.Sqrt(distanceSquared); mtv = -(poly2Circle - closestPoint) * ((circle.Radius - distance) / distance); } } result.MinimumTranslationVector = mtv; result.Point = closestPoint + polygon.position; return(true); }
public static bool PointToPoly(Vector2 point, Polygon poly, out CollisionResult result) { result = new CollisionResult(); if (poly.ContainsPoint(point)) { float distanceSquared; var closestPoint = Polygon.GetClosestPointOnPolygonToPoint(poly.Points, point - poly.position, out distanceSquared, out result.Normal); result.MinimumTranslationVector = result.Normal * Mathf.Sqrt(distanceSquared); result.Point = closestPoint + poly.position; return(true); } return(false); }