Week04: Particle System

Inspired by Daniel Shiffman’s code, I created a particle system, in which the particles consist of a shape.
I also applied the concept of attractor and repeller, therefore, the particles scatter when the mouse cursor touches them and go back to their initial position when the cursor isn’t around.

The code of this system is like below:

[sketch.js]

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
// Modified by Yeonhee Lee 20/Feb/2018

let ps;

function setup() {
  createCanvas(600, 400);
  pixelDensity(1);
  ps = new ParticleSystem(width/2-50, height/2-50, 1);
  repeller = new Repeller(width, height);
}

function draw() {
  background(0);
  
  ps.applyRepeller(repeller);
  ps.applyRecover();
//  ps.applyAttractor();
  
  repeller.update();  // update repeller's position following the mouse cursor

  ps.display();
  ps.update();
}

[particlesystem.js]

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
// Modified by Yeonhee Lee 20/Feb/2018

class ParticleSystem {


  constructor(x, y, r) {
    this.particles = [];
    // this.intact = true;
    let rows = 100;
    let cols = 100;
    for (let i = 0; i < rows * cols; i++) {
      this.addParticle(x + (i % cols) * r, y + (floor(i / rows)) * r, r);
    }
  }

  addParticle(x, y, r) {
    this.particles.push(new Particle(x, y, r));
  }

  display() {
    for (let particle of this.particles) {
      particle.display();
    }
  }


  // A function to apply a force to all Particles
  applyForce(f) {
    for(let particle of this.particles){
      particle.applyForce(f);
    }
  }

  applyRepeller(r) {
    for(let particle of this.particles){
      
      let force = r.repel(particle);
      particle.applyForce(force);
    }
  }
  
  applyRecover() {
    for(let particle of this.particles) {
      particle.recover();
    }
  }
  
  // applyAttractor() {
  //   for(let particle of this.particles) {
  //      particle.applyAttraction();
  //   }
  // }
      


  update() {
    for (let particle of this.particles) {
      particle.update();
    }
  }
}

[repeller.js]

class Repeller {
  
  constructor(x, y) {
    this.power = 100;
    this.position = createVector(x, y);
  }
  
  update() {
  	this.position.x = mouseX;
    this.position.y = mouseY;
  }
  
  repel(p) {
    let dir = p5.Vector.sub(this.position, p.position);
    let d = dir.mag();
    dir.normalize();
    if(d<50) {
 //     d = constrain(d, 1, 50);
      let force = -1 * this.power / (d*d);
      force = constrain(force, -20, -1);
      dir.mult(force);
      return dir;
    }
    else return 0;
  }
    

}

[particle.js]

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
// Modified by Yeonhee Lee 20/Feb/2018

class Particle {

  constructor(x, y, r) {
    this.acceleration = createVector();
    this.velocity = createVector()
    this.velocity.mult(0.5);
    this.position = createVector(x, y);
    this.origin = createVector(x, y);
    this.r = r;
    this.c = random(200,255);
  }


  applyForce(force) {
    this.acceleration.add(force);
  }
  
  applyAttraction() {
    let f = this.attractor.attract(this.position);
    this.applyForce(f);
  }

  // Method to update position
  update() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    this.velocity.mult(0.95);
//    this.lifespan -= 2.0;
  }

  // Method to display
  display() {
//    stroke(0);
    noStroke();		// drawing stroke makes the sketch much slower
//    stroke(255, 255, 0);	
    fill(255, 255, 0);
    rectMode(CENTER);
    rect(this.position.x, this.position.y, this.r, this.r);
  }
  
  recover() {
    let dir = p5.Vector.sub(this.origin, this.position);
    let d = dir.mag();
    
    if(d>2) {
      dir.normalize();
//      d = constrain(d, 0, 10);
      dir.mult(2);
      this.position.add(dir);
    }
    else {
 //     this.velocity.mult(0);
      this.position = this.origin.copy();
    }
  }

  // Is the particle still useful?
  // isDead() {
  //   if (this.lifespan < 0.0) {
  //     return true;
  //   } else {
  //     return false;
  //   }
  // }
}

I found that the sketch becomes very slow when it has to draw the line of the particles which is 1px by 1px square.
Therefore, I didn’t draw the lines of them and instead, reduced the pixel density to 1. In this way, the sketch runs much faster.

Following is the result:

Leave a Reply

Your email address will not be published. Required fields are marked *