Beispiel #1
0
        public override CollidableResults CheckForCollision(Collidable collidable, Vector3 velocity)
        {
            CollidableResults rayCastCollisionResult = new CollidableResults()
            {
                Intersect       = false,
                HitPoint        = Vector3.Zero,
                CollisionNormal = Vector3.Zero
            };

            //is the vector perpendicular to the edge of the polygon where the intersection occured

            for (var i = 0; i < collidable.Points.Count; i++)
            {
                var p1 = collidable.Points[i];
                var p2 = i + 1 >= collidable.Points.Count ? collidable.Points[0] : collidable.Points[i + 1];

                rayCastCollisionResult.HitPoint = new Vector3(FindLineIntersection(Points[0], Points[1], p1, p2), 0f);
                if (!rayCastCollisionResult.HitPoint.Equals(Vector3.Zero))
                {
                    rayCastCollisionResult.Intersect       = true;
                    rayCastCollisionResult.CollisionNormal = new Vector3(collidable.Edges[i].Y, -collidable.Edges[i].X, 0f);
                    rayCastCollisionResult.CollisionNormal.Normalize();
                    break;
                }
            }


            return(rayCastCollisionResult);
        }
Beispiel #2
0
        // Check if polygon A is going to collide with polygon B for the given velocity
        public override CollidableResults CheckForCollision(Collidable polygon, Vector3 velocity)
        {
            var result = new CollidableResults
            {
                Intersect     = true,
                WillIntersect = true
            };

            var     edgeCountA          = Edges.Count;
            var     edgeCountB          = polygon.Edges.Count;
            var     minIntervalDistance = float.PositiveInfinity;
            var     translationAxis     = new Vector2();
            Vector2 edge;

            // Loop through all the edges of both polygons
            for (var edgeIndex = 0; edgeIndex < edgeCountB + edgeCountA; edgeIndex++)
            {
                if (edgeIndex < edgeCountB)
                {
                    edge = polygon.Edges[edgeIndex];
                }
                else
                {
                    edge = Edges[edgeIndex - edgeCountB];
                }

                // ===== 1. Find if the polygons are currently intersecting =====

                // Find the axis perpendicular to the current edge
                var axis = new Vector2(-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, this, ref minA, ref maxA);
                ProjectPolygon(axis, (Polygon)polygon, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                if (IntervalDistance(minB, maxB, minA, maxA) > 0)
                {
                    result.Intersect = false;
                }

                // ===== 2. Now find if the polygons *will* intersect =====

                // Project the velocity on the current axis
                var velocityProjection = Vector2.Dot(axis, new Vector2(velocity.X, velocity.Y));

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

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

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!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;

                    var d = polygon.Center - Center;
                    if (Vector2.Dot(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 = new Vector3(translationAxis * minIntervalDistance, 0f);
            }

            return(result);
        }