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

    */
 ...