Skip to content

Instantly share code, notes, and snippets.

@SteffenBlake
Last active June 23, 2024 04:35
Show Gist options
  • Save SteffenBlake/bdce192e5185ebb922b07fb49a602e1b to your computer and use it in GitHub Desktop.
Save SteffenBlake/bdce192e5185ebb922b07fb49a602e1b to your computer and use it in GitHub Desktop.
public static bool ProjectIntersection(
RectangleF r1,
RectangleF r2,
Vector2 v1,
Vector2 v2,
[MaybeNullWhen(false)]
out CollisionFrame? frame
)
{
var dv = v1 - v2;
var (xStart, xEnd) = ProjectLinearIntersection(
r1.X, r1.Width, r2.X, r2.Width, dv.X
);
var (yStart, yEnd) = ProjectLinearIntersection(
r1.Y, r1.Height, r2.Y, r2.Height, dv.Y
);
var start = Math.Max(0.0f, Math.Max(xStart, yStart));
var end = Math.Min(1.0f, Math.Min(xEnd, yEnd));
if (start > 1 || end < 0)
{
frame = null;
return false;
}
var middle = (start + end) / 2f;
frame = new(
new(
new(
r1.X + (v1.X * start), r1.Y + (v1.Y * start), r1.Width, r1.Height
),
new(
r2.X + (v2.X * start), r2.Y + (v2.Y * start), r2.Width, r2.Height
)
),
new(
new(
r1.X + (v1.X * middle), r1.Y + (v1.Y * middle), r1.Width, r1.Height
),
new(
r2.X + (v2.X * middle), r2.Y + (v2.Y * middle), r2.Width, r2.Height
)
),
new(
new(
r1.X + (v1.X * end), r1.Y + (v1.Y * end), r1.Width, r1.Height
),
new(
r2.X + (v2.X * end), r2.Y + (v2.Y * end), r2.Width, r2.Height
)
)
);
return true;
}
public static (float Start, float End) ProjectLinearIntersection(
float aPos, float aWidth, float bPos, float bWidth, float translation
)
{
// Avoid divide by zero problem if objects aren't moving
var translationInternal = translation == 0 ? 0.0000000001f : translation;
var start = (bPos - aPos - aWidth) / translationInternal;
var end = (bPos + bWidth - aPos) / translationInternal;
return (start, end);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment