/// <summary>
        /// Returns true if this shape intersects with the given shape.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Intersects(CollisionRectangle other)
        {
            Vector2 projectionA, projectionB;

            foreach (Vector2 axis in this.Axes)
            {
                projectionA = Project(axis);
                projectionB = other.Project(axis);
                // check for overlap. In-lining this function to allow compiler optimization
                if (projectionA.Y < projectionB.X || projectionB.Y < projectionA.X)
                {
                    return(false);
                }
            }
            foreach (Vector2 axis in other.Axes)
            {
                projectionA = Project(axis);
                projectionB = other.Project(axis);
                if (projectionA.Y < projectionB.X || projectionB.Y < projectionA.X)
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Returns true if this shape intersects with the given shape. Also returns the
        /// minimum translation vector, or MTV, used to push the shapes apart.
        /// </summary>
        /// <param name="other"></param>
        /// <param name="mtvAxis"></param>
        /// <param name="mtvMagnitude"></param>
        /// <returns></returns>
        public bool IntersectsMTV(CollisionRectangle other, out Vector2 mtvAxis, out float mtvMagnitude)
        {
            mtvAxis      = Vector2.Zero;
            mtvMagnitude = 4000000000; // really large value
            float   overlap;
            Vector2 projectionA, projectionB;

            this.NormalizeAxes();
            other.NormalizeAxes();
            foreach (Vector2 axis in this.Axes)
            {
                projectionA = Project(axis);
                projectionB = other.Project(axis);
                // check for overlap. In-lining this function to allow compiler optimization
                if (projectionA.Y < projectionB.X || projectionB.Y < projectionA.X)
                {
                    return(false);
                }
                else
                {
                    overlap = FindOverlap(projectionA, projectionB);
                    if (Math.Abs(overlap) < Math.Abs(mtvMagnitude))
                    {
                        mtvMagnitude = overlap;
                        mtvAxis      = axis;
                    }
                }
            }
            foreach (Vector2 axis in other.Axes)
            {
                projectionA = Project(axis);
                projectionB = other.Project(axis);
                if (projectionA.Y < projectionB.X || projectionB.Y < projectionA.X)
                {
                    return(false);
                }
                else
                {
                    overlap = FindOverlap(projectionA, projectionB);
                    if (Math.Abs(overlap) < Math.Abs(mtvMagnitude))
                    {
                        mtvMagnitude = overlap;
                        mtvAxis      = axis;
                    }
                }
            }
            return(true);
        }
        public bool FindTranslationMagnitude(CollisionRectangle other, Vector2 translationAxis, out float magnitude)
        {
            float   tempMagnitude;
            Vector2 projectionA, projectionB;

            magnitude = 4000000000; // really large value;

            this.NormalizeAxes();
            other.NormalizeAxes();
            if (translationAxis == Vector2.Zero)
            {
                return(false);
            }
            translationAxis.Normalize();

            HashSet <Vector2> possibleAxes = new HashSet <Vector2>();
            double            distance;
            double            angle;

            // Collect the axis that form an acute angle with the axis of pushback
            foreach (Vector2 axis in this.Axes)
            {
                distance = Math.Pow((translationAxis.X - axis.X), 2) + Math.Pow((translationAxis.Y - axis.Y), 2);
                angle    = Math.Acos(1 - distance / 2);
                if (angle < Math.PI / 2)
                {
                    possibleAxes.Add(axis);
                }
                else
                {
                    possibleAxes.Add(axis * -1);
                }
            }
            foreach (Vector2 axis in other.Axes)
            {
                distance = Math.Pow((translationAxis.X - axis.X), 2) + Math.Pow((translationAxis.Y - axis.Y), 2);
                angle    = Math.Acos(1 - distance / 2);
                if (angle < Math.PI / 2)
                {
                    possibleAxes.Add(axis);
                }
                else
                {
                    possibleAxes.Add(axis * -1);
                }
            }

            // Calculate the shapes' for each axis. Save the minimum overlap and the axis.
            foreach (Vector2 axis in possibleAxes)
            {
                projectionA = Project(axis);
                projectionB = other.Project(axis);
                // check for overlap. In-lining this function to allow compiler optimization
                if (projectionA.Y < projectionB.X || projectionB.Y < projectionA.X)
                {
                    return(false);
                }
                else
                {
                    float overlap = projectionB.Y - projectionA.X;
                    float dotProd = (float)DotProduct(axis, translationAxis);
                    tempMagnitude = overlap / dotProd;
                    if (Math.Abs(tempMagnitude) < Math.Abs(magnitude))
                    {
                        magnitude = tempMagnitude;
                    }
                }
            }

            //magnitude = mtvMagnitude / (float)DotProduct(mtvAxis, translationAxis);
            return(true);
        }