Spring Mass System
by soulwire
HTML
<canvas id="canvas" width="500" height="500"></canvas>
JavaScript
var phys = phys || {};
var GRAVITY = 0.5;
/**
* Vector
*/
Vec2 = function(x, y) {
this.set(x, y);
};
Vec2.prototype = {
// Sets the vector components
set: function(x, y) {
this.x = x || 0.0;
this.y = y || 0.0;
},
// Adds a vector to this one
add: function(vec) {
this.x += vec.x;
this.y += vec.y;
return this;
},
// Subtracts a vector from this one
sub: function(vec) {
this.x -= vec.x;
this.y -= vec.y;
return this;
},
// Divides components by scalar
div: function(f) {
this.x /= f;
this.y /= f;
},
// Multiplies components by scalar
scale: function(f){
this.x *= f;
this.y *= f;
return this;
},
// Normalise / create unit vecotr
norm: function(){
var len = this.length();
this.x /= len;
this.y /= len;
},
// Length / magnitude of vector
length: function() {
// Length is hypotenuse, so: l^2 = a^2 + b^2 = c^2 or l = sqrt(c^2)
return Math.sqrt(this.x * this.x + this.y * this.y);
},
// Creates a copy
clone: function(){
return new Vec2(this.x, this.y);
}
};
/**
* Particle
*/
phys.Particle = function(x, y, mass) {
this.pos = new Vec2(x, y);
this.vel = new Vec2();
this.acc = new Vec2();
this.mass = mass || 1.0;
this.fixed = false;
};
phys.Particle.prototype = {
draw: function(ctx){
ctx.beginPath();
ctx.arc(this.pos.x, this.pos.y, 3, 0, Math.PI * 2);
ctx.stroke();
ctx.fill();
}
};
/**
* Spring
*/
phys.Spring = function(p1, p2, restlength, k) {
// Tightness of the spring
this.k = k || 0.5;
// Damping coefficient
this.damping = 0.05;
// The desired length of the constraint
this.restlength = restlength || 10;
// A spring connects 2 particles
this.p1 = p1 || new phys.Particle();
this.p2 = p2 || new phys.Particle();
};
phys.Spring.prototype = {
update: function(){
/*
http://www.myphysicslab.com/spring1.html
http://www.myphysicslab.com/spring2d.html
*/
...