Exemple #1
1
        // Check if polygon A is going to collide with polygon B for the given velocity
        public SvgCollision.PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity)
        {
            SvgCollision.PolygonCollisionResult result = new SvgCollision.PolygonCollisionResult();
            result.IsIntersecting = 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 polygons
            for (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 axis
                float 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 intersecting
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.IsIntersecting = false;

                // ===== 2. Now find if the polygons *will* intersect =====
                // Project the velocity on the current axis
                float velocityProjection = axis.DotProduct(velocity);

                // Get the projection of polygon A during the movement
                if (velocityProjection < 0) {
                    minA += velocityProjection;
                } else {
                    maxA += velocityProjection;
                }

                // Do the same test as above for the new projection
                intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.WillIntersect = false;

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!result.IsIntersecting && !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.
            // First moves the polygons by their velocity
            // then move polygonA by MinimumTranslationVector.
            if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance;

            return result;
        }
Exemple #2
0
        /// <summary>
        /// Test if two polygons collide by testing each line segment in polygon 1 against each line segment in polygon 2.
        /// Returns a parially filled SvgCollision.PolygonCollisionResult.
        /// </summary>
        /// <param name="ptsA">Polygon 1 point array</param>
        /// <param name="ptsB">Polygon 2 point array</param> 
        /// <returns></returns>
        public static SvgCollision.PolygonCollisionResult PolygonCollision(PointF[] ptsA, PointF[] ptsB)
        {
            SvgCollision.PolygonCollisionResult result = new SvgCollision.PolygonCollisionResult();
            result.LineIntersectingPoints = new List<PointF>();
            PointF previousA = new PointF();
            PointF previousB = new PointF();

               foreach (PointF ptsa in ptsA)
               {
               if (!(previousA.IsEmpty))
               {
                   foreach (PointF ptsb in ptsB)
                   {
                       if (!(previousB.IsEmpty))
                       {
                           if (ptsa != ptsb && previousA != previousB)
                           {
                               bool blurp = DoLinesIntersect(previousA, ptsa, previousB, ptsb);
                               if (blurp)
                               {
                                   result.IsIntersecting = true;
                                   result.OnPath = true;
                                   PointF intersection;
                                   LineIntersectionPoint(ptsa, previousA, ptsb, previousB, out intersection);
                                   result.LineIntersectingPoints.Add(intersection);
                               }
                           }
                       }
                       previousB = ptsb;
                   }
                   previousB = new PointF();
               }
               previousA = ptsa;
               }
            return result;
        }