Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if circle A is completely inside circle B

Below is a function that detects if two circles intersect. I want to change it to only detect if the periferi of the circles intersect. Hence, if circle A is completely inside circle B, there is no collision!

How?

private bool IsCircleCollision(
    int x1, int y1, int radius1,
    int x2, int y2, int radius2)
{
    int dx = x2 - x1;
    int dy = y2 - y1;

    int distance = (dx * dx) + (dy * dy);

    int radii = radius1 + radius2;
    if (distance < radii * radii)
    {
        return true;
    }
    else
    {
        return false;
    }
}
like image 594
l33t Avatar asked Jan 15 '23 15:01

l33t


1 Answers

You work this out by calculating the distance between the two centres, D say. There is an intersection if

abs(R1-R2) < D < R1+R2

where R1 and R2 are the radii of the two circles.

The first test, abs(R1-R2) < D handles the case when one circle's centre is inside the other's. And the second test, D < R1+R2, handles the case when neither circle contains the other's centre.

So, adapting your code we have:

private bool IsCircleCollision(
    int x1, int y1, int radius1,
    int x2, int y2, int radius2)
{
    int dx = x2 - x1;
    int dy = y2 - y1;

    double D = Math.Sqrt(dx*dx + dy*dy);
    return Math.Abs(radius1-radius2)<D && D<radius1+radius2;
}

If performance is important here, you can do without the call to Math.Sqrt like this:

private bool IsCircleCollision(
    int x1, int y1, int radius1,
    int x2, int y2, int radius2)
{
    int dx = x2 - x1;
    int dy = y2 - y1;

    int Dsqr = dx*dx + dy*dy;
    int rdiff = Math.Abs(radius1-radius2);
    int rsum = radius1+radius2
    return rdiff*rdiff<Dsqr && D<rsum*rsum;
}
like image 53
David Heffernan Avatar answered Jan 22 '23 07:01

David Heffernan