# October 14

# More Randomness

We have seen several examples of randomness based on calling the `random`

function. Either we use the number directly, or we use the numbers as offsets to create what is often called a “drunken walk” or Brownian motion. The last program example in Roger’s Notes for October 9 & 12 used this method.

Let’s redo this using other forms of randomness.

# Perlin Noise

The `noise`

function returns a smoothly varying value as a function of 1, 2, or 3 parameters that can be interpreted as time, space, or both. We saw Perlin noise in the terrain peak assignment. Below, we use it to move eyes. Since the `noise`

function returns a value from 0 to 1, it’s important to scale the output appropriately (also the input matters — if you step through values rapidly, the output seems more chaotic).

```
var left, right;
var gdf;
var noiseParam = 0;
var noiseStep = 0.1;
function Ball() {
this.ballX = 60;
this.ballY = 50;
this.draw = function() {
var offset = noise(noiseParam);
// map offset from 0-1 into -20 to +20
offset = map(offset, 0, 1, -20, 20);
fill(0, 222, 0);
ellipse(this.ballX + offset, this.ballY, 50, 50);
}
}
function setup() {
createCanvas(200,200);frameRate(10);
frameRate(10);
left = new Ball();
right = new Ball();
right.ballX = 140;
}
function draw() {
background(255,250,180);
fill(100);
ellipse(100, 80, 200, 200);
left.draw();
right.draw();
noiseParam += noiseStep;
};
```

Notice that the eyes do the same thing, even though each calls `noise`

and computes its “random” location independently. This emphasizes the fact that Perlin noise is a deterministic function: You put in the same parameters and you get out the same value. You only get change by changing the parameter. Since we use a global variable, `noiseParam`

, and update it only in the main `draw`

function, each Eye `draw`

method passes the same parameter value to `noise`

and gets the same result.

## Other Parameters

Almost *any* parameter can be controlled by randomness, including Perlin noise. Let’s hook Perlin noise up to the eye color.

```
var left, right;
var gdf;
var noiseParam = 0;
var noiseStep = 0.1;
function Ball() {
this.ballX = 60;
this.ballY = 50;
this.draw = function() {
var offset = noise(noiseParam);
// map offset from 0-1 into -20 to +20
offset = map(offset, 0, 1, -20, 20);
fill(100, noise(noiseParam * 0.2 + 100) * 255, noise(noiseParam * 0.2 + 200) * 255);
ellipse(this.ballX + offset, this.ballY, 50, 50);
}
}
function setup() {
createCanvas(200,200);frameRate(10);
frameRate(10);
left = new Ball();
right = new Ball();
right.ballX = 140;
}
function draw() {
background(255,250,180);
fill(100);
ellipse(100, 80, 200, 200);
left.draw();
right.draw();
noiseParam += noiseStep;
};
```

I wanted the eye color to be based on different “random” values than the eye position. Recall that I cannot simply call `noise`

again with the same argument or I’ll get the same value back. Instead, I used a useful trick: I added a fairly big number to the argument, calling `noise(noiseParam + 100)`

and `noise(noiseParam + 200)`

. Since Perlin noise changes smoothly with the parameter values, a small offset would yield similar values, but by adding a “big” number like 100 or 200, I get fairly unrelated values. Since eye position and eye color are changed by increasing `noiseParam`

at the same rate, the apparent rate of fluctuation of both color and position will be the same. I could, say, get eye color to change much more slowly by scaling `noiseParam`

. In fact, that is the version shown above. Notice that the eye color seems to change more slowly than eye position. This demonstrates that you can change the apparent rate of change by changing the step size of the parameter to `noise`

.

# Uniform and Gaussian Noise

Uniform noise spreads values equally across a fixed range, e.g. from 0 to 1. Gaussian noise tends toward a certain average value (called the *mean*), with more or less random variation around the mean determined by the *standard deviation*. Let’s put some random points onto squares using uniform random noise and Gaussian noise.

```
function setup() {
createCanvas(400,200);
background(0);
// draw center line
stroke(255);
line(width/2, 0, width/2, height);
for (var i = 0; i < 1000; i++) {
// uniform random on the left
point(random(width/2), random(height));
// Gaussian noise on the right
point(randomGaussian(width * 3/4, 30), randomGaussian(height/2, 30));
}
}
function draw() {
};
```

Notice how the Gaussian case concentrates choices around the mean value (here, at the center of the right square) while uniform random spreads the points more-or-less equally everywhere. Also, there are probably some Gaussian points that are outside the bounds of the right square. You should test and reject out-of-bounds points if it matters.

## Technique: “Gaussian” with Limits

Suppose you want a non-uniform distribution, but you want to restrict the range of values. You could simply replace `x`

by `min(x, limit)`

, but then whenever `x`

is out of bounds, it gets replaced by `limit`

, so points could pile up on the boundary. Here’s what that looks like. Notice that a number of points show up 10 pixels from the edge due to the min/max functions:

```
function setup() {
createCanvas(200,200);
background(0);
// draw center line
stroke(255);
for (var i = 0; i < 1000; i++) {
// Gaussian noise for both x,y centered on canvas
var x = randomGaussian(width/2, 50);
var y = randomGaussian(height/2, 50);
// force x, y within 10 pixels inside canvas edge
x = max(10, min(width - 10, x));
y = max(10, min(height - 10, y));
point(x, y);
}
}
function draw() {
};
```

A better idea is to simply keep picking random numbers until you get something in bounds. This is a great place to use a `while`

loop. The essence of the approach is this: “Pick a value. *While* value is out of bounds, pick a new value.” Notice the points piled up near the borders are gone here. We simply picked new values.

```
function setup() {
createCanvas(200,200);
background(0);
// draw center line
stroke(255);
for (var i = 0; i < 1000; i++) {
// Gaussian noise for both x,y centered on canvas
var x = randomGaussian(width/2, 50);
while (x < 10 || x > width - 10) {
// test was true, so run the loop body...
// x is out of bounds, try again
x = randomGaussian(width/2, 50);
}
// test was false, so now x must be in bounds
// compute y just like x: keep looping until value is in bounds
var y = randomGaussian(height/2, 50);
while (y < 10 || y > height - 10) {
y = randomGaussian(height/2, 50);
}
point(x, y);
}
}
function draw() {
};
```

## Gaussian Noise with Colors

You could get a similar effect by just not drawing points that are out of bounds. This would result in drawing fewer points, which is probably OK for this application, but maybe you need a Gaussian-like distribution for color selection, so simply ignoring bad values is not an option. Here’s some code that adds limited Gaussian noise to colors. Note that mouseX controls the standard deviation of the Gaussian values.

```
function setup() {
createCanvas(200,200);
frameRate(1);
}
function draw() {
var range = 50; // random r ranges from -100 to 100
background(0);
noStroke();
for (var x = 0; x < width; x += 5) {
for (var y = 0; y < height; y += 5) {
var r = randomGaussian(0, mouseX / 5);
while (r < -range || r > range) {
r = randomGaussian(0, 20);
}
fill(128, 200 + r, 180 - r); // add some random to G & B
rect(x, y, 5, 5);
}
}
};
```

# Skewing with Power

Suppose you want to add an offset to some number to achieve some artistic variation. You want the offset to be small (normally) but sometimes much larger. Consider the simple expression `x * x`

. If `x`

is in the range 0 to 1, `x * x`

will be smaller than `x`

. E.g. if x = 1/2, then x*x = 1/4. However, if x=1, then x*x = 1. Thus, x*x has the same range as x, but the values are skewed toward zero. We can get an even more extreme skew toward zero by computing x*x*x, or x*x*x*x, etc. Multiplication is cheap, and the more multiplies, the less likely it is to get a large number (i.e. close to 1).

## Power

Instead of writing x*x or x*x*x, we can write `Math.pow(x, 2)`

or `Math.pow(x, 3)`

. The `pow`

function has the advantage that we can use a parameter for the exponent. If you are not familiar with the “power” function or exponents, please review the subject and see the reference for Math.pow. E.g. instead of `Math.pow(x, 2)`

, we can write `Math.pow(x, skew)`

, where `skew`

is a variable we can easily adjust to get the effect we want.

Here is an example: The goal is to *occasionally* produce a bright circle. The `skew`

parameter can be varied with the mouse:

```
var skew = 4;
function setup() {
createCanvas(200,200);
frameRate(10);
}
function draw() {
background(0);
skew = mouseX;
noStroke();
skew = map(mouseX, 0, width, 0, 10);
text("move mouse to change skew", 10, 10);
text("skew = " + skew.toFixed(2), 10, 25);
fill(Math.pow(random(1), skew) * 255);
ellipse(width/2, height/2, width/2, height/2);
}
```

# Playing with Random Functions

There’s no “right” or “wrong” way to use random values. Uniform random is just that — random. As you add *structure* to randomness by shaping the distribution, applying maximum and minimum limits, and perhaps other rules, constraints, and behaviors, you progressively move from “random” to “generative” or “algorithmic” — i.e. deliberate artistic expression.

Combining functions to get complex behavior is standard fare. For example, if you raise Perlin noise values to some power using `Math.pow()`

, you can achieve the smoothness of Perlin noise while skewing the values to mostly near-zero values.

You can also add non-random variation using our old friends `sin()`

and `cos()`

, which produce regular oscillations.

Experimentation and progressive refinement is the key.

# Smooth Motion

Perlin noise has the nice feature that it is “smooth” — small parameter changes result in small output changes. Uniform `random`

and `guassianRandom`

functions jump around when you pick a new value. If you want to use random numbers for controlling positions, whether you are drawing lines or creating animation, you probably want smooth transitions as opposed to jumps. One way to do this in drawing is to use curves and Bezier splines to do the smooth interpolation. With animation, other techniques can be used. Mainly, you can use random points to establish targets or attractors, and then move the object or control parameter (e.g. an angle) smoothly in the direction of the target/attractor. We will spend some time soon on physics, gravity, attraction, acceleration, and smooth motion.