You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.2 KiB
84 lines
2.2 KiB
const Vect = p5.Vector
|
|
const width = 256;
|
|
const height = 256;
|
|
const nParticles = 15;
|
|
const initialSpeed = 2;
|
|
const particleRadius = 10;
|
|
const gap = 5;
|
|
const wallRadius = width/2-gap-particleRadius;
|
|
|
|
|
|
const sq = x => x*x;
|
|
|
|
function Particle(position, speed, color){
|
|
this.pos = position;
|
|
this.speed = speed;
|
|
this.color = color;
|
|
|
|
this.collidePart = function(other){
|
|
otherPos = other.pos
|
|
partPos = this.pos
|
|
dif = Vect.sub(partPos, otherPos);
|
|
if( dif.magSq() > 0
|
|
&& dif.magSq() < 4*sq(particleRadius)){
|
|
force = Vect.mult(
|
|
dif, (2*particleRadius - dif.mag())/dif.mag())
|
|
this.pos.add(Vect.div(force,2));
|
|
other.pos.sub(Vect.div(force,2));
|
|
let aux = this.speed;
|
|
this.speed = other.speed;
|
|
other.speed = aux;
|
|
}
|
|
}
|
|
}
|
|
|
|
let particles = [];
|
|
|
|
function setup() {
|
|
createCanvas(width,height);
|
|
colorMode(HSB);
|
|
noStroke();
|
|
frameRate(30);
|
|
for(let i = 0; i < nParticles; i += step) {
|
|
for(let overlap = true; overlap;){
|
|
pos = new Vect(
|
|
random(-width/2, width/2),
|
|
random(-height/2, height/2)
|
|
);
|
|
if(pos.mag() >= wallRadius)
|
|
continue;
|
|
overlap = particles.find(p => Vect.sub(p.pos, pos).mag() < particleRadius*2)
|
|
}
|
|
direction = new Vect(
|
|
random(-width/2, width/2),
|
|
random(-height/2, height/2)
|
|
);
|
|
direction.normalize();
|
|
speed = Vect.mult(direction, initialSpeed);
|
|
aParticle = new Particle(pos, speed, 360*i/nParticles);
|
|
particles.push(aParticle);
|
|
step = 1;
|
|
}
|
|
}
|
|
|
|
function draw() {
|
|
// update code
|
|
particles.forEach(p => p.pos.add(p.speed));
|
|
particles.forEach(function(particle,i){
|
|
if(particle.pos.mag() > wallRadius){
|
|
particle.pos.normalize()
|
|
particle.pos.mult(wallRadius)
|
|
particle.speed.reflect(particle.pos.copy())
|
|
}
|
|
particles.slice(0,i).forEach(p => particle.collidePart(p))
|
|
})
|
|
// drawing code
|
|
background(0);
|
|
fill(255);
|
|
translate(height/2, width/2);
|
|
circle(0,0,width-gap);
|
|
particles.forEach(function(particle){
|
|
fill(particle.color,255,255);
|
|
circle(particle.pos.x, particle.pos.y, 2*particleRadius);
|
|
})
|
|
}
|
|
|