public class Spring implements Force { float springConstant; float damping; float restLength; Particle a, b; boolean on; public Spring( Particle A, Particle B, float ks, float d, float r ) { springConstant = ks; damping = d; restLength = r; a = A; b = B; on = true; } public final void turnOff() { on = false; } public final void turnOn() { on = true; } public final boolean isOn() { return on; } public final boolean isOff() { return !on; } public final Particle getOneEnd() { return a; } public final Particle getTheOtherEnd() { return b; } public final float currentLength() { return a.position().distanceTo( b.position() ); } public final float restLength() { return restLength; } public final float strength() { return springConstant; } public final void setStrength( float ks ) { springConstant = ks; } public final float damping() { return damping; } public final void setDamping( float d ) { damping = d; } public final void setRestLength( float l ) { restLength = l; } public final void apply() { if ( on && ( a.isFree() || b.isFree() ) ) { float a2bX = a.position().x - b.position().x; float a2bY = a.position().y - b.position().y; float a2bZ = a.position().z - b.position().z; float a2bDistance = (float)Math.sqrt( a2bX*a2bX + a2bY*a2bY + a2bZ*a2bZ ); if ( a2bDistance == 0 ) { a2bX = 0; a2bY = 0; a2bZ = 0; } else { a2bX /= a2bDistance; a2bY /= a2bDistance; a2bZ /= a2bDistance; } // spring force is proportional to how much it stretched float springForce = -( a2bDistance - restLength ) * springConstant; // want velocity along line b/w a & b, damping force is proportional to this float Va2bX = a.velocity().x - b.velocity().x; float Va2bY = a.velocity().y - b.velocity().y; float Va2bZ = a.velocity().z - b.velocity().z; float dampingForce = -damping * ( a2bX*Va2bX + a2bY*Va2bY + a2bZ*Va2bZ ); // forceB is same as forceA in opposite direction float r = springForce + dampingForce; a2bX *= r; a2bY *= r; a2bZ *= r; if ( a.isFree() ) a.force().add( a2bX, a2bY, a2bZ ); if ( b.isFree() ) b.force().add( -a2bX, -a2bY, -a2bZ ); } } protected void setA( Particle p ) { a = p; } protected void setB( Particle p ) { b = p; } }