Demo Code from this video
class Bead {
constructor(radius, mass, pos) {
this.radius = radius;
this.mass = mass;
this.pos = pos.clone();
this.prevPos = pos.clone();
this.vel = new Vector2();
}
startStep(dt, gravity) {
this.vel.add(gravity, dt);
this.prevPos.set(this.pos);
this.pos.add(this.vel, dt);
}
keepOnWire(center, radius) {
var dir = new Vector2();
dir.subtractVectors(this.pos, center);
var len = dir.length();
if (len == 0.0)
return;
dir.scale(1.0 / len);
var lambda = physicsScene.wireRadius - len;
this.pos.add(dir, lambda);
return lambda;
}
endStep(dt) {
this.vel.subtractVectors(this.pos, this.prevPos);
this.vel.scale(1.0 / dt);
}
}
// --- collision handling -------------------------------------------------------
function handleBeadBeadCollision(bead1, bead2)
{
var restitution = 1.0;
var dir = new Vector2();
dir.subtractVectors(bead2.pos, bead1.pos);
var d = dir.length();
if (d == 0.0 || d > bead1.radius + bead2.radius)
return;
dir.scale(1.0 / d);
var corr = (bead1.radius + bead2.radius - d) / 2.0;
bead1.pos.add(dir, -corr);
bead2.pos.add(dir, corr);
var v1 = bead1.vel.dot(dir);
var v2 = bead2.vel.dot(dir);
var m1 = bead1.mass;
var m2 = bead2.mass;
var newV1 = (m1 v1 + m2 v2 - m2 (v1 - v2) restitution) / (m1 + m2);
var newV2 = (m1 v1 + m2 v2 - m1 (v2 - v1) restitution) / (m1 + m2);
bead1.vel.add(dir, newV1 - v1);
bead2.vel.add(dir, newV2 - v2);
}
var physicsScene =
{
gravity : new Vector2(0.0, -10.0),
dt : 1.0 / 60.0,
numSteps : 100,
wireCenter : new Vector2(),
wireRadius : 0.0,
beads : [],
};
// ------------------------------------------------
function simulate()
{
var sdt = physicsScene.dt / physicsScene.numSteps;
for (var step = 0; step < physicsScene.numSteps; step++) {
for (var i = 0; i < physicsScene.beads.length; i++)
physicsScene.beads[i].startStep(sdt, physicsScene.gravity);
for (var i = 0; i < physicsScene.beads.length; i++) {
physicsScene.beads[i].keepOnWire(
physicsScene.wireCenter, physicsScene.wireRadius);
}
for (var i = 0; i < physicsScene.beads.length; i++)
physicsScene.beads[i].endStep(sdt);
for (var i = 0; i < physicsScene.beads.length; i++) {
for (var j = 0; j < i; j++) {
handleBeadBeadCollision(
physicsScene.beads[i], physicsScene.beads[j]);
}
}
}
}
USeful References
Comments