Particles and forces
Cloth simulation involves modeling a system of particles that have mass and are interconnected by constraints.
To apply forces to these particles and determine how those forces affect their positions, we need two key components:
- Newton second law, to translate force into acceleration:
- Verlet integration, to translate acceleration into position:
Particle Class in Javascript :
function Particle( x, y, z, mass ) {
this.position = clothFunction( x, y ); // position
this.previous = clothFunction( x, y ); // previous
this.original = clothFunction( x, y );
this.a = new THREE.Vector3( 0, 0, 0 ); // acceleration
this.mass = mass;
this.invMass = 1 / mass;
this.tmp = new THREE.Vector3();
this.tmp2 = new THREE.Vector3();
}
Method add Force:
// Force -> Acceleration
Particle.prototype.addForce = function( force ) {
this.a.add(
this.tmp2.copy( force ).multiplyScalar( this.invMass )
);
};
Method for computing Verlet integration, slightly modified to include damping (where DRAG = 1 - DAMPING):
// Performs Verlet integration
Particle.prototype.integrate = function( timesq ) {
var newPos = this.tmp.subVectors( this.position, this.previous );
newPos.multiplyScalar( DRAG ).add( this.position );
newPos.add( this.a.multiplyScalar( timesq ) );
this.tmp = this.previous;
this.previous = this.position;
this.position = newPos;
this.a.set( 0, 0, 0 );
};
At this point, we have everything needed to move particles in space. Next, we must introduce constraints that will make this collection of particles behave like cloth. To do this, we’ll add connections that restrict particle movement and form a grid structure.
Position constraints
Our connections will be based on distance constraints between pairs of particles. Each constraint defines a preferred distance — the rest distance — that represents the cloth’s equilibrium state. To maintain this, we apply constraint satisfaction, which adjusts the positions of the two particles so that their separation returns to the rest distance.
In the example below, P1 and P2 are positioned too far apart:

To satisfy the constraint, we adjust the positions of P1 and P2 equally by a value called correctionHalf.
var diff = new THREE.Vector3();
function satisfyConstraints( p1, p2, distance ) {
diff.subVectors( p2.position, p1.position );
var currentDist = diff.length();
if ( currentDist === 0 ) return; // prevents division by 0
var correction = diff.multiplyScalar( 1 - distance / currentDist );
var correctionHalf = correction.multiplyScalar( 0.5 );
p1.position.add( correctionHalf );
p2.position.sub( correctionHalf );
}
Classe Cloth
The Cloth class is quite simple — it only requires a constructor that initializes a collection of particles along with their associated constraints.
Two types of constraints are used here:
