Description
Imagine a space like the arcade game Asteroids where everything wraps around right to left and bottom to top - effectively coordinates on a flat torus. The diagram shows an example of two intersecting rectangles. The red rectangle at bottom right is wrapping around so that portions off screen are shown on the top and left, likewise with the blue.
Code
The code takes in coordinates and width and height of two rectangles and the domain for x and y, and it returns whether they are intersecting given that they wrap around within the domain. I've included some test cases.
Asking for thoughts on improvements, optimisations, simplifications, bugs? etc...
// Preconditions: x1, w1, y1, h1, x2, w2, y2, h2 are between 0 and domain exclusive
bool IntersectsOnTorus(int x1, int w1, int y1, int h1, int x2, int w2, int y2, int h2, int domain)
{
int r1 = x1 + w1;
int r2 = x2 + w2;
if (r1 < domain || r2 < domain)
{
r1 -= r1 >= domain ? domain : 0;
r2 -= r2 >= domain ? domain : 0;
if (x1 >= r2 && x2 >= r1 || x1 <= r1 && x2 <= r2 && (x1 >= r2 || x2 >= r1))
return false;
}
int b1 = y1 + h1;
int b2 = y2 + h2;
if (b1 < domain || b2 < domain)
{
b1 -= b1 >= domain ? domain : 0;
b2 -= b2 >= domain ? domain : 0;
if (y1 >= b2 && y2 >= b1 || y1 <= b1 && y2 <= b2 && (y1 >= b2 || y2 >= b1))
return false;
}
return true;
}
Test(5, 10, 5, 20, 20, 10, 20, 10, 50, false);
Test(5, 15, 5, 20, 20, 10, 20, 10, 50, false);
Test(5, 17, 5, 20, 20, 10, 20, 10, 50, true);
Test(5, 25, 5, 20, 20, 10, 20, 10, 50, true);
Test(5, 28, 5, 20, 20, 10, 20, 10, 50, true);
Test(5, 48, 5, 20, 20, 10, 20, 10, 50, true);
Test(25, 28, 5, 20, 20, 10, 20, 10, 50, true);
Test(30, 28, 5, 20, 20, 10, 20, 10, 50, false);
Test(30, 45, 5, 20, 20, 10, 20, 10, 50, true);
void Test(int x1, int w1, int y1, int h1, int x2, int w2, int y2, int h2, int domain, bool expected)
{
bool result1 = IntersectsOnTorus(x1, w1, y1, h1, x2, w2, y2, h2, domain);
bool result2 = IntersectsOnTorus(x2, w2, y2, h2, x1, w1, y1, h1, domain);
bool result3 = IntersectsOnTorus(y1, h1, x1, w1, y2, h2, x2, w2, domain);
bool result4 = IntersectsOnTorus(y2, h2, x2, w2, y1, h1, x1, w1, domain);
bool success = result1 == result2 && result2 == result3 && result3 == result4 && result1 == expected;
Console.WriteLine($"""{result1}, {result2}, {result3}, {result4}, {(success ? "Success" : "Fail")}""");
Console.WriteLine();
}