/// <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); }