public class Attraction implements Force { Particle a; Particle b; float k; boolean on; float distanceMin; float distanceMinSquared; public Attraction( Particle a, Particle b, float k, float distanceMin ) { this.a = a; this.b = b; this.k = k; on = true; this.distanceMin = distanceMin; this.distanceMinSquared = distanceMin*distanceMin; } protected void setA( Particle p ) { a = p; } protected void setB( Particle p ) { b = p; } public final float getMinimumDistance() { return distanceMin; } public final void setMinimumDistance( float d ) { distanceMin = d; distanceMinSquared = d*d; } public final void turnOff() { on = false; } public final void turnOn() { on = true; } public final void setStrength( float k ) { this.k = k; } public final Particle getOneEnd() { return a; } public final Particle getTheOtherEnd() { return b; } public 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 a2bDistanceSquared = a2bX*a2bX + a2bY*a2bY + a2bZ*a2bZ; if ( a2bDistanceSquared < distanceMinSquared ) a2bDistanceSquared = distanceMinSquared; float force = k * a.mass * b.mass / a2bDistanceSquared; float length = (float)Math.sqrt( a2bDistanceSquared ); // make unit vector a2bX /= length; a2bY /= length; a2bZ /= length; // multiply by force a2bX *= force; a2bY *= force; a2bZ *= force; // apply if ( a.isFree() ) a.force().add( -a2bX, -a2bY, -a2bZ ); if ( b.isFree() ) b.force().add( a2bX, a2bY, a2bZ ); } } public final float getStrength() { return k; } public final boolean isOn() { return on; } public final boolean isOff() { return !on; } }