constraints_ForcePivotConstraint.js
const Constraint = require("./Constraint");
const Particle = require("../core/Particle");
const Vector2D = require("../utils/Vector2D");
/**
* `ForcePivotConstraint` is a `Constraint` that limits the motion of a particle to a certain length away from a
* point in space. The implementation of this constraint is force-based like that of `ForceDistanceConstraint`.
* @extends {Constraint}
*/
class ForcePivotConstraint extends Constraint {
/**
* Instantiates new `ForcePivotConstraint`
* @param {Vector2D} pos - position of pivot
* @param {Particle} c1 - constrained particle
* @param {Number} len - constrained length
* @param {Number} stiffness - the "spring constant", higher values are more stiff
* @param {Number} breakForce - force at which the constraint breaks
* @param {Number} dampening - damping force on constraint, must be greater than 0
* @constructor
*/
constructor(pos, c1, len, stiffness, breakForce = Infinity, dampening = 0) {
super();
if (c1 === null) {
throw new Error("One of the particles is null!");
}
this.pos = pos;
this.c1 = c1;
this.breakForce = breakForce;
this.dampening = dampening;
this.stiffness = stiffness;
this.len = len;
this.color = "black";
this.force = new Vector2D(0,0);
}
/**
* @override
* @param {Number} timeStep
*/
update(timeStep) {
let dp = this.c1.pos.sub(this.pos);
let dpMag = dp.mag();
if(dpMag != 0) {
dp.multTo(1 / dpMag);
let dxMag = dpMag - this.len;
let dv = this.c1.vel;
let damp = this.dampening * dv.dot(dp);
this.force = dp.mult(-this.stiffness * dxMag - damp);
const a1 = this.force.mult(1 / this.c1.mass);
a1.multTo(timeStep * timeStep);
this.c1.pos.addTo(a1);
}
}
/**
* @override
* @returns {Vector2D[]}
*/
vertices() {
return [this.pos, this.c1.pos];
}
/**
* @override
* @returns {Particle[]}
*/
particles() {
return [this.c1];
}
/**
* @override
* @param {Number} timeStep
*/
applyCorrection(timeStep) {
return;
}
}
module.exports = ForcePivotConstraint;