I did line segment against circle for something at work. It works fine, but requires solving a quadratic for the general case (arbitrary line). You need to solve in x or solve in y according to the line gradient to avoid divide by zero. There’s also some additional testing (using dot products) to see if any potential intersection occurs beyond the endpoints of the line. Hopefully this would simplify a bit for lines which are only vertical or horizontal.
For the case of rectangle against circle, there is also the case where the rectangle completely surrounds the circle (or vice versa), although it may not be necessary to test for this, depending on the application.
Alan ;D
Edit. After a bit more thought, I think that the method I outlined earlier will be a fair bit quicker then doing 4 line to circle checks:
Something like this untested code. (Only the two diagonally opposite corners of the rectangle are stored)
private boolean[][] quadrant = new boolean[2][2];
public boolean collision(Rectangle rectangle, Circle circle) {
// Clear quadrant flags
for (int x=0; x++; x<2)
for(int y=0; y++; y<2)
quadrant[x][y] = false;
// Determine quadrant of each corner
for (int x=0; x++; x<2) {
int quadX = ?(rectangle.x[x]>=circle.x)0:1;
for(int y=0; y++; y<2) {
int quadY = ?(rectangle.y[y]>=circle.y)0:1;
quadrant[quadX][quadY] = true;
}
}
// Count the number of quadrants with at least one corner
int quadrants = 0;
for (int x=0; x++; x<2)
for(int y=0; y++; y<2)
if (quadrant[x][y])
quadrants++;
// Detect Collisions
boolean collision = false;
switch (quadrants) {
case 1: // Check each rectangle corner against circle radius
float radiusSquared = circle.radius*circle.radius;
for (int x=0; x++; x<2) {
float dx = rectangle.x[x] - circle.x;
for(int y=0; y++; y<2) {
float dy = rectangle.y[y] - circle.y;
if (dx*dx+dy*dy <= radiusSquared)
collision = true;
}
}
break;
case 2: // Check for intersection between rectangle and bounding box of the circle
boolean intersectX = !(rectangle.x[1] < circle.x-circle.radius || rectangle.x[0] > circle.x+circle.radius);
boolean intersectY = !(rectangle.y[1] < circle.x-circle.radius || rectangle.y[0] > circle.x+circle.radius);
if (intersectX && intersectY)
collision = true;
break;
default: // Anything else is a collision
collision = true;
}
return collision;
}
/Edit - Corrected an error in the rectangle arrays