# Applying Simple Joints To 2D Particles

## Recommended Posts

I've got my particle system nailed down and I wanted to start working on joints. My first plan was to simply make a joint that kept two particles at a set distance apart. My implementation seems logical, but the joint behaves very strange. I'm using two particles with equal mass, but one always seems to swing around the other during collisions.
public override void Update(float dt)
{
Vector2 d = p1.position - p2.position;

if (d.LengthSquared() != (length * length))
{
//calculate each particle's "influence" on the joint
float p1Influence = p1.mass;
float p2Influence = p2.mass;

//figure out the total "influence" the joint has
float totalInfluence = p1Influence + p2Influence;

//get the percentage of influence for both particles.
//notice the reversal of the particle influence for
//the percentage. this percentage is the percentage
//of the correction distance each particle must move.
//hence the particle with the highest influence, has the
//lowest percentage it must move.
float p1Percentage = p2Influence / totalInfluence;
float p2Percentage = p1Influence / totalInfluence;

//get the correction distance and vector
float correctionDistance = d.Length() - length;
Vector2 correctionVector = p1.position - p2.position;
correctionVector.Normalize();

//move the particles
p1.position -= correctionVector * (p1Percentage * correctionDistance);
p2.position += correctionVector * (p2Percentage * correctionDistance);
}
}


##### Share on other sites
How are you handling the velocity change?

##### Share on other sites
Quote:
 Original post by Cowboy CoderHow are you handling the velocity change?

I totally forgot about that. Thanks. I'll go back through and try to do it with forces.

##### Share on other sites
So I tried again. I used the f=ma and p=v/t equations to come to equation f=pm/t2 (t-squared). Using this I applied it to my joint update method:

public override void Update(float dt)		{			Vector2 d = p1.position - p2.position;			if (d.LengthSquared() != (length * length))			{				//calculate each particle's "influence" on the joint				float p1Influence = p1.mass;				float p2Influence = p2.mass;				//figure out the total "influence" the joint has				float totalInfluence = p1Influence + p2Influence;				//get the percentage of influence for both particles.				//notice the reversal of the particle influence for				//the percentage. this percentage is the percentage				//of the correction distance each particle must move.				//hence the particle with the highest influence, has the				//lowest percentage it must move.				float p1Percentage = p2Influence / totalInfluence;				float p2Percentage = p1Influence / totalInfluence;				//get the correction distance and vector				float correctionDistance = d.Length() - length;				Vector2 correctionVector = p1.position - p2.position;				correctionVector.Normalize();				//apply the forces				p1.ApplyForce(-(correctionVector * (correctionDistance * p1Percentage)) * p1.mass / (dt * dt));				p2.ApplyForce(correctionVector * (correctionDistance * p2Percentage) * p2.mass / (dt * dt));			}		}

It works to a degree. It looks better than it did before, but my particles now never come to rest and actually appear to shiver. In my main physics code, I do a loop three times that first updates all the particles, checks for terrain collision, and then handles the joint problems. Any ideas where I'm going wrong?

Edit:
I've combined my methods and compensated for the fact that this is called three times per frame by making the last part into this:
				p1.position -= correctionVector * (p1Percentage * correctionDistance);				p2.position += correctionVector * (p2Percentage * correctionDistance);				p1.ApplyForce(-(correctionVector * (correctionDistance * p1Percentage)) * p1.mass / (dt * dt) / 3f);				p2.ApplyForce(correctionVector * (correctionDistance * p2Percentage) * p2.mass / (dt * dt) / 3f);

So now my joints act correctly, but it still seems to never want to completely come to rest. I thought about using a velocity cutoff in my particles, but I couldn't implement it properly. My particles usually reach a point where they are (visually) at rest, but when I use joints, I can clearly see it shivering.

[Edited by - NickGravelyn on March 19, 2007 5:39:08 PM]

##### Share on other sites
Well,
if (d.LengthSquared() != (length * length))
is never going to return false, so they are never going to settle. You need some kind of epsilon range if you want them to actually stop.

You might also want to look at verlet integration for this kind of thing. For example, see my blob code.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628381
• Total Posts
2982360

• 10
• 9
• 15
• 24
• 11