Orbital Sketch with Grid Filter

Iterating on the previous Orbiting Bodies sketches I had made, I tried to see if there was a more interesting way to display the movement of the particles. What I ended up with, was a grid of circles that respond to the proximity to the particles.

I used the class coding syntax to construct particles with their own parameters stored in each iteration and then filled out a pretty intense draw function that has a series of nested loops that do the following:

  1. Check the distance of each “pixel” (the term for this post that describes each circle in the grid of circles) from each orbiting particle.
  2. Apply a formula to that distance which is based on a standard statistical bell curve that results in a diameter.
  3. Check if this new diameter is greater than the diameter previously stored in it. This step allows the greatest diameter to be displayed when multiple particles are present.
  4. Draw the circles with the resulting diameters across the entire grid.

The class is in fact just in charge of the particle movements but doesn’t actually have a display or show function attached to it. This felt like the most logical way to achieve this effect, but there may be more efficient ways to do it. Code attached below.

let prtcl = [];
let prtcl = [];
let grid = 40;
let deviation;
let diam = [];
let baseDiam;
function setup() { 
  createCanvas(500, 500); 
  for (let i = 0; i < 25; i++) { 
    prtcl[i] = new Particle; 
  } 
  baseDiam = 2;
  deviation = 65;
  for (let i = 0; i < grid; i++) { 
    diam[i] = [];
    for (let j = 0; j < grid; j++) {
      diam[i][j] = baseDiam; 
    }
  }
}
function draw() { 
  background(0);
  let w = width / grid;
  let h = height / grid;
  let distance = [];

  for (let i = 0; i < grid; i++) { 
    for (let j = 0; j < grid; j++) { 
      for (let q = 0; q < prtcl.length; q++) { 
        distance[q] = dist(prtcl[q].x, prtcl[q].y, i * w, j * h);
        let diameter = pow(deviation, 2) / (deviation * sqrt(2 * PI)) 
        * pow(Math.E, -1 * pow(distance[q] * 20, 2) / (2 * pow(deviation, 2)));
        if (diam[i][j] < diameter) { 
          diam[i][j] = diameter; 
        }
      } 
    }
  }
  for (let q = 0; q < prtcl.length; q++) {
    prtcl[q].place(); 
  }
  for (let i = 0; i < grid; i++) {
    for (let j = 0; j < grid; j++) { 
      fill(255, 100); 
      stroke(255, 255, 255); 
      strokeWeight(1); 
      ellipse(i * w, j * h, diam[i][j], diam[i][j]) 
    } 
  }
  for (let i = 0; i < grid; i++) {
    for (let j = 0; j < grid; j++) {
      if (diam[i][j] > baseDiam) {
        diam[i][j] = diam[i][j] / 1.1; 
      } else { 
        diam[i][j] = baseDiam; 
      } 
    } 
  }
}
function keyPressed() { 
  let p = new Particle; 
  prtcl.push(p);
}
class Particle { 
  constructor() { 
    this.s = random(0, PI / 90); //this will establish the increment of movement, somewhere between 0 and 2 degrees 
    this.r = random(width * (1 / 8), width * (3 / 7)); 
    this.t = random(0, 2 * PI);random(-this.s, this.s); 
    this.x = this.r * cos(this.t) + height / 2; 
    this.y = this.r * sin(this.t) + height / 2; 
  }
  place() { 
    this.t += this.s;
    this.x = this.r * cos(this.t) + height / 2; 
    this.y = this.r * sin(this.t) + height / 2;
  }
}

Leave a Reply

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