示例#1
1
 public static void RenderPolygone(SpriteBatch spriteBatch, Texture2D texture, Polygon polygon, int lineThickness, Color color)
 {
     for (int i = 0; i < polygon.Points.Count; ++i)
     {
         RenderLine(spriteBatch, texture, polygon.Points[i], polygon.Edges[i], 1, lineThickness, color);
     }
 }
 // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval
 private static void ProjectPolygon(Vector2 axis, Polygon polygon, ref float min, ref float max)
 {
     // To project a point on an axis use the dot product
     float temp = Vector2Util.DotProduct(axis, polygon.Points[0]);
     min = temp;
     max = temp;
     for (int i = 0; i < polygon.Points.Count; i++)
     {
         temp = Vector2Util.DotProduct(polygon.Points[i], axis);
         if (temp < min)
         {
             min = temp;
         }
         else
         {
             if (temp > max)
             {
                 max = temp;
             }
         }
     }
 }
        public static PolygonIntersectionResult PolygonIntersection(Polygon polygonMoving, Polygon polygon, Vector2 velocity)
        {
            PolygonIntersectionResult result = new PolygonIntersectionResult();

            float minIntervalDistance = float.PositiveInfinity;
            Vector2 translationAxis = Vector2.Zero;

            List<Vector2> edges = new List<Vector2>(polygonMoving.Edges);
            edges.AddRange(polygon.Edges);

            foreach (Vector2 edge in edges)
            {
                // Find the axis perpendicular to the current edge
                Vector2 axis = new Vector2(-edge.Y, edge.X);
                axis = Vector2Util.Normalize(axis);

                // Find the projection of the polygon on the current axis
                float minPolygonMoving = 0;
                float maxPolygonMoving = 0;
                float minPolygon = 0;
                float maxPolygon = 0;

                ProjectPolygon(axis, polygonMoving, ref minPolygonMoving, ref maxPolygonMoving);
                ProjectPolygon(axis, polygon, ref minPolygon, ref maxPolygon);

                // Project the velocity on the current axis
                float velocityProjection = Vector2Util.DotProduct(axis, velocity);

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

                // Do the same test as above for the new projection
                float intervalDistance = IntervalDistance(minPolygonMoving, maxPolygonMoving, minPolygon, maxPolygon);
                if (intervalDistance > 0)
                {
                    result.WillIntersect = false;
                    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;

                    Vector2 d = polygonMoving.Center - polygon.Center;
                    if (Vector2Util.DotProduct(d, 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;
        }