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); }) }