A brownian motion sketch that samples a black and white image and leaves a point when the sampled color is black. Link to source files.
let Trails = [];
let Samples = [];
let CSamples = [];
let pg;
let img;
function preload() {
img = loadImage('yes.jpg');
}
function setup() {
createCanvas(800, 800);
for(let i = 0; i < 15; i++){
append(Trails,new Brownian());
}
noStroke();
pg = createGraphics(width, height);
}
function draw() {
background(0);
pg.image(img, 0, 0);
for(let i = 0; i < Trails.length; i++){
let tr = Trails[i];
tr.update();
tr.display();
}
for(let i = 0; i < Samples.length; i++){
let p = Samples[i];
fill(CSamples[i]);
ellipse(p.x,p.y,20,20);
}
}
class Brownian {
constructor() {
this.bx = random(25,width-25);
this.by = height/2;
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.lifespan = 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(-25,25);
let newpy = random(-25,25);
if(this.bx + newpx > width-25 || this.bx + newpx < 25){
newpx = -newpx;
}
if(this.by + newpy > height-25 || this.by + newpy < 25){
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;
let newR = red(this.c[this.c.length-1]) + random(-8,8);
let newG = green(this.c[this.c.length-1]) + random(-8,8);
let newB = blue(this.c[this.c.length-1]) + random(-8,8);
if(this.lifespan < 130){
append(this.pos, createVector(this.x, this.y));
append(this.a, 255);
append(this.s, 20);
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] -= 1;
this.s[i] = this.s[i] * 0.98;
}
let pt = this.pos[this.pos.length-1];
let cs = pg.get(pt.x,pt.y);
let cr = this.c[this.c.length-1];
if(red(cs) < 100 && this.lifespan < 130){
append(Samples, createVector(this.x, this.y));
append(CSamples, cr);
this.lifespan++;
}
noStroke();
}
}