Advertisement

Verlet integration spring system question

Started by May 25, 2006 08:20 PM
6 comments, last by rip-off 8 years, 7 months ago
Hi everyone... I'm trying to implement Verlet integration into my mass spring system and I'm getting strange results. Whenever the grid is disturbed it keep's accumulating force and never comes to rest (and depending on the K_coef value sometimes get's unstable and totally breaks). Here's some code snippets:

void Spring::ComputeForce(float k_coef)
{
	float     intensity;
	float     delta;
	Vector	  force_dir;
	Vector dv;
	float damping = 0;
	//get the distance
	float  dx =   nodeB->pos.x-nodeA->pos.x;
	float  dy =   nodeB->pos.y-nodeA->pos.y;
	CurrDistance = (float) sqrtf ((dx*dx)+(dy*dy));

	force_dir.x = dx;
	force_dir.y = dy;
	force_dir.x /= CurrDistance;
	force_dir.y /= CurrDistance;

	delta = CurrDistance-restLength;
	//0.5 is the K value
	intensity = 0.5*delta;
	ComputedForce.x = force_dir.x*(intensity);
	ComputedForce.y = force_dir.y*(intensity);

	nodeA->force+=ComputedForce;
	nodeB->force-=ComputedForce;
}

here's the verlet integration part (this is called for every node in the system):

resultant = 0;
// move nodes away from ship (this causes disturbance as it moves nodes away from each other
Vector temp(node_curr->GetPosition().x - ShipPos.x,
  	    node_curr->GetPosition().y - ShipPos.y,
	    node_curr->GetPosition().z - 0);
if (sqrtf(temp.x * temp.x + temp.y * temp.y + temp.z * temp.z) < 30 )
{
     SpringComputeSingleForce(&force_tmp, &node_curr->pos, &ShipPos, k_coef, 0);
	 			resultant.x -= 5*force_tmp.x;
				resultant.y -= 5*force_tmp.y;
}
node_curr->force += resultant;
				
// Verlet part
temp = node_curr->pos;
node_curr->pos.x += node_curr->pos.x - node_curr->LastPos.x + node_curr->force.x *dt*dt;
node_curr->pos.y += node_curr->pos.y -   node_curr->LastPos.y + node_curr->force.y *dt*dt;
node_curr->LastPos = temp;
}

Now, my question is basically what mechanism is supposed to keep forces from gaining force? why doesn't my system behave like it does when i use euler integration, where it goes to back to it's original position with no problems? Any insight would be much appreacited! Ehud.
You forgot to apply damping
Advertisement
Uhhhh...
I'm not really certain how damping works with verlet integration.
I thought damping is used on the velocity itself, but since verlet does not use velocity, how exactly can I damp it?

Also, 2 other issues that i'm currently thinking of:
1. is there a standard way to connect a cloth like mass spring system?
I'm currently using a very connected grid of nodes and that's really having a bad impact on performance. My current system is that each node is connected to all 8 neighbours and 4 diagonal 2nd degree neghibours (totalling in 12 springs per node, which adds up to around 10000+ in my grid).
That's a lot of forces to calculate, and I was wondering if there's a smarter way (that still keeps the system stable of course).

2. Why is it that when i'm using euler integration i find that lower K values work better, and using verlet I need to work with much larger K values? How does K actually affects the system?

Thanks!
Quote: 1. is there a standard way to connect a cloth like mass spring system?


I can't remember off the top of my head, but the book "Physics for Game Developers" had a chapter on springs. In it, was a cloth example using springs. I'm not at home to check my book, so I'm not entirely sure if it used verlet or runge-kutta. If you could get a hold of a copy of that book it may help.

The more I think about it, the example probably used runge-kutta. Sorry I couldn't offer more help.
Quote: Uhhhh...
I'm not really certain how damping works with verlet integration.
I thought damping is used on the velocity itself, but since verlet does not use velocity, how exactly can I damp it?


I think you can do something like this:
// Verlet partfloat dampFactor=0.9f;temp = node_curr->pos;node_curr->pos.x += (node_curr->pos.x - node_curr->LastPos.x) * dampFactor+ node_curr->force.x *dt*dt;node_curr->pos.y += (node_curr->pos.y -   node_curr->LastPos.y) * dampFactor+ node_curr->force.y *dt*dt;node_curr->LastPos = temp;
Thanks, works wonderfully :)
Advertisement

Correct me if I'm wrong but I think velocity should not be mul by dampen just like that but by Pow(damp, deltaTime). That is correct for Euler integration. at least, I'm not sure how it works for Verlet so I would appreciate if someone could verify this.

Thanks, but please don't reply to such old threads.

This topic is closed to new replies.

Advertisement