Last active
June 29, 2019 13:42
-
-
Save JoaoBaptMG/ab8ce6465b4dd48ff6a623817c59308c to your computer and use it in GitHub Desktop.
Rectangle Intersection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Check if two rotated rectangles intersect, assuming they are rotated relative to their center points | |
/// </summary> | |
/// <param name="r1">The first rectangle</param> | |
/// <param name="r2">The second rectangle</param> | |
/// <param name="rotation1">The first rectangle's rotation in radians</param> | |
/// <param name="rotation2">The second rectangle's rotation in radians</param> | |
/// <returns>Whether the two rectangles intersect</returns> | |
public static bool RectangleIntersection(Rectangle r1, Rectangle r2, float rotation1, float rotation2) | |
{ | |
// Calculate the axis points of the first rectangle | |
var topLeft1 = r1.Center.ToVector2(); | |
var haxisHor1 = r1.Width * new Vector2((float)Math.Cos(rotation1), (float)Math.Sin(rotation1)) / 2; | |
var haxisVert1 = r1.Height * new Vector2(-(float)Math.Sin(rotation1), (float)Math.Cos(rotation1)) / 2; | |
// The four vecors for the second rectangle's vertices | |
var rectPoints1 = new Vector2[4] | |
{ | |
topLeft1 + haxisHor1 + haxisVert1, | |
topLeft1 + haxisHor1 - haxisVert1, | |
topLeft1 - haxisHor1 + haxisVert1, | |
topLeft1 - haxisHor1 - haxisVert1, | |
}; | |
// Calculate the axis points for the second rectangle | |
var topLeft2 = r2.Center.ToVector2(); | |
var haxisHor2 = r2.Width * new Vector2((float)Math.Cos(rotation2), (float)Math.Sin(rotation2)) / 2; | |
var haxisVert2 = r2.Height * new Vector2(-(float)Math.Sin(rotation2), (float)Math.Cos(rotation2)) / 2; | |
// The four vecors for the second rectangle's vertices | |
var rectPoints2 = new Vector2[4] | |
{ | |
topLeft2 + haxisHor2 + haxisVert2, | |
topLeft2 + haxisHor2 - haxisVert2, | |
topLeft2 - haxisHor2 + haxisVert2, | |
topLeft2 - haxisHor2 - haxisVert2, | |
}; | |
// Now, apply the Separating Axis Theorem for each of the two axes of each rectangle | |
if (SeparatingAxis(topLeft1, haxisHor1, rectPoints1, rectPoints2)) return false; | |
if (SeparatingAxis(topLeft1, haxisVert1, rectPoints1, rectPoints2)) return false; | |
if (SeparatingAxis(topLeft2, haxisHor2, rectPoints1, rectPoints2)) return false; | |
if (SeparatingAxis(topLeft2, haxisVert2, rectPoints1, rectPoints2)) return false; | |
// None of the two axes separate the rectangles, so they must overlap | |
return true; | |
} | |
// Local function to compute whether q->v is the separating axis of the following point lists | |
static bool SeparatingAxis(Vector2 q, Vector2 v, Vector2[] pointList1, Vector2[] pointList2) | |
{ | |
// Calculate the minimum and maximum of the first pointList | |
var min1 = float.PositiveInfinity; | |
var max1 = float.NegativeInfinity; | |
foreach (var p in pointList1) | |
{ | |
var proj = Vector2.Dot(v, p - q); | |
if (min1 > proj) min1 = proj; | |
if (max1 < proj) max1 = proj; | |
} | |
// Calculate the minimum and maximum of the second pointList | |
var min2 = float.PositiveInfinity; | |
var max2 = float.NegativeInfinity; | |
foreach (var p in pointList2) | |
{ | |
var proj = Vector2.Dot(v, p - q); | |
if (min2 > proj) min2 = proj; | |
if (max2 < proj) max2 = proj; | |
} | |
// Now, do an interval search to find if we have a separating axis | |
return max1 < min2 || max2 < min1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment