Jump to content
  • Advertisement
Sign in to follow this  
egg100

Basic Collision Detection Problem

This topic is 4836 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This must be a fundamental issue in basic collision detection. I'm trying to make a snooker game and its all working fine except for a major issue with the ball collisions. I iterate through every ball, and create a vector between 2 balls. If the vector magnitude is greater than 2*radius then a collision has happened. All very simple. Problem is that after a collision, the collided balls are closer than 2*radius and do not always seperate in time for the next collision detection. They therefore get stuck permanently colliding with each other. Is there a standard way of getting around this problem?

Share this post


Link to post
Share on other sites
Advertisement
What you are doing is testing for static object-object intersection. What you are not taking into account is the fact that the balls are moving. This can complicate the collision detection process a lot, especially if both balls being tested for collisions are moving. I believe a moving sphere or circle can be represented as a 2d or 3d capsule, but you should do some research to find out more.

If your balls are not moving too quickly (ie. there is no chance of a ball going straight through another ball), you can get away with static-static intersection tests by adjusting the position of the balls when an intersection is detected, before you do anything physics related or stop the ball. If only one ball is moving, this is very easy: After detecting the collision, keep the vector you used between the two balls. Set its length to 2*radius. Then: MovingBall.Center =StaticBall.Center +DistanceVector (where DistanceVector is the vector between the two balls). This is not all that accurate, but it is very fast and works well in most situations.

After that, you can apply forces to the ball or stop it or whatever it is balls do in a snooker like game :). If both balls are moving, then you have to take their velocities into account. You should be able to find articles on such collision prevention and handling on the Internet.

Hope that helps; good luck :)

Share this post


Link to post
Share on other sites
Ok that seems to make sense.
I dont think there's a chance of the balls going fast enough to completely miss each other so i'll try and adjust the ball positions so the distance is 2*rad before I do anything else. I suppose the difficult thing is that if both balls are moving at different vels then adjusting thier positions acuarately so they are 2*rad apart. I'll give it a go.
Thanks very much for the tip.

Share this post


Link to post
Share on other sites
I did something like this to test for moving ball collisions in a billiards game:

**(For some reason all my 'plus' signs disappeared in the preview, so I replaced them with '?')



//update position
ball_a[XPOSITION] ? =ball_a[XVELOCITY];
ball_a[YPOSITION] ? =ball_a[YVELOCITY];
ball_b[XPOSITION] ? =ball_b[XVELOCITY];
ball_b[YPOSITION] ? =ball_b[YVELOCITY];

//compute the distance between ball centers
float nabx = (ball_b[XPOSITION] - ball_a[XPOSITION] );
float naby = (ball_b[YPOSITION] - ball_a[YPOSITION] );
float length = sqrt(nabx*nabx ? naby*naby);

// is there a collision?
//3*RAD is an experimental value, the faster balls travel the bigger it should be
//if balls are within 3*radius, test to see if they collided
if (length <= 3*RAD){
//first put them back where they were at the beginning of the frame
ball_a[XPOSITION]-=ball_a[XVELOCITY];
ball_a[YPOSITION]-=ball_a[YVELOCITY];
ball_b[XPOSITION]-=ball_b[XVELOCITY];
ball_b[YPOSITION]-=ball_b[YVELOCITY];

double counter=0;
double steps=MAX_VELOCITY;

//now step through their positions in increments of 1/MAX_VELOCITY
while(counter < steps){
ball_a[XPOSITION]?=(1/steps)*ball_a[XVELOCITY];
ball_a[YPOSITION]?=(1/steps)*ball_a[YVELOCITY];
ball_b[XPOSITION]?=(1/steps)*ball_b[XVELOCITY];
ball_b[YPOSITION]?=(1/steps)*ball_b[YVELOCITY];

//compute the distance again
nabx = (ball_b[XPOSITION] - ball_a[XPOSITION] );
naby = (ball_b[YPOSITION] - ball_a[YPOSITION] );
length = sqrt(nabx*nabx ? naby*naby);

//if they are 2*radius or less, there is a collision at the current positions
//so break out of the loop
if(length<=2*RAD){
break;
}

counter?=1;

}//end while loop

//if length is 2*radius or less, process the collision
if(length<=2*RAD){
process_collision();
}
}




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!