Week 9 - Timers, Translation, Rotation

Today

  • Translation, Rotation and the Push/Pop matrix
  • Working with time
  • workshop: generative music maker
  • check-ins
  • use camera apps

Translation

Translation moves our coordinate system until the end of an individual run of draw().

//first rectangle
rect(0,0,100,100)

//move the starting coordinates
translate(100,100)

//second rectangle
rect(0,0,100,100)

Observe: We can draw the same rect function with the exact same coordinates. Because we used translate to move the starting coordinate, our second rectangle is drawn 100 pixels over and 100 pixels down.

Translation is additive

If you translate more than once in draw, the new translation coordinates are combined with the previous:

//first rectangle
rect(0,0,100,100)
//move coordinates system
translate(100,100)
//our second rectangle
rect(0,0,100,100)
//move again
translate(100,100)
//our third rectangle
rect(0,0,100,100)

Rotation

If we want to rotate our canvas, we use the rotate() function. By default, we are rotating with radians.

rotate(PI/4)
rect(0,0,100,100)

To use degrees, we must set the angleMode in our setup.

angleMode(DEGREES)
rotate(mouseX)
rect(0,0,100,100)

Rotate from center

Rotation always happens from the 0,0 coordinate. So to rotate from the center of a shape, we must first translate to the center of a shape.

angleMode(DEGREES)
translate(50,50)
rotate(mouseX)
rect(-50,-50,100,100)

In the code above we need to place the rect so it’s center point is at the translation/rotation point. To do that, we first translate, then rotate, then place down the rect exactly so its center is at the point of translation 50,50.

One thing that may make it easier is to draw a rectangle from its center point:

rectMode(CENTER)
angleMode(DEGREES)
translate(50,50)
rotate(mouseX)
rect(0,0,100,100)

Separate coordinate layers

Before, I showed how translation is additive: each time we call translate it continues to move the starting point of the coordinate system based on the previous starting point.

//move starting point to 100,100
translate(100,100)

//move it again
translate(100,100)

//now our starting coordinate is 200,200
rect(0,0,100,100)

Using the push/pop matrix

We can actually separate parts of our code so that they use their own translation independent from each other. Basically, we can place down separate layers with their own coordinate system.

Without push/pop matrix:

background(0)

translate(50,50)
rotate(mouseX)
rect(0,0,100,100)

translate(100,100)
rotate(mouseX)
rect(0,0,100,100)

Without the push/pop matrix, our second translation and second rotation are additive. The first rect rotates as we expect, but the second one is rotating around the first.

To separate them, we use the push/pop matrix:

push()
  translate(50,50)
  rotate(mouseX)
  rect(0,0,100,100)
pop()

push()
  translate(100,100)
  rotate(mouseX)
  rect(0,0,100,100)
pop()

How would you rotate an image?

Timers with millis()

p5.js has a single command for working with time:

millis()

millis() always returns the amount of milliseconds that have elapsed since your program started running.

print("it's been " + millis() + " seconds since our program started");

We can use millis() to create timers.

//check if it's been 3 seconds since our program started
if (millis() > 3000){
  //do something
}

We can make a repeating timer if it’s in our draw and we increase the timer each time it’s triggered. This is like the ‘snooze’ feature on an alarm. It keeps adding a bit more time.

let timer = 3000;
if (millis() > timer){
  //do something
  timer+=3000; //add 3 more seconds to the timer each time it goes off
}

How would we have a random timer?

//pick a random time between 1 and 10 seconds
let timer = random(1000,10000); 

if (millis() > timer){
  //do something
}

challenge: Ambient Music Generator

Starter code

Goal: create an ambient sound generator.

Use a timer. Have a random sound get selected when timer goes off and play that sound.

“One of the notes repeats every 23 1/2 seconds. It is in fact a long loop running around a series of tubular aluminum chairs in Conny Plank’s studio. The next lowest loop repeats every 25 7/8 seconds or something like that. The third one every 29 15/16 seconds or something. What I mean is they all repeat in cycles that are called incommensurable — they are not likely to come back into sync again.” — Brian Eno

Resources

Introduction to Generative Music article How Mubert (Probably) Works article

Brian Eno - How to Make Original Ambient Music video

Generative.fm

References

  • tint in the p5.js reference
  • Bonus: scanner camera scanner effect

Homework

Finish your generative sound program.

  1. Start by reproducing “Music for Airports” with code. Sound should randomly periodically play, at times overlapping (or not).
  2. Then add a visual component. Perhaps an image is randomly presented on screen, or begins moving when a sound begins to play and disappears when it is offscreen. Or something else. See examples such as Mellow Waves and Patatap by Jono Brandel,
  3. OPTIONAL: Use your own sounds or sounds downloaded for example from freesound.org. If you do use creative commons sounds from the internet, be sure to credit the source in a comment in your code.