xxxxxxxxxx
97
let particles = [];
const numParticles = 20;
let attractors = [];
function setup() {
createCanvas(800, 800);
background(0);
for (let i = 0; i < 4; i++) {
attractors.push(createVector(random(width), random(height)));
}
strokeWeight(2);
}
function draw() {
if (particles.length < numParticles) {
particles.push(new Particle(width / 2, height / 2));
}
for (let i = particles.length - 1; i >= 0; i--) {
let p = particles[i];
// Apply force from attractors
attractors.forEach(attractor => {
p.applyForce(p.attract(attractor));
});
p.update();
p.show();
// Multiple Symmetry Axes
push();
translate(width - p.pos.x * 2, 0);
p.showMirrored();
pop();
push();
translate(0, height - p.pos.y * 2);
p.showMirrored();
pop();
push();
translate(width - p.pos.x * 2, height - p.pos.y * 2);
p.showMirrored();
pop();
if (p.isOffScreen()) {
particles.splice(i, 1);
}
}
}
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.prevPos = this.pos.copy();
this.vel = createVector(random(-2, 2), random(-2, 2));
this.acc = createVector();
}
applyForce(force) {
this.acc.add(force);
}
update() {
this.vel.add(this.acc);
this.vel.x += map(noise(this.pos.y * 0.02), 0, 1, -2, 2);
this.vel.y += map(noise(this.pos.x * 0.02), 0, 1, -2, 2);
this.pos.add(this.vel);
this.acc.mult(0);
}
show() {
stroke(255);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
this.prevPos = this.pos.copy();
}
showMirrored() {
stroke(255);
line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
}
attract(attractor) {
let force = p5.Vector.sub(attractor, this.pos);
let distanceSq = constrain(force.magSq(), 25, 500);
let strength = 10 / distanceSq; // increased strength
force.setMag(strength);
return force;
}
isOffScreen() {
return (this.pos.y > height + 5 || this.pos.y < -5 || this.pos.x > width + 5 || this.pos.x < -5);
}
}