Take a Walk on the Random Side

I recently began to create Generative Art, and I’m hooked! For those who aren’t familiar with this area, it’s a perfect combination of coding and creativity that I realize I had been looking for without realizing it. As a trained statistician, my wheelhouse was replete with probability, variation and randomness, but I had never combined it with my love for art and design. In Generative Art, the computer is given a set of instructions or parameters for the type of piece that the coder/artist wants to produce. However, a degree of randomness is also introduced so that each piece that is produced is unique (a 1/1 original). This principal can be applied to both still and moving forms.

When I decided to move into this area and began to look for resources, I was surprised not to find nearly as many as for other coding endeavors like Python, HTML/CSS, etc. After my experience, I think the best way to get started is with the JavaScript library p5.js. It’s an effort to put the functionality of the Processing language that has been used for artistic coding for a while into the JavaScript framework, and it’s powerful. A great resource is the gorgeous book Generative Design by Bohnacker, Groß, Laub and Lazzeroni from 2012 which covers Processing, and their subsequent edition from 2018 which updates to p5.js.

To get started with p5.js library, you don’t have to install anything, just head over to

editor.p5js.org

where they take care of the details for you, all you have to do is code!

Some basics to get started are that we’re just going to have 2 sections to keep things simple. One is an area at the top of the code where we’ll define certain parameters. The second is a single setup() function that p5.js needs. It’s like a wrapper where we’ll put everything, and will look like this:

function setup() {
}

Let’s start by setting up a square grid to contain our design, 900 pixels each side. At the top of the code, we’ll have

var canvasHeight = 900;
var canvasWidth = 900;

function setup() {
  createCanvas(canvasWidth, canvasHeight);
  background('#FFFFFF');
  noStroke();
}

Background with all F’s in the hex code is just white, and noStroke() means that we don’t want boundaries around any of our shapes. Let’s start with drawing a circle, and go ahead and introduce a little randomness. If we add these constants at the top

var min_size = 200;
var max_size = 400;
var x_min = 300;
var x_max = 600;
var y_min = 300;
var y_max = 600;

we’re setting a range for the size of the circle (diameter between 200 and 400 pixels) and a range for where it can appear on our canvas (x and y positions between 300 and 600). Then in our setup function we can take uniform random draws to have actual values for the circle size and position we’re about to draw.

var rand_size = random(min_size,max_size);
  var rand_x = random(x_min, x_max);
  var rand_y = random(y_min, y_max);

To start off we’ll let the circle be filled entirely by one random color 

var fill_color = color(random(255), random(255), random(255));
 fill(fill_color);

And finally with this setup we can plot the circle:

ellipse(rand_x, rand_y, rand_size, rand_size);

Okay, let’s make things a little more interesting by drawing some colored rings inside the circle. We’ll actually do this by drawing smaller and smaller circles that will just look like rings. We need to define some additional parameters to represent the number of rings that we want and their size

var num_rings = 5;
var step_size = 50;

Our circle drawing function now needs to go inside a loop that prints the rings

for (let j = 0; j <= num_rings; j++) {
    var fill_color = color(random(255), random(255), random(255));
    fill(fill_color);
    ellipse(rand_x, rand_y, rand_size-(j*step_size), rand_size-(j*step_size));
  }

Here’s what we get:

This looks pretty cool, like a target bullseye. Let’s see if we can make things look a bit livelier and give the circles the illusion of movement. We need a new random jitter to move each circle a tiny bit.

var jitter = 10;

The last piece is to add this jitter to the circle plot. We do this in a way so that when the ring is even, it jitters up, and when it’s odd, it jitters down.

if (j % 2 == 0){
    ellipse(rand_x+random(jitter), rand_y+random(jitter), rand_size-(j*step_size), rand_size-(j*step_size));
      } else {
        ellipse(rand_x-random(jitter), rand_y-random(jitter), rand_size-(j*step_size), rand_size-(j*step_size));
      }

And here’s our circle!

That’s fun! Let’s make a few more, as many as we’d like.

Here’s the complete code in one place.

var canvasHeight = 900;
var canvasWidth = 900;
var min_size = 200;
var max_size = 400;
var x_min = 300;
var x_max = 600;
var y_min = 300;
var y_max = 600;
var num_rings = 5;
var step_size = 50;
var jitter = 10;

function setup() {
  createCanvas(canvasWidth, canvasHeight);
  background('#FFFFFF');
  noStroke();
  
  var rand_size = random(min_size,max_size);
   var rand_x = random(x_min, x_max);
   var rand_y = random(y_min, y_max);
    
    for (let j = 0; j <= num_rings; j++) {
    
    	var fill_color = color(random(255), random(255), random(255));
    	fill_color.setAlpha(128 + random(128));
    	fill(fill_color);
      	if (j % 2 === 0){
   	 ellipse(rand_x+random(jitter), rand_y+random(jitter), rand_size-(j*step_size), rand_size-(j*step_size));
      	} else {
        	ellipse(rand_x-random(jitter), rand_y-random(jitter), rand_size-(j*step_size), rand_size-(j*step_size));
      	}
    } 
}

By adding more shapes, some squares, and a bit of translucency, we have our design:

You can see more examples from the randomly generated series here to get an idea of the variations that arise when you run the design repeatedly. 

So, I have a new addiction, and you might too if you try to create something in p5.js! I’m thinking it’s a healthy one, like going to the gym every day. Both can create something beautiful and make our lives a little sweeter 😊