Advertisement

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

Started by April 22, 2014 04:55 AM
8 comments, last by too_many_stars 10 years, 9 months ago

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

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/

Advertisement

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.

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.

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.

Can you post the code for handleBallColl?

Maybe we can see something in that.

Advertisement

Hi Stainless,

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

Mike

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

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.

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.

This topic is closed to new replies.

Advertisement