Skip to content

Instantly share code, notes, and snippets.

@JoaoBaptMG
Last active June 29, 2019 13:42
Show Gist options
  • Save JoaoBaptMG/ab8ce6465b4dd48ff6a623817c59308c to your computer and use it in GitHub Desktop.
Save JoaoBaptMG/ab8ce6465b4dd48ff6a623817c59308c to your computer and use it in GitHub Desktop.
Rectangle Intersection
/// <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