示例#1
0
        public Range Projection(Vector2 shapePosition, Vector2 axis)
        {
            Polygon polygon = new Polygon(Shape);

            polygon.Translate(shapePosition);
            return(polygon.Projection(axis));
        }
示例#2
0
        public static bool TestLineSegmentWithConvexPolygon(Vector2 startPoint, Vector2 endPoint, Polygon polygon, IEnumerable <Vector2> axes, out Contact?contact)
        {
            Vector2[] intersections = polygon.Intersects(new Line(startPoint, endPoint));

            // no intersections, no contact
            if (intersections.Length == 0)
            {
                contact = null;
                return(false);
            }

            Contact leastPenetrationContact = new Contact {
                Position         = intersections[0],
                PenetrationDepth = float.PositiveInfinity
            };

            // calculate line-segment first contact point position
            float closestIntersectionDist = Math.DistanceSquared(startPoint, intersections[0]);

            for (int i = 1; i < intersections.Length; i++)
            {
                float d = Math.DistanceSquared(startPoint, intersections[i]);
                if (d < closestIntersectionDist)
                {
                    leastPenetrationContact.Position = intersections[i];
                    closestIntersectionDist          = d;
                }
            }

            foreach (Vector2 axis in axes)
            {
                Range projectionA        = axis.Projection(startPoint, endPoint),
                             projectionB = polygon.Projection(axis);

                if (!projectionA.Overlaps(projectionB, out float penetrationDepth))
                {
                    contact = null;
                    return(false);
                }

                if (penetrationDepth < leastPenetrationContact.PenetrationDepth)
                {
                    leastPenetrationContact.PenetrationDepth = penetrationDepth;
                    leastPenetrationContact.Normal           = projectionA.Min > projectionB.Min ? -axis : axis;
                }
            }

            contact = leastPenetrationContact;
            return(true);
        }
示例#3
0
        public static bool TestIShapeWithConvexPolygon(IShape shape, Vector2 shapePos, Polygon polygon, ICollection <Vector2> axes, out Contact?contact)
        {
            Debug.Assert(!(shape is PolygonShape), "TestIShapeWithConvexPolygon can't handle PolygonShape correctly. Please use another polygon specific variant.");

            Contact leastPenetrationContact = new Contact {
                Position         = shapePos,
                PenetrationDepth = float.PositiveInfinity
            };

            foreach (Vector2 axis in axes)
            {
                Range projectionA        = shape.Projection(shapePos, axis),
                             projectionB = polygon.Projection(axis);

                if (!projectionA.Overlaps(projectionB, out float penetrationDepth))
                {
                    contact = null;
                    return(false);
                }

                if (penetrationDepth < leastPenetrationContact.PenetrationDepth)
                {
                    leastPenetrationContact.PenetrationDepth = penetrationDepth;
                    leastPenetrationContact.Normal           = projectionA.Min > projectionB.Min ? -axis : axis;
                }
            }

            // contact points
            (Vector2 MaxProjVertex, Line Edge)edgeA = shape.FindBestClippingEdge(shapePos, leastPenetrationContact.Normal);
            (Vector2 MaxProjVertex, Line Edge)edgeB = FindBestEdge(polygon, -leastPenetrationContact.Normal);

            if (edgeA.Edge.PointA != edgeA.Edge.PointB)
            {
                Vector2[] contactPoints = CalculateContactPoints(edgeA, edgeB, leastPenetrationContact.Normal);

                if (contactPoints.Length > 0)
                {
                    leastPenetrationContact.Position = contactPoints[0];
                }
            }

            contact = leastPenetrationContact;
            return(true);
        }
示例#4
0
        private static bool TestConvexPolygons(Polygon A, Polygon B, IEnumerable <Vector2> axes, out Contact?contact)
        {
            Contact leastPenetrationContact = new Contact {
                Position         = A[0],
                PenetrationDepth = float.PositiveInfinity
            };

            foreach (Vector2 axis in axes)
            {
                Range projectionA        = A.Projection(axis),
                             projectionB = B.Projection(axis);

                if (!projectionA.Overlaps(projectionB, out float penetrationDepth))
                {
                    contact = null;
                    return(false);
                }

                if (penetrationDepth < leastPenetrationContact.PenetrationDepth)
                {
                    leastPenetrationContact.PenetrationDepth = penetrationDepth;
                    leastPenetrationContact.Normal           = projectionA.Min > projectionB.Min ? -axis : axis;
                }
            }

            // contact points
            (Vector2 MaxProjVertex, Line Edge)edgeA = FindBestEdge(A, leastPenetrationContact.Normal);
            (Vector2 MaxProjVertex, Line Edge)edgeB = FindBestEdge(B, -leastPenetrationContact.Normal);

            Vector2[] contactPoints = CalculateContactPoints(edgeA, edgeB, leastPenetrationContact.Normal);

            if (contactPoints.Length > 0)
            {
                leastPenetrationContact.Position = contactPoints[0];
            }

            contact = leastPenetrationContact;
            return(true);
        }