Chapter 2 – Animation

In the previous chapter we looked at how code art can create emergent patterns through simple (and not so simple) repetitions.

Movement is another feature fundamental to computer graphics. Let’s dive straight into it.

The syntax

Just like in math, we can replace any number with a longer expression, and wrap it in parenthesis (). The expressions start with a function name, followed by the parameters of that function. Here’s an example:

forward (wave 100..200)

Just like in the last chapter, it’s best to try it out in the editor so you will see the visual as well.

The wave function becomes a number that oscillates between 100 and 200. We can also change the frequency (cycles per minute):

forward (wave 100..200 frequency=60)

Since many programmers are lazy, there is also a shorthand:

forward (wave 100..200 f=60)

Like said, the functions can be used anywhere:

repeat (wave 10..30)
    forward 300
    turn-left 129
end-repeat

Or even inside each other:

forward (wave 100..(wave 200..250 f=200))

This becomes more interesting when we combine different functions. Speaking of which...

Linear wave

The wave function is a soft sine wave, but sometimes we want sharpness.

repeat 20
    forward 400
    turn-left (linear 162..150 f=9)
    forward 300
    turn-right 90
end-repeat

The angle in the tips of the star evenly decreases from 162 to 150, then jumps back to 162. And it does that 9 times per minute.

linear is quite handy for rotations that go on forever:

turn-right (linear 0..360)
forward 1000

Another word for linear is sawtooth. They mean the same thing.

Randomness

Randomness is a way to bring human-like imperfection to the art. It doesn’t move.

repeat 100
    forward (random 10..200)
    turn-left 90
end-repeat

Let’s draw a series or bars with random lengths:

backward 400
repeat 80
    forward 10
    turn-left 90
    forward (random 100..200)
    turn-right 180
    forward (random 100..200)
    turn-left 90
end-repeat

This looks pretty, but what if we want the bottoms to align? The random value is different every time, so we can’t just come back the same amount.

Luckily, we can wrap part of the code inside a side-track block, which makes the turtle to return to the same spot after it’s done with the block:

backward 400
repeat 80
    forward 10
    side-track
        turn-left 90
        forward (random 100..200)
    end-side-track
end-repeat

See, we also got rid of two turn commands!

You can also skew the random distribution to favor one end over the other by using the skew parameter:

backward 400
repeat 80
    forward 10
    side-track
        turn-left 90
        forward (random 0..200 skew=250)
    end-side-track
end-repeat

A skew of 0 does nothing. Negative values favor the lower end, and positive values favor the higher end.

To see the effect more clearly, we can animate it:

backward 400
repeat 80
    forward 10
    side-track
        turn-left 90
        forward (random 0..200 skew=(wave -250..250 f=10))
    end-side-track
end-repeat

Simplex noise

Okay, this is the most powerful of them all, once you get the hang of it! Noise is a kind of smooth random that depends on the current location of the turtle. It also changes over time. The noise continues forever and never loops back to the same pattern.

backward 400
repeat 80
    forward 10
    side-track
        turn-left 90
        forward (noise 0..200)
    end-side-track
end-repeat

You can make it less smooth by changing the size parameter (default is 300):

backward 400
repeat 80
    forward 10
    side-track
        turn-left 90
        forward (noise 0..200 size=100)
    end-side-track
end-repeat

The noise function also has a frequency parameter.

To better see what’s happening, try this code and play with the numbers:

backward 500
turn-left 90
backward 500
pen-up
set-thickness 10
repeat 100
    forward 10
    side-track
        turn-right 90
        repeat 100
            pen-down
            set-lightness (noise -30..30 size=300 f=20)
            forward 10
        end-repeat
    end-side-track
end-repeat

Oh, there’s a new set-thickness command. You can probably guess what it does.

Here’s a fun trick: if you move the turtle iteratively based on noise, the next value of noise will change as well (since noise depends on turtle’s location), which in turn will influence the next movement, and so on. This creates a feedback loop that creates quite an unpredictable and heterogenous movement:

repeat 100
    forward (noise 100..300)
    turn-left 90
end-repeat

Computational art allows almost limitless complexity, and it’s up to you to decide how wild you want to go! You don’t need to know what will happen before you try it out – in fact, the last example belongs to the category of chaotic algorithms where it’s mathematically impossible to predict the outcome – without running the code somehow.

Phase

Here’s a little extra: you can change the phase of a wave with the phase (or p) parameter. This way you can create waves that have the same frequency but are out of sync. Phase is measured in percentage of the wave cycle, so 0 is the beginning, 50 is the middle, and 100 is the end.

backward 400
repeat 80
    forward 10
    side-track
        turn-left 90
        forward (wave 0..200 p=(random 0..50))
    end-side-track
end-repeat

Or:

repeat 720
    turn-left 0.5
    side-track
        forward (wave 20..400 p=(random 0..100 skew=120))
    end-side-track
end-repeat

Phase can also be used with linear and noise.

Recap

In this chapter we talked about animations and randomness. You can change any number in the code with one or more of these functions:

We also learned about the side-track block and various parameters, like frequency, phase and size.

In the next chapter we’ll look at how to make tree fractals by cloning the turtle. (coming soon)