How do I detect intersections between a circle and any other circle in the same plane?
Two circles intersect if, and only if, the distance between their centers is between the sum and the difference of their radii. Given two circles (x0, y0, R0)
and (x1, y1, R1)
, the formula is as follows:
ABS(R0 - R1) <= SQRT((x0 - x1)^2 + (y0 - y1)^2) <= (R0 + R1)
Squaring both sides lets you avoid the slow SQRT
, and stay with ints if your inputs are integers:
(R0 - R1)^2 <= (x0 - x1)^2 + (y0 - y1)^2 <= (R0 + R1)^2
Since you need only a yes/no test, this check is faster than calculating the exact intersection points.
The above solution should work even for the "one circle inside the other" case.
Assuming filled circle intersection (ie: One circle inside another is an intersection).
Where:
- x0,y0,r0 = Center and radius of circle 0.
- x1,y1,r1 = Center and radius of circle 1.
Code:
boolean intersects = Math.hypot(x0-x1, y0-y1) <= (r0 + r1);
XNA / C# solution
class Circle
{
public Vector2 Center;
public float Radius;
public bool Intersects(Circle circle)
{
float distanceX = Center.X - circle.Center.X;
float distanceY = Center.Y - circle.Center.Y;
float radiusSum = circle.Radius + Radius;
return distanceX * distanceX + distanceY * distanceY <= radiusSum * radiusSum;
}
public bool Contains(Circle circle)
{
if (circle.Radius > Radius)
return false;
float distanceX = Center.X - circle.Center.X;
float distanceY = Center.Y - circle.Center.Y;
float radiusD = Radius - circle.Radius;
return distanceX * distanceX + distanceY * distanceY <= radiusD * radiusD;
}
}
Note that method Circle.Intersects() returns true even if one circle is within another (treats them as "filled" circles).
If the distance between the centers of two circles is at most the sum of their radii, but at least the absolute value of the difference between the radii, then the circles themselves intersect at some point.
The "at least the difference" part applies if you care only about the circles themselves, and not their inner areas. If you care whether the circles or the areas they enclose share any points -- that is, if one circle totally inside the other counts as "intersecting" to you -- then you can drop the "at least the difference" check.