Fun with polygons [p5.js]

I decided to play a bit with p5.js. I haven’t been using processing or p5.js for some time, and so I decided to do something simple, with random outlined polygons moving and leaving a trace!



Try to see what happens when the polygons have 0 sides (if that makes sense) and the outline bigger by playing with the two buttons above!
And here’s the (not so polished) code for the sketch above:

/* DEPENDENCIES
//
// - https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js
// - https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js
// - https://www.dariomazzanti.com/js/RandomColorPaletteGeneration.js
*/
// we will use this to store a nice color palette
var palette;
var maxColNum = 50;
// we will store here the colors to generate our palette
var col_1, col_2, col_3;
// color of the background
var bgColor;
// how many polygons would you like?
var howMany = 30;
// storing polygons here
var polygons =[];
// fun mode
var noSidesPoly = false;
function setup()
{
  // "polysketch" is the ID of the div containing this script
  // we get a reference to it in order to know its current width and height
  const elt = select("#polysketch");
  w = elt.width;
  h = elt.height;
  // we now create our canvas for p5js, and parent it to the specified element (our "polysketch" div)
  canvas = createCanvas(w, h);
  canvas.parent('polysketch');
  canvas.position(0,0);
  // we use this value to generate objects which fit within the canvas
  var elementsScaler = min(width, height);
  // oh yes
  smooth();
  // we are not going to fill the shapes, we just draw their outline
  noFill();
  // setting the outline thickness, based on canvas proportions
  // we want a thicker outline for our noSidesPoly mode :)
  if(noSidesPoly)
      strokeWeight(elementsScaler/100);
  else
    strokeWeight(elementsScaler/400);
  // setting up some colors
  bgColor = color(0, 8);
  col_1 = color(30, 67, 130);
  col_2 = color(0, 255, 51);
  col_3 = color(51, 78, 210);
  // and generating our palette!
  GeneratePalette();
  // instantiating the polygons
  if(noSidesPoly)
  {
    // no polygons! check the third argument, it's 0!
    for(var i = 0; i < 100; i++)
      polygons[i] = new AnimPoly(random(width), random(height), 0, random(elementsScaler/15, elementsScaler/3), color(palette[int(random(maxColNum))]));
  }
  else
  {
    // random number of polygons! Check the third argument: it will return a float - I suppose that's why we have also non-regular polygons ;)
    for(var j = 0; j < howMany; j++)
      polygons[j] = new AnimPoly(random(width), random(height), random(1,7), random(elementsScaler/15, elementsScaler/3), color(palette[int(random(maxColNum))]));
  }
  background(bgColor);
  fill(bgColor);
  rect(0,0,width,height);
}
// calling this we can set the mode while the sketch is running
function noSidesPolysMode(_enable)
{
    noSidesPoly = _enable;
    setup();
}
// in case the window is resized
function windowResized()
{
    const elt = select("#polysketch");
    w = elt.width;
    h = elt.height;
    if(w > displayWidth)
        w = displayWidth;
    if(h > displayHeight)
        h = displayHeight;
    resizeCanvas(w, h);
    setup();
}
function draw()
{
  // no background, just a rectangle using a transparent color, so that shapes leave a trail
  fill(bgColor);
  rect(0,0,width,height);
  // update of animating values and then drawing each shape
  for(var i = 0; i < howMany; i++)
  {
    polygons[i].animate(0.01, 0.001);
    polygons[i].draw();
  }
}
// our polygons!
class AnimPoly
{
  constructor(_x, _y, _n, _scale, _col)
  {
    this.posX = _x;
    this.posY = _y;
    this.speedX = random(-0.1, 0.1);
    this.speedY = random(-0.1, 0.1);
    this.nSides = _n;
    this.rotAngle = 0.0;
    this.col = _col;
    this.dim = _scale;
    this.startDim = this.dim;
    this.dimMult = 1.0;
    this.thickness = 5;
    this.timeOffset = random(1000);
    this.pulseSpeed = random(0.01, 0.02);
    this.rotSpeed = random(0.001, 0.003);
    this.polyAngle =  TWO_PI / this.nSides;
  }
  draw()
  {
    push();
      translate(this.posX, this.posY);
        rotate(this.rotAngle);
        stroke(this.col);
      beginShape();
        for (var a = 0; a < TWO_PI; a += this.polyAngle)
        {
          var sx = cos(a) * this.dim;
          var sy = sin(a) * this.dim;
          vertex(sx, sy);
        }
      endShape(CLOSE);
    pop();
  }
  // updating current rotation angle
  rotate()
  {
      this.rotAngle = sin(this.rotSpeed*25*(frameCount + this.timeOffset));
  }
  // scaling the shape over time
  pulsate()
  {
    this.dimMult = sin(this.pulseSpeed*(frameCount + this.timeOffset));
    this.dim = (this.dimMult *this.startDim + this.startDim)*0.5;
    if(this.dim <=1)
    {
      this.posX = random(width);
      this.posY = random(height);
      this.speedX = random(-0.1, 0.1);
      this.speedY = random(-0.1, 0.1);
      this.col = color(palette[int(random(maxColNum))]);
    }
  }
  // moving around randomly
  move()
  {
    this.posX += this.speedX*deltaTime;
    this.posY += this.speedY*deltaTime;
  }
  // calling some functions...
  animate()
  {
    this.rotate();
    this.pulsate();
    this.move();
  }
}
// this one calls a palette generator from our RandomColorPaletteGeneration "api"
function GeneratePalette()
{
  var colorsNum = maxColNum;
  var greyControlValue = 0.9;
    palette = new Array(colorsNum);
    palette = RandomMixPalette(
      col_1,
      col_2,
      col_3,
      greyControlValue,
      colorsNum
    );
}

An interesting thing to notice is that polygons are not always regular! This specific feature is given by this part of code:

polygons[j] = new AnimPoly(random(width), random(height), 
random(1,7), 
random(proport/15, proport/3), color(palette[int(random(maxColNum))]));

The third parameter of the AnimPoly constructor is the number of sides of the polygon. You would expect an integer value for that, but here we are passing a random value between 1 and 7!

dario mazzanti, 2021

Up ↑