xxxxxxxxxx
82
// press mouse button to activate repulsion
var positions = [];
var velocities = [];
var isChild = [];
var numLinks = 50;
var linkLength = 6;
var chainStart = 100;
var gravity;
constrainIterations = 20;
var simSpeed = 1;
function setup() {
createCanvas(480, 640);
gravity = createVector(0, 2);
// create links
var offset = createVector(width/2, chainStart);
for(var i = 0; i < numLinks; i++) {
var offsetX = random(-linkLength, +linkLength);
var offsetY = sqrt(linkLength**2 - offsetX**2);
positions.push(offset.copy());
velocities.push(createVector());
isChild.push(true);
offset.x += offsetX;
offset.y += offsetY;
}
}
function draw() {
background(240);
var pendingVelocities = [];
for(var i = 1; i < numLinks; i++) {
var pos1 = positions[i];
// draw
var pos2 = positions[i-1];
line(pos1.x, pos1.y, pos2.x, pos2.y);
}
for(var it = 0; it < constrainIterations; it++) {
for(var i = 1; i < numLinks; i++) {
// simulate gravity
velocities[i].add(p5.Vector.div(gravity, constrainIterations/simSpeed));
// mouse force
var mouseVector = positions[i].copy();
mouseVector.sub(createVector(mouseX, mouseY));
mouseVector.setMag((mouseVector.mag() ** (-2))*5000);
if(mouseIsPressed) {
velocities[i].add(p5.Vector.div(mouseVector, constrainIterations/simSpeed));
}
// forces between links
// backward
var backward = p5.Vector.sub(positions[i], positions[i-1])
backward.normalize();
var dot = velocities[i].dot(backward);
backward.mult(dot);
velocities[i].sub(p5.Vector.div(backward, constrainIterations/simSpeed));
velocities[i-1].add(p5.Vector.div(backward, constrainIterations/simSpeed));
// forward
if(i < numLinks-1 && false) {
var forward = p5.Vector.sub(positions[i+1], positions[i])
backward.normalize();
var dot = velocities[i].dot(backward);
backward.mult(dot);
velocities[i].add(p5.Vector.div(backward, constrainIterations/simSpeed*2));
velocities[i+1].sub(p5.Vector.div(backward, constrainIterations/simSpeed*2));
}
// integrate
positions[i].add(p5.Vector.div(velocities[i], constrainIterations/simSpeed));
// constrain links
positions[i].sub(positions[i-1]);
positions[i].setMag(linkLength);
positions[i].add(positions[i-1]);
}
}
velocities[0].setMag(0);
}