Fast circle collision

Started by
7 comments, last by endasil 20 years, 5 months ago
I''m working with a very simple game to test some things. It has two circles that can be moved around screen and collide with each other. To make it easier to calculate in what direction the circles should move when colliding, i decided to cut the circle into four pices. What would the fastest wayto determin what sides of the circle that has collided be? Counting them as simple squares was the first thing that came to my mind, but then it could count as a collision even if the circles never actually touch eachother on the screen. I don''t know if a player would find this annoying, but for someone who is trying to find things to complain on, it could be. Is there a better way that is still as simple as square collision but more exact?
EndasilVisit my site, try my gameswww.dragonrealmsoftware.comI need more beta tester for my game! Check out http://www.dragonrealmsoftware.com
Advertisement
Two circles collide when their center is apart less then the sum of the two radius'' (sp?).

As you probably want the exact point of collission, take the line (vector) between the two centers. With the angle of the line you should be able to tell the exact point on each of the circles.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

radii :D
If you are using perfect circles you can simply calulate the distance between the centers of the circles and then test the distance against the sum of their radii.
I need something a like this for a thing im working on...

Would it be something like:

if a.radius + b.radius = SQRT((a.x - b.x)^2 + (a.y - b.y)^2)

or would it be better to do:

if (a.radius + b.radius)^2 = (a.x - b.x)^2 + (a.y - b.y)^2)
those both look like they would work.. the 2nd one without the sqrt would probably be faster. Just be careful using the equal sign for your comparisons. The distance and radii comparison might not always be exactly equal, so it would be better to use greater than or equal to " >= ".
The second method would probably be better.

______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Formats______________________________________________________________________________________
Fastest would indeed be a detection without sqrt()... because apparently the sqrt() function takes around 70 cycles, whereas multiplication takes 1-3 cycles. Significant difference, eh?

But, to break it down, start to finish:

distance=sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
if(distance <= (radius1 + radius2))
{
//collision has occured. code here.
}

That''s the SLOW version. To speed it up, slightly, you can do this:

//let''s call these pcx/y for pre-calculated
float pcx=(x1-x2);
float pcy=(y1-y2);

distance=sqrt(pcx*pcx + pcy*pcy);
if(distance <= (radius1 + radius2))
{
//collision has occured. code here.
}

Now, to speed it up further, remove the sqrt():
//let''s change distance to distsqr for distance squared.

float pcx(x1-x2);
float pcy(y1-y2);

distsqr=(pcx*pcx+pcy*pcy);
if(distsqr <= ((radius1 + radius2)*(radius1 + radius2)))
{
//collision has occured. code here.
}

And there, you have a fast circle detection algorithm. You could even modify it to be a sphere fairly easy, for 3d detection. The only problem you may encounter with this is having an overflow, since the actual numbers may get rather large. For instance, say radius1 is 1000 and radius2 is 2000, right there you have 3000^2 or 9000000! It depends on what you are doing, but this could be a problem.

You should check out this very good article on the subject.
You are not the one beautiful and unique snowflake who, unlike the rest of us, doesn't have to go through the tedious and difficult process of science in order to establish the truth. You're as foolable as anyone else. And since you have taken no precautions to avoid fooling yourself, the self-evident fact that countless millions of humans before you have also fooled themselves leads me to the parsimonious belief that you have too.--Daniel Rutter

This topic is closed to new replies.

Advertisement