p5.js Session 10: Randomness and Variation

Use random() to decide where and how often to call a function, then switch to map randomness onto shape choices.

In Session 9 we used a function to place flowers exactly where we wanted, corner by corner. Now let’s hand that decision over to chance.

random()

random(min, max) returns a decimal number somewhere between the two.

function setup() {
  createCanvas(600, 600);
  angleMode(DEGREES);
  noLoop();
  noStroke();
}

function draw() {
  background(0);
  let x = random(100, 500);
  let y = random(100, 500);
  drawFlower(x, y);
}

function drawFlower(x, y) {
  push();
  translate(x, y);
  for (let i = 0; i < 8; i++) {
    rotate(45);
    fill(0, 0, 255);
    ellipse(60, 0, 90, 35);
  }
  fill(255, 0, 0);
  circle(0, 0, 25);
  pop();
}

A single flower placed at a random position within the canvas

Every time this sketch runs, the flower lands somewhere new. drawFlower() doesn’t care where its numbers come from, fixed or random, it just uses whatever it’s given.

A random number of flowers, each with its own colour

Random position was just the start. Let’s bring random() into colour and count too.

function setup() {
  createCanvas(600, 600);
  angleMode(DEGREES);
  noLoop();
  noStroke();
}

function draw() {
  background(0);
  let count = floor(random(4, 8));
  for (let i = 0; i < count; i++) {
    let x = random(80, 520);
    let y = random(80, 520);
    let r = int(random(255));
    let g = int(random(255));
    let b = int(random(255));
    drawFlower(x, y, r, g, b);
  }
}

function drawFlower(x, y, r, g, b) {
  push();
  translate(x, y);
  for (let i = 0; i < 24; i++) {
    rotate(20);
    fill(r, g, b);
    ellipse(60, 0, 75, 15);
  }
  fill(255, 0, 0);
  circle(0, 0, 35);
  pop();
}

Several flowers, somewhere between four and seven, each at a random position and a random colour

switch: mapping a number to a choice

Randomness isn’t just useful for position and colour, it can decide what to draw too. This time each cell gets two independent rolls: one switch for colour, one for shape.

function setup() {
  createCanvas(600, 600);
  noLoop();
  noStroke();
}

function draw() {
  background(0);
  let cols = 6;
  let cellSize = width / cols;

  for (let row = 0; row < cols; row++) {
    for (let col = 0; col < cols; col++) {
      let x = col * cellSize;
      let y = row * cellSize;
      let half = cellSize / 2;

      let colourChoice = floor(random(3));
      switch (colourChoice) {
        case 0:
          fill(187, 20, 20);
          break;
        case 1:
          fill(255, 163, 34);
          break;
        case 2:
          fill(0, 0, 178);
          break;
      }

      let shapeChoice = floor(random(8));
      switch (shapeChoice) {
        case 0:
          rect(x, y, cellSize, half);           // top half
          break;
        case 1:
          rect(x, y + half, cellSize, half);    // bottom half
          break;
        case 2:
          rect(x, y, half, cellSize);           // left half
          break;
        case 3:
          rect(x + half, y, half, cellSize);    // right half
          break;
        case 4:
          triangle(x, y, x + cellSize, y, x, y + cellSize);               // top-left corner
          break;
        case 5:
          triangle(x, y, x + cellSize, y, x + cellSize, y + cellSize);    // top-right corner
          break;
        case 6:
          triangle(x, y, x, y + cellSize, x + cellSize, y + cellSize);    // bottom-left corner
          break;
        case 7:
          triangle(x + cellSize, y, x + cellSize, y + cellSize, x, y + cellSize); // bottom-right corner
          break;
      }
    }
  }
}

A 6x6 grid of half-rectangles and corner triangles, each cell a random one of three colours

Colour and shape are chosen independently, so any of the three colours can land on any of the eight shapes. Run it again and the grid looks completely different: same three colours, same eight shapes, but a different roll for every cell.


In Session 11 we’ll look at building shapes from scratch with our own points, instead of relying on the built-in ones.