package efruchter.particles.constraints.soft;
import efruchter.particles.constraints.Constraint;
import efruchter.particles.datatypes.Particle;
import efruchter.vectorutils.Vector3;
/**
* A simple, cheap constraint type that can be iterated for speed v. accuracy.
* Min/max versions of this can be found in this package.
*
* @author toriscope
*
*/
public class DistanceConstraint extends Constraint {
protected float dist, squish;
public static float DEFAULT_SQUISH = .5f;
protected float scale = .5f;
/**
* Create a constraint with a given distance and squish, with 0 as maximum
* give, and 1 as no give.
*
* @param a
* particle a.
* @param b
* particle b.
* @param dist
* distance between particles.
* @param squish
* the amount of give.
*/
public DistanceConstraint(final Particle a, final Particle b,
final float dist, final float squish) {
super(a, b);
this.dist = dist;
this.squish = squish;
}
public DistanceConstraint(final Particle a, final Particle b) {
this(a, b, a.x.distance(b.x), DEFAULT_SQUISH);
}
/**
* Move the particles a/b to satisfy constraint.
*/
public void satisfy() {
Vector3 x1 = this.a.x, x2 = this.b.x;
Vector3 delta = x2.sub(x1);
delta = delta.scale(dist * dist / (delta.dot(delta) + dist * dist) - scale);
this.a.x = x1.sub(delta.scale(squish * a.m));
this.b.x = x2.add(delta.scale(squish * b.m));
super.satisfy();
}
}