top of page
Search
cedarcantab

Position Based Dynamics Bead on Wire


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



2 views0 comments

Recent Posts

See All

p2 naive broadphase

var Broadphase = require('../collision/Broadphase'); module.exports = NaiveBroadphase; /** * Naive broadphase implementation. Does N^2...

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js";...

Comments


記事: Blog2_Post
bottom of page