xxxxxxxxxx
104
let get_ball = (pos) => {
return ({
pos: {x:pos.x, y:pos.y},
velocity: {x:0, y:0} ,
radius: 12,
mass: 2
})
}
let balls = [];
let num_balls = 80;
let G = 19.8;
let forceField = {
pos: {x:0, y:0},
velocity: {x:0, y:0} ,
radius: 140
}
function setup() {
createCanvas(800, 800);
for (let i = 0; i < num_balls; i++) {
balls.push(
get_ball( { x: random(0, width), y:random(0, height) } )
)
}
forceField.pos = {x: width/2, y: height/2};
}
const solvePosition = (pos, vel, acc, dt) => {
return pos + vel * dt + ((acc * (dt*dt)) / 2);
}
const verlet_gravity = (obj, dt) => {
let acc_y = G;
obj.pos.y += dt * (obj.velocity.y * acc_y /2);
let new_acc_y = G;
obj.velocity.y += dt * (acc_y + new_acc_y) /2;
return obj;
}
function dist2 (v, w) {
return ((v.x - w.x) * (v.x - w.x)) + ((v.y - w.y) * (v.y - w.y) )
}
function draw() {
background(20);
forceField.pos.y = mouseY;
forceField.pos.x = mouseX;
balls.map((ball) => {
let d = dist2(ball.pos, forceField.pos);
let real_d = Math.sqrt(d);
let max_d = forceField.radius;
let min_d = forceField.radius/4;
let dt = deltaTime/1000;
if (real_d < max_d) {
let influence = map(real_d, max_d, min_d, 1, 0.1);
influence = max(0.1, influence);
dt *= influence;
}
ball = verlet_gravity(ball, dt);
if(ball.pos.y > height*2) {
ball.pos.y = 20;
ball.velocity.y = 0;
}
noStroke();
fill(255);
ellipse(ball.pos.x, ball.pos.y, ball.radius, ball.radius);
})
noFill();
stroke(120);
ellipse(forceField.pos.x, forceField.pos.y, forceField.radius, forceField.radius);
}