Esempio n. 1
0
        /// <summary>
        /// Check to see if a rectangle centered at the specified point and oriented at
        /// the specified angle will fit within the geometry.
        /// </summary>
        /// <param name="geometryEdges">The boundary geometry.</param>
        /// <param name="centerPoint">The center point of the rectangle.</param>
        /// <param name="angleRadians">The orientation, in radians, of the rectangle.</param>
        /// <param name="width">The width of the rectangle.</param>
        /// <param name="height">The height of the rectangle.</param>
        private bool CheckRectangleFit(
            Edge[] geometryEdges,
            Vector2 centerPoint,
            float angleRadians,
            float width,
            float height)
        {
            float halfWidth  = width * 0.5f;
            float halfHeight = height * 0.5f;

            // Calculate the rectangle corners.
            Vector2 topLeft     = new Vector2(centerPoint.x - halfWidth, centerPoint.y + halfHeight);
            Vector2 topRight    = new Vector2(centerPoint.x + halfWidth, centerPoint.y + halfHeight);
            Vector2 bottomLeft  = new Vector2(centerPoint.x - halfWidth, centerPoint.y - halfHeight);
            Vector2 bottomRight = new Vector2(centerPoint.x + halfWidth, centerPoint.y - halfHeight);

            // Rotate the rectangle.
            topLeft     = RotatePoint(topLeft, centerPoint, angleRadians);
            topRight    = RotatePoint(topRight, centerPoint, angleRadians);
            bottomLeft  = RotatePoint(bottomLeft, centerPoint, angleRadians);
            bottomRight = RotatePoint(bottomRight, centerPoint, angleRadians);

            // Get the rectangle edges.
            Edge topEdge    = new Edge(topLeft, topRight);
            Edge rightEdge  = new Edge(topRight, bottomRight);
            Edge bottomEdge = new Edge(bottomLeft, bottomRight);
            Edge leftEdge   = new Edge(topLeft, bottomLeft);

            // Check for collisions with the boundary geometry. If any of our edges collide,
            // the rectangle will not fit within the playspace.
            for (int i = 0; i < geometryEdges.Length; i++)
            {
                if (EdgeUtilities.IsValidPoint(EdgeUtilities.GetIntersectionPoint(geometryEdges[i], topEdge)) ||
                    EdgeUtilities.IsValidPoint(EdgeUtilities.GetIntersectionPoint(geometryEdges[i], rightEdge)) ||
                    EdgeUtilities.IsValidPoint(EdgeUtilities.GetIntersectionPoint(geometryEdges[i], bottomEdge)) ||
                    EdgeUtilities.IsValidPoint(EdgeUtilities.GetIntersectionPoint(geometryEdges[i], leftEdge)))
                {
                    return(false);
                }
            }

            // No collisions found with the rectangle. Success!
            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Find points at which there are collisions with the geometry around a given point.
        /// </summary>
        /// <param name="geometryEdges">The boundary geometry.</param>
        /// <param name="point">The point around which collisions will be identified.</param>
        /// <param name="angleRadians">The angle, in radians, at which the collision points will be oriented.</param>
        /// <param name="topCollisionPoint">Receives the coordinates of the upper collision point.</param>
        /// <param name="bottomCollisionPoint">Receives the coordinates of the lower collision point.</param>
        /// <param name="leftCollisionPoint">Receives the coordinates of the left collision point.</param>
        /// <param name="rightCollisionPoint">Receives the coordinates of the right collision point.</param>
        /// <returns>
        /// True if all of the required collision points are located, false otherwise.
        /// If a point is unable to be found, the appropriate out parameter will be set to <see cref="EdgeUtilities.InvalidPoint"/>.
        /// </returns>
        private static bool FindSurroundingCollisionPoints(
            Edge[] geometryEdges,
            Vector2 point,
            float angleRadians,
            out Vector2 topCollisionPoint,
            out Vector2 bottomCollisionPoint,
            out Vector2 leftCollisionPoint,
            out Vector2 rightCollisionPoint)
        {
            // Initialize out parameters.
            topCollisionPoint    = EdgeUtilities.InvalidPoint;
            bottomCollisionPoint = EdgeUtilities.InvalidPoint;
            leftCollisionPoint   = EdgeUtilities.InvalidPoint;
            rightCollisionPoint  = EdgeUtilities.InvalidPoint;

            // Check to see if the point is inside the geometry.
            if (!EdgeUtilities.IsInsideBoundary(geometryEdges, point))
            {
                return(false);
            }

            // Define values that are outside of the maximum boundary size.
            float largeValue = EdgeUtilities.MaxWidth;
            float smallValue = -largeValue;

            // 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    = topEndpoint.RotateAroundPoint(point, angleRadians);
            bottomEndpoint = bottomEndpoint.RotateAroundPoint(point, angleRadians);
            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 = rightEndpoint.RotateAroundPoint(point, angleRadians);
            leftEndpoint  = leftEndpoint.RotateAroundPoint(point, angleRadians);
            var horizontalLine = new Edge(rightEndpoint, leftEndpoint);

            for (int i = 0; i < geometryEdges.Length; i++)
            {
                // Look for a vertical collision
                var verticalIntersectionPoint = EdgeUtilities.GetIntersectionPoint(geometryEdges[i], verticalLine);

                if (EdgeUtilities.IsValidPoint(verticalIntersectionPoint))
                {
                    // Is the intersection above or below the point?
                    if (verticalIntersectionPoint.RotateAroundPoint(point, -angleRadians).y > point.y)
                    {
                        // Update the top collision point
                        if (!EdgeUtilities.IsValidPoint(topCollisionPoint) ||
                            (Vector2.SqrMagnitude(point - verticalIntersectionPoint) < Vector2.SqrMagnitude(point - topCollisionPoint)))
                        {
                            topCollisionPoint = verticalIntersectionPoint;
                        }
                    }
                    else
                    {
                        // Update the bottom collision point
                        if (!EdgeUtilities.IsValidPoint(bottomCollisionPoint) ||
                            Vector2.SqrMagnitude(point - verticalIntersectionPoint) < Vector2.SqrMagnitude(point - bottomCollisionPoint))
                        {
                            bottomCollisionPoint = verticalIntersectionPoint;
                        }
                    }
                }

                // Look for a horizontal collision
                var horizontalIntersection = EdgeUtilities.GetIntersectionPoint(geometryEdges[i], horizontalLine);

                if (!EdgeUtilities.IsValidPoint(horizontalIntersection))
                {
                    continue;
                }

                // Is this intersection to the left or the right of the point?
                if (horizontalIntersection.RotateAroundPoint(point, -angleRadians).x < point.x)
                {
                    // Update the left collision point
                    if (!EdgeUtilities.IsValidPoint(leftCollisionPoint) ||
                        (Vector2.SqrMagnitude(point - horizontalIntersection) < Vector2.SqrMagnitude(point - leftCollisionPoint)))
                    {
                        leftCollisionPoint = horizontalIntersection;
                    }
                }
                else
                {
                    // Update the right collision point
                    if (!EdgeUtilities.IsValidPoint(rightCollisionPoint) ||
                        (Vector2.SqrMagnitude(point - horizontalIntersection) < Vector2.SqrMagnitude(point - rightCollisionPoint)))
                    {
                        rightCollisionPoint = horizontalIntersection;
                    }
                }
            }

            // Each corner of the rectangle must intersect with the geometry.
            return(EdgeUtilities.IsValidPoint(topCollisionPoint) &&
                   EdgeUtilities.IsValidPoint(leftCollisionPoint) &&
                   EdgeUtilities.IsValidPoint(rightCollisionPoint) &&
                   EdgeUtilities.IsValidPoint(bottomCollisionPoint));
        }