Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Collision detection problem with bouncing and rolling balls

This topic is 5148 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

I'm working on a simple demo program in which a ball is dropped from a specific height and bounces off several slanted platforms. The collision detection I have implemented works fine when a ball bounces off a platform, but I am having difficulty getting the ball to roll (or slide, since I'm not dealing with angular velocity) along a platform. Instead, the ball simply falls right through the platform. (Example: If I drop the ball straight down onto a perfectly flat surface, it will bounce, and keep losing momentum until it gets to the point where it should just rest on the surface of the platform--but instead, it just falls through the bottom.) Here is the code I am using to handle collision detection and response:

// Each platform (or obstacle, "obst") is a triangle with vectors representing its three corners, and a normal vector.

// s is the position vector of the ball; v is its velocity vector.

// timestep is the length of a timestep.

// RayTriangleIntersection returns a very large number indicating no collision, or the parametric point of intersection

// (I think it's the amount of time in the future when the ray intersects the triangle)


if (RayTriangleIntersection(s, v, obst[i].corner[0],obst[i].corner[1], obst[i].corner[2], 1.0) <= timestep)
{
   v = v - ( obst[i].normal * ( v * obst[i].normal ) ) * 2; // calculate the bounce vector

   v *= 0.50; // temporary kludge for decaying ball momentum

}
Any suggestions? [edited by - mjs2000 on April 14, 2004 11:05:18 PM]

Share this post


Link to post
Share on other sites
Advertisement
Your problem ist the accuracy of float points, and you will not get around it this way at all.
Your velocity will get close to 0, and finally your ball will just slip through your plane.
There are two ways to fix it the fast way:

1) after a bounce calculate your new velocity like:
v = v - ( obst.normal * ( (v + 0.1) * obst.normal ) ) * 2

this way after a bounce you always give your ball a push away from the plane.

Problem: you add impulse energy into your system and it can "explode" (ball suddenly gets more and more energy and jumps away).


2) after a bounce you just lift your ball some away in direction of the plane normal.

Problem: same as with 1), only difference is the kind of energy you add to the system.


To solve this problem "correctly" you should work with an epsilon to get around the inaccuracy of calculations.


btw: v = v * 0.5 isn't the correct way to decay energy on bouncing, but a pretty easy one

edit: stupid italic code.

[edited by - OmniBrain on April 15, 2004 2:15:09 AM]

Share this post


Link to post
Share on other sites
It might be worthwhile taking a look at this and this topic regarding the circle sweep (one way of doing it) and this topic regarding the bouncing of the ball. Note that the code available in the first link has a bug that will most likely never be seen but I shall point it out anyway - if the circle is traveling toward an endpoint of the segment when the direction of the velocity is *exactly* the same as the direction of the line normal or the reversed direction of the line normal (ie the segment and the circle’s velocity have the same gradient) then the circle is not reflected properly - just handle it as a special case. Note sure if this is what you are looking for though.

[edited by - jack_1313 on April 15, 2004 3:35:56 AM]

Share this post


Link to post
Share on other sites
OmniBrain: Yeah, I figured it was floating-point error.

Impossible and jack_1313: I''ll check out that information on swept sphere collisions. Thanks!

Share this post


Link to post
Share on other sites
I had a similar problem a while ago, except in my case the ball would gradually lose height after each bounce but when the height got very low it would not come to rest, instead it would sit their bouncing very low as if it was vibrating...

Let me explain how my collision works:

1) detect collision - if there is a colision move the ball to the surface so that there is no overlap.

2) reflect the velocity of the ball.

This is why the vibration occurs when the ball should be at rest:

Lets assume that at the start of the frame the ball is stationary.
- First i apply my gravity to the velocity of the ball.
- Then the velocity is applied to move the position of the ball.
- The ball now lies a little beneath the surface.
- Collision detection moves the ball back to the surface.
- The velocity is then reflected

the problem is that at the end of all this, the ball has a small velocity away from the surface (the velocity is equal to the velocity it gained during the frame while dropping through the surface).

Now i assume you don''t have this problem yet because on colision detection you probably don''t move the ball, instead you just reflect the velocty. I would suggest that you do as i have, and then for the small issue of vibration i came up with this to fix it:

When i move the ball back to the surface i calculate the amount of potential energy i am giving the the ball by doing so. The formula is simple its PE = m*g*h (where m = mass of the ball, g = gravity constant, h = distance ball moved in direction of gravity). This is equal to the amount of kenetic energy the ball has gained by moving that small distance. So all i need to do is take away the Potential Energy gained from the Kenetic Energy. The formula for KE is, KE = 1/2*m*v^2 (where v = velocity of the ball in direction of gravity). If you re-arrange the equation you can calculate what velocity you must remove from the ball after collision detection, that is:

v = sqrt(2*g*h)

Note:

v = velocity in the direction of gravity (i.e. just take the z component of the velocity)
h = distance moved in the direction of gravity(i.e. again just take the z component of distance)

So you just subtract that from the velocity of the ball... And the result is that you have no more vibration at all while still allowing the ball to bounce as it should. Works great, even with very low frame rates (where the problem is the most visible without the fix).

Share this post


Link to post
Share on other sites
What I did, which may work out to the exact same thing as dealing with energy ( which I like ), was to always sweep the sphere a bit of extra distance, even if it wouldn''t get there this time period.

Then look for collisions, if one is found, only move the ball up to the point in time up until it exactly hits surface normal * ( 1.0f + Epsilon_Distance ). Then you move the ball there, take away that amount of time, then calculate the reflection / sliding, etc.

To do angular velocity I hacked it so that any time a collision happened, I took the cross product of the collision normal and resulting velocity to get the axis of rotation, then made the angular velocity equal to resulting velocity / 2pi.

I realize that doesn''t preserve energy, but it looked good to my eye...

I also completely simulate one ball''s timeslice before moving any other balls. This won''t work for low physics time-steps, but worked great for me, and simplified things.


Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!