This sketch smooths out the movement of a random brownian motion point with another point that follows using a spring. The class adds a motion trail to the springy point with diminishing scale and changing color. You can find the sketch with the editor here.
let Trails = [];
function setup() {
createCanvas(800, 800);
for(let i = 0; i < 10; i++){
append(Trails,new Brownian());
}
noStroke();
}
function draw() {
background(0);
for(let i = 0; i < Trails.length; i++){
let tr = Trails[i];
tr.update();
tr.display();
}
}
class Brownian {
constructor() {
this.bx = random(width);
this.by = random(height);
this.x = this.bx;
this.y = this.by;
this.damping = 0.9;
this.k = 0.2;
this.mass = 7.8;
this.velx = 0.0; // X Velocity
this.vely = 0.0; // Y Velocity
this.accel = 0; // Acceleration
this.force = 0;
this.pos = [];
this.a = [];
this.s = [];
this.c = [];
append(this.pos, createVector(this.x, this.y));
append(this.a, 255);
append(this.s, 20);
append(this.c,color(random(255),random(255),random(255)));
}
update(){
let newpx = random(-15,15);
let newpy = random(-15,15);
if(this.bx + newpx > width || this.bx + newpx < 0){
newpx = -newpx;
}
if(this.by + newpy > height || this.by + newpy < 0){
newpy = -newpy;
}
this.bx = this.bx + newpx
this.by = this.by + newpy;
this.force = -this.k * (this.y - this.by); // f=-ky
this.accel = this.force / this.mass;// Set the acceleration, f=ma == a=f/m
this.vely = this.damping * this.vely + this.accel;// Set the velocity
this.y = this.y + this.vely;// Updated position
this.force = -this.k * (this.x - this.bx);// f=-ky
this.accel = this.force / this.mass;// Set the acceleration, f=ma == a=f/m
this.velx = this.damping * this.velx + this.accel;// Set the velocity
this.x = this.x + this.velx;
append(this.pos, createVector(this.x, this.y));
append(this.a, 255);
append(this.s, 50);
let newR = red(this.c[this.c.length-1]) + random(-4,4);
let newG = green(this.c[this.c.length-1]) + random(-4,4);
let newB = blue(this.c[this.c.length-1]) + random(-4,4);
append(this.c,color(newR,newG,newB));
if(this.pos.length > 300){
this.pos.splice(0,1);
this.a.splice(0,1);
this.s.splice(0,1);
this.c.splice(0,1);
}
}
display(){
for(let i = 0; i < this.pos.length; i++){
let pt = this.pos[i];
fill(red(this.c[i]),green(this.c[i]),blue(this.c[i]),this.a[i]);
ellipse(pt.x, pt.y, this.s[i] , this.s[i] );
this.a[i] -= 0.5;
this.s[i] = this.s[i] * 0.995;
}
fill(255);
ellipse(this.bx, this.by, 10, 10);
stroke(255);
line(this.bx, this.by,this.x,this.y);
noStroke();
}
}