Beispiel #1
0
        /// <summary>
        /// Returns true if a rectangle centered at the given point, at the
        /// given angle and dimensions, will fit in the polygon.
        /// </summary>
        private bool WillRectangleFit(Edge[] edges, Vector2 center, float angleRad, float width, float height)
        {
            float halfWidth  = width / 2;
            float halfHeight = height / 2;

            var topLeft     = new Vector2(center.x - halfWidth, center.y + halfHeight);
            var topRight    = new Vector2(center.x + halfWidth, center.y + halfHeight);
            var bottomLeft  = new Vector2(center.x - halfWidth, center.y - halfHeight);
            var bottomRight = new Vector2(center.x + halfWidth, center.y - halfHeight);

            topLeft     = RotatePoint(center, angleRad, topLeft);
            topRight    = RotatePoint(center, angleRad, topRight);
            bottomLeft  = RotatePoint(center, angleRad, bottomLeft);
            bottomRight = RotatePoint(center, angleRad, bottomRight);

            var top    = new Edge(topLeft, topRight);
            var right  = new Edge(topRight, bottomRight);
            var bottom = new Edge(bottomLeft, bottomRight);
            var left   = new Edge(topLeft, bottomLeft);

            // If any edges of the polygon intersect with any of our edges, it won't fit
            foreach (var edge in edges)
            {
                if (EdgeHelpers.IsValidPoint(EdgeHelpers.GetIntersection(edge, top)) || EdgeHelpers.IsValidPoint(EdgeHelpers.GetIntersection(edge, right)) ||
                    EdgeHelpers.IsValidPoint(EdgeHelpers.GetIntersection(edge, bottom)) || EdgeHelpers.IsValidPoint(EdgeHelpers.GetIntersection(edge, left)))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Given a point inside of the boundary, finds the points on the
        /// boundary directly above, below, left and right of the point,
        /// with respect to the given angle.
        /// </summary>
        private bool FindSurroundingCollisionPoints(
            Edge[] edges,
            Vector2 point, float angleRad, out Vector2 topCollisionPoint,
            out Vector2 bottomCollisionPoint, out Vector2 leftCollisionPoint,
            out Vector2 rightCollisionPoint)
        {
            topCollisionPoint    = EdgeHelpers.InvalidPoint;
            bottomCollisionPoint = EdgeHelpers.InvalidPoint;
            leftCollisionPoint   = EdgeHelpers.InvalidPoint;
            rightCollisionPoint  = EdgeHelpers.InvalidPoint;

            bool isInside = EdgeHelpers.IsInside(edges, point);

            if (!isInside)
            {
                return(false);
            }

            // Find the top and bottom collision points by creating a large line segment that goes through the point to MAX and MIN values on Y
            var topEndpoint    = new Vector2(point.x, largeValue);
            var bottomEndpoint = new Vector2(point.x, smallValue);

            topEndpoint    = RotatePoint(point, angleRad, topEndpoint);
            bottomEndpoint = RotatePoint(point, angleRad, bottomEndpoint);
            var verticalLine = new Edge(topEndpoint, bottomEndpoint);
            // Find the left and right collision points by creating a large line segment that goes through the point to MAX and Min values on X
            var rightEndpoint = new Vector2(largeValue, point.y);
            var leftEndpoint  = new Vector2(smallValue, point.y);

            rightEndpoint = RotatePoint(point, angleRad, rightEndpoint);
            leftEndpoint  = RotatePoint(point, angleRad, leftEndpoint);
            var horizontalLine = new Edge(rightEndpoint, leftEndpoint);

            // Loop the edges and find the nearest intersection point
            foreach (var edge in edges)
            {
                Vector2 verticalIntersection = EdgeHelpers.GetIntersection(edge, verticalLine);
                if (EdgeHelpers.IsValidPoint(verticalIntersection))
                {
                    // Is this intersection above or below the point?
                    bool isAbove = RotatePoint(point, -angleRad, verticalIntersection).y > point.y;
                    if (isAbove)
                    {
                        // If this collision point is closer than the previous one
                        if (!EdgeHelpers.IsValidPoint(topCollisionPoint) ||
                            Vector2.SqrMagnitude(point - verticalIntersection) < Vector2.SqrMagnitude(point - topCollisionPoint))
                        {
                            topCollisionPoint = verticalIntersection;
                        }
                    }
                    else
                    {
                        if (!EdgeHelpers.IsValidPoint(bottomCollisionPoint) ||
                            Vector2.SqrMagnitude(point - verticalIntersection) < Vector2.SqrMagnitude(point - bottomCollisionPoint))
                        {
                            bottomCollisionPoint = verticalIntersection;
                        }
                    }
                }  // If vertical intersection found

                Vector2 horizontalIntersection = EdgeHelpers.GetIntersection(edge, horizontalLine);
                if (EdgeHelpers.IsValidPoint(horizontalIntersection))
                {
                    // Is this intersection left or right of the point?
                    bool isLeft = RotatePoint(point, -angleRad, horizontalIntersection).x < point.x;
                    if (isLeft)
                    {
                        // Is it closer than the previous intersection?
                        if (!EdgeHelpers.IsValidPoint(leftCollisionPoint) ||
                            Vector2.SqrMagnitude(point - horizontalIntersection) < Vector2.SqrMagnitude(point - leftCollisionPoint))
                        {
                            leftCollisionPoint = horizontalIntersection;
                        }
                    }
                    else
                    {
                        // Is it closer than the previous intersection?
                        if (!EdgeHelpers.IsValidPoint(rightCollisionPoint) ||
                            Vector2.SqrMagnitude(point - horizontalIntersection) < Vector2.SqrMagnitude(point - rightCollisionPoint))
                        {
                            rightCollisionPoint = horizontalIntersection;
                        }
                    }
                }
            }

            // Assert that any point inside should have intersection points on all sides with the polygon
            if (!EdgeHelpers.IsValidPoint(topCollisionPoint) || !EdgeHelpers.IsValidPoint(bottomCollisionPoint) ||
                !EdgeHelpers.IsValidPoint(leftCollisionPoint) || !EdgeHelpers.IsValidPoint(rightCollisionPoint))
            {
                return(false);
            }
            return(true);
        }