xxxxxxxxxx
95
// click mouse and drag to add force
var links = [];
var meshSize = 32;
var offset = 0.2
var gravity;
var gravityAcceleration = 500;
var coefficient = 5000;
var simSteps = 5;
var shouldBeDistance;
function setup() {
gravity = createVector(0, gravityAcceleration);
createCanvas(400, 400);
for(var y = 0; y < meshSize; y++) {
for(var x = 0; x < meshSize; x++) {
links.push([createVector(width * (offset + (1-offset*2) * x / meshSize), height * (offset + (1 - offset*2) * y / meshSize)), createVector()]);
}
}
shouldBeDistance = links[1][0].x - links[0][0].x;
}
function draw() {
background(245);
// drawing
for(var y = 0; y < meshSize; y++) {
for(var x = 0; x < meshSize; x++) {
var i = y * meshSize + x;
var [pos, vel] = links[i];
var neighbors = [];
if(x > 0) neighbors.push(i-1);
if(y > 0) neighbors.push(i-meshSize);
if(x < meshSize-1) neighbors.push(i+1);
if(y < meshSize-1) neighbors.push(i+meshSize);
for(var neighbor of neighbors) {
var [pos2, vel2] = links[neighbor];
line(pos.x, pos.y, pos2.x, pos2.y);
}
}
}
// physics
for(var it = 0; it < simSteps; it++) {
for(var y = 0; y < meshSize; y++) {
for(var x = 0; x < meshSize; x++) {
var i = y * meshSize + x;
var [pos, vel] = links[i];
var physics = y > 0 || x % 3 >= 2;
if(!physics) continue;
// gravity
vel.add(normalize(gravity));
// spring forces
var neighbors = [];
if(x > 0) neighbors.push(i-1);
if(y > 0) neighbors.push(i-meshSize);
if(x < meshSize-1) neighbors.push(i+1);
if(y < meshSize-1) neighbors.push(i+meshSize);
for(neighbor of neighbors) {
[pos2, vel2] = links[neighbor];
var dir = p5.Vector.sub(pos2, pos);
var distance = dir.mag();
var extension = distance - shouldBeDistance;
dir.setMag(extension * coefficient);
vel.add(normalize(dir));
}
// mouse forces
var mouseVector = pos.copy();
mouseVector.sub(createVector(mouseX, mouseY));
mouseVector.setMag((mouseVector.mag() ** (-1))*20000);
if(mouseIsPressed) {
vel.add(normalize(mouseVector));
}
}
}
for(y = 0; y < meshSize; y++) {
for(x = 0; x < meshSize; x++) {
i = y * meshSize + x;
[pos, vel] = links[i];
// integrate
pos.add(normalize(vel));
}
}
}
}
function normalize(vec) {
return p5.Vector.mult(vec, max(min(deltaTime, 40), 40)/1000/simSteps);
}