Jump to content

  • Log In with Google      Sign In   
  • Create Account


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

  • You cannot reply to this topic
8 replies to this topic

#1 too_many_stars   Members   -  Reputation: 184

Like
0Likes
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



Sponsor:

#2 ultramailman   Prime Members   -  Reputation: 1467

Like
0Likes
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/



#3 too_many_stars   Members   -  Reputation: 184

Like
0Likes
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.



#4 ultramailman   Prime Members   -  Reputation: 1467

Like
0Likes
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.



#5 Olof Hedman   Crossbones+   -  Reputation: 2227

Like
0Likes
Like

Posted Yesterday, 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, Yesterday, 04:10 AM.


#6 Stainless   Members   -  Reputation: 449

Like
0Likes
Like

Posted Yesterday, 07:23 AM

Can you post the code for handleBallColl?

 

Maybe we can see something in that.



#7 too_many_stars   Members   -  Reputation: 184

Like
0Likes
Like

Posted Yesterday, 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



#8 too_many_stars   Members   -  Reputation: 184

Like
0Likes
Like

Posted Today, 08:58 PM

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



#9 frob   Moderators   -  Reputation: 16324

Like
0Likes
Like

Posted Today, 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 personal indie blog at bryanwagstaff.com.





PARTNERS