Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast circle collision detection

I'm trying to write a method that will calculate if two circles are overlapping. I've come up with the following and I'm just curious to know if there is anyway it could be optimised further.

private static boolean isCollision(Point2D p1, float r1, Point2D p2, float r2)
{
    float a,dx, dy;
    a = (r1+r2) * (r1+r2);
    dx = (float) (p1.getX() - p2.getX());
    dy = (float) (p1.getY() - p2.getY());

    if (a > (dx*dx) + (dy*dy))
    {
        return true;
    }
    return false;
}
like image 853
Oli Avatar asked Mar 30 '09 13:03

Oli


2 Answers

Hmm. That looks pretty good as far as the math goes. Some minor points on how to make the Java side of it faster and terser:

  • If you used doubles instead of floats for the radii, you wouldn't have to down-cast the doubles to floats.
  • If you specifically ask for Point2D.Double parameters, you can use their x and y public fields instead of using the getters.
  • Also, why the if (foo) { return true; } else { return false; }? Just do return foo;!

An improved version, then:

private static boolean isCollision(Point2D.Double p1, double r1, Point2D.Double p2, double r2)
{
    final double a = r1 + r2;
    final double dx = p1.x - p2.x;
    final double dy = p1.y - p2.y;
    return a * a > (dx * dx + dy * dy);
}

(Note that if your code is entirely float-based, you can do the same thing with Point2D.Float and floats.)

like image 122
Zarkonnen Avatar answered Oct 11 '22 12:10

Zarkonnen


Overlap or intersect?

If intersect, don't forget about the case where the circles don't intersect because they are inside each other.

If it's overlap, I don't really see how you could optimize further; you're comparing the point distances to the sum of the radii, using distance squared to avoid taking a square root. Doesn't seem like there's any fat left to trim.

like image 39
Jason S Avatar answered Oct 11 '22 12:10

Jason S