多边形碰撞算法

原文地址:http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection

==================================================

// Check if polygon A is going to collide with polygon B.// The last parameter is the *relative* velocity // of the polygons (i.e. velocityA - velocityB)public PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity) { PolygonCollisionResult result = new PolygonCollisionResult(); result.Intersect = true; result.WillIntersect = true; int edgeCountA = polygonA.Edges.Count; int edgeCountB = polygonB.Edges.Count; float minIntervalDistance = float.PositiveInfinity; Vector translationAxis = new Vector(); Vector edge; // Loop through all the edges of both polygonsfor (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++) { if (edgeIndex < edgeCountA) { edge = polygonA.Edges[edgeIndex]; } else { edge = polygonB.Edges[edgeIndex - edgeCountA]; } // ===== 1. Find if the polygons are currently intersecting =====// Find the axis perpendicular to the current edge Vector axis = new Vector(-edge.Y, edge.X); axis.Normalize(); // Find the projection of the polygon on the current axisfloat minA = 0; float minB = 0; float maxA = 0; float maxB = 0; ProjectPolygon(axis, polygonA, ref minA, ref maxA); ProjectPolygon(axis, polygonB, ref minB, ref maxB); // Check if the polygon projections are currentlty intersectingif (IntervalDistance(minA, maxA, minB, maxB) > 0)\ result.Intersect = false; // ===== 2. Now find if the polygons *will* intersect =====// Project the velocity on the current axisfloat velocityProjection = axis.DotProduct(velocity); // Get the projection of polygon A during the movementif (velocityProjection < 0) { minA += velocityProjection; } else { maxA += velocityProjection; } // Do the same test as above for the new projectionfloat intervalDistance = IntervalDistance(minA, maxA, minB, maxB); if (intervalDistance > 0) result.WillIntersect = false; // If the polygons are not intersecting and won't intersect, exit the loopif (!result.Intersect && !result.WillIntersect) break; // 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 intervalDistance = Math.Abs(intervalDistance); if (intervalDistance < minIntervalDistance) { minIntervalDistance = intervalDistance; translationAxis = axis; Vector d = polygonA.Center - polygonB.Center; if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis; } } // The minimum translation vector// can be used to push the polygons appart.if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance; return result;}==========================================================================Vector polygonATranslation = new Vector();PolygonCollisionResult r = PolygonCollision(polygonA, polygonB, velocity);if (r.WillIntersect) { // Move the polygon by its velocity, then move// the polygons appart using the Minimum Translation Vector polygonATranslation = velocity + r.MinimumTranslationVector;} else { // Just move the polygon by its velocity polygonATranslation = velocity;}polygonA.Offset(polygonATranslation);

posted on 2012-04-02 13:47  真阿当  阅读(284)  评论(0编辑  收藏  举报