# AABB Collision Detection with Intersection Points (Incl. Rotation)

``````public struct Line {
public Vector2 a;
public Vector2 b;

public Line(float x1, float y1, float x2, float y2) {
a = new Vector2(x1, y1);
b = new Vector2(x2, y2);
}

public void Rotate(float rad, Vector2 center) {
}

private void Rotate(float rad, ref Vector2 point, Vector2 center) {
point = Vector2.Transform(point - center, Matrix.CreateRotationZ(rad)) + center;
}

public bool Intersect(Line line, out Vector2 ? intersectionPoint) {
intersectionPoint = null;

float a1 = b.Y - a.Y;
float b1 = a.X - b.X;
float c1 = a1 * a.X + b1 * a.Y;

float a2 = line.b.Y - line.a.Y;
float b2 = line.a.X - line.b.X;
float c2 = a2 * line.a.X + b2 * line.a.Y;

//If the lines are parallel, no collision possible.
float det = a1 * b2 - a2 * b1;
if (det == 0) return false;

float x = (b2 * c1 - b1 * c2) / det;
float y = (a1 * c2 - a2 * c1) / det;

if (OnLine(this, x, y) && OnLine(line, x, y)) {
intersectionPoint = new Vector2(x, y);
return true;
}

return false;
}

public static bool OnLine(Line line, float x, float y) {
return Math.Min(line.a.X, line.b.X) <= x && x <= Math.Max(line.a.X, line.b.X) && Math.Min(line.a.Y, line.b.Y) <= y && y <= Math.Max(line.a.Y, line.b.Y);
}
}``````
``````public struct SRectangle {
public Line left;
public Line top;
public Line right;
public Line bottom;

public void Rotate(float rad, Vector2 center) {
}

public static SRectangle FromRectangle(Rectangle rectangle, Vector2 origin, float rotation) {
Line left = new Line(rectangle.X, rectangle.Y, rectangle.X, rectangle.Y + rectangle.Height);
Line top = new Line(rectangle.X, rectangle.Y, rectangle.X + rectangle.Width, rectangle.Y);
Line right = new Line(rectangle.X + rectangle.Width, rectangle.Y, rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height);
Line bottom = new Line(rectangle.X, rectangle.Y + rectangle.Height, rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height);

left.a.X -= origin.X;
left.a.Y -= origin.Y;
left.b.X -= origin.X;
left.b.Y -= origin.Y;
top.a.X -= origin.X;
top.a.Y -= origin.Y;
top.b.X -= origin.X;
top.b.Y -= origin.Y;
right.a.X -= origin.X;
right.a.Y -= origin.Y;
right.b.X -= origin.X;
right.b.Y -= origin.Y;
bottom.a.X -= origin.X;
bottom.a.Y -= origin.Y;
bottom.b.X -= origin.X;
bottom.b.Y -= origin.Y;

origin.X += rectangle.X - rectangle.Width / 2;
origin.Y += rectangle.Y - rectangle.Height / 2;

left.Rotate(rotation, origin);
right.Rotate(rotation, origin);
top.Rotate(rotation, origin);
bottom.Rotate(rotation, origin);

return new SRectangle() {
left = left,
right = right,
top = top,
bottom = bottom
};
}
}``````
``````public static bool AABB_AABB(SmartRectangle x, SmartRectangle y, out Vector2[] collisionPoints) {
List < Vector2 > cp = new List < Vector2 > ();

/* Left against y */
if (x.left.Intersect(y.left, out Vector2 ? llcp)) cp.Add(llcp.Value);
if (x.left.Intersect(y.top, out Vector2 ? ltcp)) cp.Add(ltcp.Value);
if (x.left.Intersect(y.right, out Vector2 ? lrcp)) cp.Add(lrcp.Value);
if (x.left.Intersect(y.bottom, out Vector2 ? lbcp)) cp.Add(lbcp.Value);
/* Top against y */
if (x.top.Intersect(y.left, out Vector2 ? tlcp)) cp.Add(tlcp.Value);
if (x.top.Intersect(y.top, out Vector2 ? ttcp)) cp.Add(ttcp.Value);
if (x.top.Intersect(y.right, out Vector2 ? trcp)) cp.Add(trcp.Value);
if (x.top.Intersect(y.bottom, out Vector2 ? tbcp)) cp.Add(tbcp.Value);
/* Right against y */
if (x.right.Intersect(y.left, out Vector2 ? rlcp)) cp.Add(rlcp.Value);
if (x.right.Intersect(y.top, out Vector2 ? rtcp)) cp.Add(rtcp.Value);
if (x.right.Intersect(y.right, out Vector2 ? rrcp)) cp.Add(rrcp.Value);
if (x.right.Intersect(y.bottom, out Vector2 ? rbcp)) cp.Add(rbcp.Value);
/* Bottom against y */
if (x.bottom.Intersect(y.left, out Vector2 ? blcp)) cp.Add(blcp.Value);
if (x.bottom.Intersect(y.top, out Vector2 ? btcp)) cp.Add(btcp.Value);
if (x.bottom.Intersect(y.right, out Vector2 ? brcp)) cp.Add(brcp.Value);
if (x.bottom.Intersect(y.bottom, out Vector2 ? bbcp)) cp.Add(bbcp.Value);

collisionPoints = cp.ToArray();
return cp.Count > 0;
}``````