• Create Account

## 2D physics, random line geometry, many balls, and jitter problem

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

9 replies to this topic

### #1too_many_stars  Members

320
Like
1Likes
Like

Posted 21 April 2014 - 10:55 PM

Hi guys,

I have managed to cobble together a simple phyiscs simulation with random line geometry, and as many balls as I wish to create, all of which posses mass, resitituion and friction properties,

Collision and all of the physical properties seem to work fine, but I can't get the balls to settle, once they are close to rest, they keep jittering and bouncing slightly, and it's really unappealing. I tried implementing a threshold, but it did not solve my problem. Here's a section of the main loop.

		for(int i=0;i<balls.size();i++)
balls[i]->update((float)(SDL_GetTicks()-time));
time=SDL_GetTicks();

for(int i=0;i<balls.size();i++){//balls vs balls
for(int j=i+1;j<balls.size();j++){
V2 coll_normal;
if(balls[i]->checkBallColl(*balls[j],coll_normal)){
balls[i]->handleBallColl(*balls[j],coll_normal);
coll_normal.x*=-1;
coll_normal.y*=-1;
balls[j]->handleBallColl(*balls[i],coll_normal);
}
}
}
for(int i=0;i<lines.size();i++){//lines vs balls
for(int j=0;j<balls.size();j++){
V2 point(0,0);

if(balls[j]->checkLineColl(*lines[i],point)){
balls[j]->bounce(point);

}
}

}


I was wondering if anyone has a good perspective on settling the balls to a resting state.

Thanks,

Mike

### #2ultramailman  Prime Members

1720
Like
1Likes
Like

Posted 21 April 2014 - 11:16 PM

I don't understand the concept yet, but "speculative contacts" is one way to go.

http://www.wildbunny.co.uk/blog/2011/03/25/speculative-contacts-an-continuous-collision-engine-approach-part-1/

### #3too_many_stars  Members

320
Like
1Likes
Like

Posted 21 April 2014 - 11:21 PM

Hi Ultramailmain,

I have spent many hours on Paul's site ( I even purchased some of his code) but speculative contacts is out of comprehension right now I am afraid.

### #4ultramailman  Prime Members

1720
Like
1Likes
Like

Posted 21 April 2014 - 11:48 PM

Another way is to perform your collision solving step multiple times per frame, because solving collision once could lead to new collisions. So think of it as a fixed point method, refining your physics world the more times you run it.

### #5Olof Hedman  Members

5699
Like
1Likes
Like

Posted 22 April 2014 - 04:09 AM

Its a really tricky problem in all physics simulation.

In what way did the threshold "not work"?

That is a common approach to this problem, when the object is not moving enough, simply remove it from the simulation (deactivate it). Then reactivate it again when a (big enough) force acts upon it.

You could also try tweak dampening parameters.

It can also help running several iterations.

You can try change the scale of your simulation, to avoid floating point errors.

Apart from that, I don't know of much you can do except trying to implement more advanced collision handling.

Edited by Olof Hedman, 22 April 2014 - 04:10 AM.

### #6Stainless  Members

1875
Like
1Likes
Like

Posted 22 April 2014 - 07:23 AM

Can you post the code for handleBallColl?

Maybe we can see something in that.

### #7too_many_stars  Members

320
Like
1Likes
Like

Posted 22 April 2014 - 07:45 AM

Hi Stainless,

Sure, I will post the code tonight (I am at work now and can't do so until the evening)

Mike

### #8too_many_stars  Members

320
Like
1Likes
Like

Posted 23 April 2014 - 08:58 PM

Here are the bounce functions, one's for ball vs ball, the other ball vs line respectively

void Ball::bounce(RigidBody &rigid, V2 &coll_vect){

V2 difference=rigid.getVelocity()-velocity;
V2 contact_normal=coll_vect;
contact_normal.normalize();
float dot=contact_normal.dot(difference);

float mass_rat=(1+e)*(rigid.getMass()/(rigid.getMass()+mass));
if(dot>0){//if they are moving in the same direction
c.p.x=c.p.x-mass_rat*contact_normal.x;
c.p.y=c.p.y-mass_rat*contact_normal.y;
}
else{//bounce here
correction.x=correction.x+(mass_rat*dot)*contact_normal.x;
correction.y=correction.y+(mass_rat*dot)*contact_normal.y;
}

}

void Ball::bounceLine(V2 &point){

V2 coll_normal=c.p-point;
float coll_n_len=coll_normal.mag();
coll_normal.normalize();

c.p.x+=coll_normal.x*(c.r-coll_n_len);
c.p.y+=coll_normal.y*(c.r-coll_n_len);

float dot=velocity.dot(coll_normal);
correction.x-=(1+e)*(dot)*coll_normal.x;
correction.y-=(1+e)*(dot)*coll_normal.y;
}


As you can see it's the first function that's causing the jittering problem as it's impulse based while the other one ball vs line is after the fact position correction, that's why it's not jittering on the lines.

Any help would be greatly appreciated,

Thanks

Mike

### #9frob  Moderators

41248
Like
2Likes
Like

Posted 23 April 2014 - 11:32 PM

You write that you had a minimum threshold before and it didn't work out well. What didn't work about it?

You will need to have something that says "this is small enough, stop working", otherwise they may never come fully to rest.  You never say what your scale is, it is common to use 1.0 = 1 meter. Recall that a float can represent down to 1e-37. That is very tiny. For comparison, the size of an electron is about 1e-15 meters. Plank length, the smallest theoretically measurable distance in the universe, is about 1e-35. So without any threshold in place, you are telling the computer that any motion, even motion that is 1/100 of the smallest theoretical measurable distance, it is still a significant movement.

A physics engine absolutely needs a minimum threshold. Even a threshold like 1e-3 or 1e-6, at some point you need to accept that the number is small enough that it no longer matters.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

### #10too_many_stars  Members

320
Like
0Likes
Like

Posted 24 April 2014 - 08:01 AM

Thanks for the great and thoughtful reply frob. I tried to do things like

if(velocity<some small value) //dont check for collisions with other balls

but this caused more problems than it solved as all velocities start at V2(0,0), even though it did settle things down. Being a noob with physics engines (and programming in general), I am not exactly sure how to implement the threshold accurately as I don't fully understand the scope of the problem.

Initially it seemed like it would be rather simple to solve, but that has proven not to be the case.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.