The random walk is one of the easiest & most fun algorithms one can devise using randomness. True to its name, it involves choosing a starting point and a direction to walk in, and walking there. When repeating these two steps over and over again, we end up with a random walk. Nature of Code, Dan Shiffman's book on generative art, has a detailed section on random walks in its introduction. Take a look if you're curious!
Below is an example for how to implement a random walk. It takes a starting position (center of the page in our case,) and over a certain number of steps it draws a new line to a new random direction.
// Holds all our 'path' objects
// which could be from createPath, or SVGPath string, or polylines
const paths = [];
// ** Random walk example **
// We create our initial coodinate, in the middle of the canvas
let x = width / 2, y = height / 2
// We also set a maximum length for each step of the random walk
let maxStepLength = 1
// Creating the canvas-sketch path, as usual, and moving it to our initial coordinate
let p = createPath()
p.moveTo(x, y)
// We take 20 steps, each time adding a random value between 0 and maxStepLength to our x and y coordinates
for (let i = 0; i < 20; i++) {
x = x + Math.random() * maxStepLength
y = y + Math.random() * maxStepLength
// After updating our coordinates, we simply draw a line to the new point.
p.lineTo(x, y)
}
paths.push(p)
Running this code will produce a line similar to the one below. Since we are using Math.random()
in our composition, refreshing the page will produce different results each time.
We could adjust the maxStepLength
and the total number of steps we take, if we wanted to increase the "resolution" of the line. The example below has a maxStepLength
of 0.1
(1mm) and draws 200 steps. Feel free to play with these parameters in your code, and see what you obtain.
You probably noticed that even though we get a different line every time we refresh the page, the random walk always moves towards the bottom-right of our composition. That is happening because, at every step we add a positive value to both our x
and y
coordinates. Remember, the top-left corner of our composition has coordinates (0, 0)
, and the bottom-right is at (width, height)
. Math.random()
always returns a value between 0
and 1
, so with each step of the for loop, both x
and y
become slightly larger, getting closer to the bottom-right corner.
Let's address that, and adjust our random walk to go in any possible direction at each step. In order to do that, we need x
and y
to be able to travel in both positive and negative directions. So, instead of getting a random value between 0
and 1
, we should get one between -0.5
and 0.5
. We could do that by subtracting 0.5
from the result we're getting from Math.random()
, but the formulas would get slightly more tedious if we were to add more parameters to our range. (e.g. we'd need to multiply the result by 2
if we wanted a random value between -1
and 1
, etc.)
One reason I enjoy working with the canvas-sketch
library is the fact that it has a great utility class for randomness, found under canvas-sketch-util/random
. If you created your sketch using the penplot
template, this will be already imported. If you created it from scratch, you can import this utility by adding the following line to the beginning of your script:
const Random = require('canvas-sketch-util/random')