# Noise and Randomness

Students will leave the session with an understanding of how to incorporate Perlin Noise into compositions.

### Class Agenda

Sketching & Presentations 8:30 - 9:30am
BREAK 15min
Code Lecture 9:45 - 11:00am
BREAK 60min
Workshop 12:00 - 2pm

### Morning Sketch

Continuing our exploration of generative artwork. Find and recreate two pieces from the following early generative artists and recreate it: Vera Molnár, Manfred Mohr, Frieder Nake, Georg Nees, A. Michael Noll.

### Weekly Assignment

Recursion, 3D and Noise. Create a typographic composition using at least one of these concepts.

### Weekly Assignment 2

Create a 3D letter using textToPoints and implement orbitControl so that the user can explore the composition. Similar to the Loading screen assignment create an effect around your composition that occurs on a time loop.

# Code Lecture

### Randomness

In creative coding randomness allows us to build more variety into our system without having to specify the exact parameters. It is a way of turning over control to the computer as we search for the exact conditions we want to use in our final composition. Up until now we have been using `random()` but when we are working with motion this function has its downsides.

``````function setup() {
createCanvas(400, 400);

frameRate(2);
}

function draw() {
background(220);

var x = random(width);

circle(x, height / 2, 10);
}
``````

In the example above the randomness is almost too random and sometimes we instead want a function that is more smooth and organic.

### Perlin Noise

In p5.js we have a function called `noise()` that uses the concept of Perlin noise, named after its inventor, Ken Perlin. Perlin noise was created to provide semi-random variations that are continuous and smooth. You can use it in a number of different ways to create textures, terrains and generally randomized outputs that feel smoother.

``````let noiseX = 0;

function setup() {
createCanvas(400, 400);

noiseX = random(1);
}

function draw() {
background(220);

var x = width * noise(noiseX);

circle(x, height / 2, 10);

noiseX += 0.025;
}
``````

Noise can be applied to any values in our sketches. Let's create a grid of circles

``````var gridSize = 10;

function setup() {
createCanvas(400, 400);
}

function draw() {
background(220);

var cellSize = width / gridSize;

for (var rowIndex = 0; rowIndex < gridSize; rowIndex += 1) {
for (var columnIndex = 0; columnIndex < gridSize; columnIndex += 1) {
var posX = cellSize * columnIndex;
var posY = cellSize * rowIndex;

circle(posX + cellSize / 2, posY + cellSize / 2, cellSize);
}
}
}
``````

Using the `rowIndex` and `columnIndex` we can use 2D Noise and randomize the size of our circles based on their position.

``````var gridSize = 10;

function setup() {
createCanvas(400, 400);
}

function draw() {
background(220);

var cellSize = width / gridSize;

for (var rowIndex = 0; rowIndex < gridSize; rowIndex += 1) {
for (var columnIndex = 0; columnIndex < gridSize; columnIndex += 1) {
var posX = cellSize * columnIndex;
var posY = cellSize * rowIndex;
var size = noise(rowIndex, columnIndex) * cellSize;

circle(posX + cellSize / 2, posY + cellSize / 2, size);
}
}
}
``````

Let's step through how we can apply textToPoints to our new Noise technique.

``````var bebasFont;
var bounds;
var points = [];
var fontSize = 500;
var rotateAmt = 0;
var noiseX;
var noiseY;

/**
* Please note that this is a font hosted by another project of mine.
* There is no guarantee that this url will function in the future.
*/
}

function setup() {
createCanvas(500, 500);

textFont(bebasFont);
textSize(fontSize);
textAlign(CENTER, CENTER);
fill("white");
noStroke();
angleMode(DEGREES);

// create the points and points
points = bebasFont.textToPoints("A", 0, 0, fontSize, {
sampleFactor: 0.5,
simplifyThreshold: 0,
});
bounds = bebasFont.textBounds("A", 0, 0, fontSize);

// set up noise
noiseX = random(1);
noiseY = random(1);
}

function draw() {
background(220);

// translate the entire canvas
translate(width / 2, height / 2);
// align the bounds
translate(-bounds.w / 2, bounds.h / 2);

points.forEach((pt, index) => {
var offset = noise(pt.x + noiseX, pt.y + noiseY) * 20;
var x = pt.x + offset;
var y = pt.y + offset;

circle(x, y, 5);

// DEBUG
// push();
// fill("red");
// circle(pt.x, pt.y, 5);
// pop();
});

noiseX += 0.1;
noiseY += 0.1;
}
``````