## Collision Detection between 2 circles

cheatdeath
Unregistered

Post: #1
I'm working on a new game, it allows 2 players to move rackets around inside a ring and hit a ball. If the ball hits a wall twice before the next players turn you lose, etc.
How would I go about doing the collision between the ball and the court.

Sage
Posts: 1,403
Joined: 2005.07
Post: #2
I dont know how you would do It but I would do:

the small ball is A
the large ball is B

[SOURCECODE]
xd = A.x-B.x;
yd = A.y-B.y;

xd *= xd;
yd *= yd;

if(xd+yd >= (B.r - A.r)^2)
collision
[/SOURCECODE]

then for collision response,

[SOURCECODE]
dst = sqrt(xd*xd+yd*yd);

xd /= dst;
yd /= dst;

vel = sqrt(A.velocity.x*A.velocity.x + A.velocity.y*A.velocity.y);

A.velocity.x = xd*vel;
A.velocity.y = yd*vel;
[/SOURCECODE]

Sir, e^iÏ€ + 1 = 0, hence God exists; reply!
cheatdeath
Unregistered

Post: #3
I think i'm actually looking for handling the collision rather than just detecting it. Thank a million anyway.
Sage
Posts: 1,403
Joined: 2005.07
Post: #4
thats both...

Sir, e^iÏ€ + 1 = 0, hence God exists; reply!
cheatdeath
Unregistered

Post: #5
Somethings wrong, the ball only bounces when the velocity or coords are negative.

Meaning it only bounces when its in the bottom left quadrant, the center is (0,0).
Sage
Posts: 1,403
Joined: 2005.07
Post: #6
I think line 1 of the second source code should be
dst = sqrt(xd+yd);

and printf each time a collision occurs, make sure its only happening once per frame (event though that makes no difference here)

Sir, e^iÏ€ + 1 = 0, hence God exists; reply!
Moderator
Posts: 460
Joined: 2002.09
Post: #7
Quote:I think line 1 of the second source code should be
dst = sqrt(xd+yd);
I believe the author squared both sides of the equation in order to avoid a square-root operation. (I suspect the bug is in the collision response code.)

1 - A safety check you can add to the collision detection is to check that the ball's velocity is towards the wall in question. If it's already moving away from the wall then don't collide it. That way, if it doesn't move far enough in that frame to no-longer intersect the wall, the hit won't be detected again in the next frame.

1b - Alternately, you can try to guarantee that it won't intersect the wall again in the code that responds to the collision. One method is to compute where the intersection actually took place and "back up" the ball to that point. This could be done mathematically for simple geometry, or it can be done iteratively (move the ball back and forth in decreasing increments until it's right up against the wall without intersecting it.)

1c. If the geometry is simple you can take this a step further and mathematically compute where the next collision will be, rather than detecting a collision that has already happened. That's how my old game 3D Brick Bash worked. It has an advantage in that a slow frame rate will not cause objects to pass through each other.

Measure twice, cut once, curse three or four times.
Sage
Posts: 1,403
Joined: 2005.07
Post: #8
Assuming you have this working now bear in mind the ball will be moving directly towards the center of the circle, the what you need to do is reflect to velocity around the normal (xd, yd).
A good explanation of the maths of that is here:
http://astronomy.swin.edu.au/~pbourke/ge...reflected/

1 this is not required because even if something is moving away you still want to check for collisions.

1b if you do move an object directly this is like creating or destroying energy which is impossible and will lead to an unstable situation, you should subdivide the timestep to find the exact time of collision and perform the response calculations at that instance.

Sir, e^iÏ€ + 1 = 0, hence God exists; reply!
Member
Posts: 196
Joined: 2003.10
Post: #9
Funny. Looks a lot like this: http://idevgames.com/forum/showthread.php?t=10427

Hope you have more success than I did.
Member
Posts: 41
Joined: 2006.01
Post: #10
if you just want to know if 2 circles intersect can't you just go like so:

Code:
```bool BallHitsRing(float x, float y, float r, float ringRadius) {     return x * x + y * y + r > ringRadius; }```
(assuming your ring center is at {0, 0})

Also, the ball should bounce off the ring's tanget line at the point of impact. The angle the ball's path makes with the line from the center of the ring to the point of impact should be the same on either side (if you follow me).
Moderator
Posts: 460
Joined: 2002.09
Post: #11
unknown Wrote:1 this is not required because even if something is moving away you still want to check for collisions.
If you've allowed the object to enter the wall, then you do not want to detect in the next frame that the ball is still inside the wall (if it still is) and reflect the velocity vector again. One way or another you have to let the ball leave the wall again.
Quote:1b if you do move an object directly this is like creating or destroying energy which is impossible and will lead to an unstable situation, you should subdivide the timestep to find the exact time of collision and perform the response calculations at that instance.
That's pretty much what I describe in 1b, but I didn't explicitly mention that the time of collision also needs to be moved forward and backwards along with the position- my bad. (There's nothing unstable about what I described though. This is a simple function for calculating the ball's next position, nothing more.)

Measure twice, cut once, curse three or four times.