xxxxxxxxxx
atomsAmount = 300;
atoms = [];
gravity = 0.05;
types = {
positive: {
color: "orange",
radius: 16,
},
negative: {
color: "green",
radius: 24,
},
};
atom = (t = types[random(2) < 1 ? "positive" : "negative"]) => ({
type: t ,
radius: t.radius,
color: t.color,
pos: createVector(random(-1, 1), random(-1, 1)),
vel: createVector(0, 0),
acc: createVector(0, 0),
show() {
push();
translate(this.pos);
fill(this.color);
sphere(this.radius);
pop();
},
update() {
this.vel.limit(5);
this.vel.mult(0.98);
this.vel.add(this.acc);
this.pos.add(this.vel);
this.acc = createVector(0,gravity);
},
wrap() {
const r = this.radius ;
this.pos.x = constrain(this.pos.x, r - width / 2, width / 2 - r);
this.pos.y = constrain(this.pos.y, r - height / 2, height / 2 - r);
},
});
function setup() {
createCanvas(640, windowHeight, WEBGL);
noStroke();
atoms = Array(atomsAmount)
.fill()
.map((e) => atom());
}
function draw() {
background('white');
directionalLight(color("white"), 0, 0, -1);
directionalLight(color("gray"), 0, 0, -1);
avoidOverlapping();
frameCount%500<200
?attractBetweenChanges()
:attractBetweenChanges2();
atoms.forEach((a) => a.update());
atoms.forEach((a) => a.wrap());
atoms.forEach((a) => a.show());
}
function attractBetweenChanges() {
for (let i = atoms.length; i--; ) {
const A = atoms[i];
for (let j = i; j--; ) {
const B = atoms[j];
const delta = A.pos.copy().sub(B.pos);
const distance = sqrt(delta.x ** 2 + delta.y ** 2);
const sumRadius = A.radius + B.radius;
const k = distance / sumRadius || 1 ;
const force = delta
.div(k * k)
.div(500)
.mult(A.type == B.type?-1:.1);
A.acc.add(force);
B.acc.sub(force);
}
}
}
function attractBetweenChanges2() {
for (let i = atoms.length; i--; ) {
const A = atoms[i];
for (let j = i; j--; ) {
const B = atoms[j];
const delta = A.pos.copy().sub(B.pos);
const distance = sqrt(delta.x ** 2 + delta.y ** 2);
const sumRadius = A.radius + B.radius;
const k = distance / sumRadius || 1;
const force = delta.div(k*k).div(3000).mult(A.type!=B.type?-3:1);
A.acc.add(force);
B.acc.sub(force);
}
}
}
function mouse() {
return {
pos: createVector(mouseX - width / 2, mouseY - height / 2),
acc: createVector(0, 0),
radius: 100,
show(){
push();
fill("ghostwhite");
translate(this.pos);
sphere(this.radius/sqrt(2));
pop();
}
}
}
function avoidOverlapping() {
const player = mouse();
player.show();
const all = atoms.concat(player);
for (let i = all.length; i--; ) {
const A = all[i];
for (let j = i; j--; ) {
const B = all[j];
const delta = A.pos.copy().sub(B.pos);
const distance = sqrt(delta.x ** 2 + delta.y ** 2);
const sumRadius = A.radius + B.radius;
if (distance < sumRadius) {
const k = 1 - distance / sumRadius;
const force = delta.mult(k * k);
A.acc.add(force);
B.acc.sub(force);
}
}
}
}