Sign in to follow this  

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

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

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Sorry for the belated reply.

 

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

This topic is 1363 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this