Outline

In this week’s lab you will:

  • learn about transforms: translate, rotate & scale
  • write your own functions to package up “drawing” units
  • build a kaleidoscope

Pre-lab checklist

Before you attend your lab session, make sure:

  • you can fork, pull & push to GitLab
  • you’ve watched the week 3 lecture on iteration

Introduction

When you were a kid you might have had a kaleidoscope toy which looked something like this:

Classic tin kaleidoscope

and when you looked through the tube you saw something like this:

View inside a kaleidoscope

Kaleidoscopes work by using mirrors to create multiple reflections of a simple pattern, which can produce beautiful geometric patterns like the picture above.

By the end of today’s lab (part 4) you’ll be able to use p5’s built-in transformation functions to do the same sort of thing. But first, you’ll do a couple of exercises to help you get your head around exactly what it means to transform the grid in p5.

If you’re proud of your nametag, you should go and share it on the official nametag tthread — and go checkout what everyone else did.

Part 1: scale, rotate and translate

Before we can start work on our kaleidoscope, we need to learn about three new p5.js functions: scale(), rotate(), and translate(). In the business, we call these “transform” functions—cause they transform the grid you draw on (maybe you can see how this could be helpful for a kaleidoscope?).

Below you’ll find a widget containing some p5.js code that is half finished. Your job is to drag the lines of code from the left-hand-side to the right-hand-side to try and achieve the following goals:

  1. Can you move the square to the left? Or the right? (requires 1 block of code)
  2. Can you move the square to the center of the canvas? (requires 1 block of code)
  3. Can you rotate the square in the center of the screen? (requires 2 blocks of code, one of which you just wrote!)
  4. Can you make the square bigger, or smaller? (requires 1 block of code)

If you get stuck, ask your tutor for help—or give the reference a read (otherwise, maybe you can figure it out by just trying random options!). Here’s links to the references for:

Beware, for the rotate() function p5 talks about angles in radians (where 360 degrees equals two pi radians). Also, it’s important to remember that rotation happens around the x=0, y=0 point (the origin), not the centre of the canvas.

Play around with the different code blocks and arguments to try and build an intuition about what they do to the canvas.

Did you discover anything cool? Send a message to your labs Teams channel describing your discovery, and how to re-create it.

Part 2: a draw functions

Now we’re going back to VSCode. Fork and then clone the lab 5 template repo, open it in VSCode and start the live server as usual.

Write some code in your draw() loop that draws a simple shape using the primitive p5.js functions you’ve learnt so far (rect, ellipse, line, etc.). Examples might be a house, a flower, a cross — be creative, but don’t spend too much time on it (simple is good!).

Now we’re going to write a function to draw this shape. Package up the “shape drawing” code you just wrote into a function which takes x and y parameters, and then draws the thing at that location. It’ll look something like this:

function drawShape(x, y){
  // draw all the things using the x and y parameters
}

Call your new function multiple times in your draw loop, with different co-ordinates. Once you’ve got the hang of drawing the exact same shape in different places, can you add an additional parameter to the function so that you can draw the shape with a different size each time? How about passing in some sort of colour parameter?

At the end of this part, your sketch should draw a bunch of similar shapes to the canvas. You want your sketch to have good coverage of the canvas, but also to leave some blank space (i.e. you don’t want to paint the whole canvas with your shapes). The reasons for this will become clear in the next section.

Copy the code for your shape function and share it with your labs channel on Teams. This is very important (read on to find out why)!

Why would you want to package your drawing code into a function. What’s the main benefit? What are the downsides? If you’re struggling to think of anything, ask your tutor—maybe they can point you in the right direction.

Part 3: kaleidoscope

Find a partner in your labs Teams channel. If no-one else is currently looking for a partner, send a message advertising yourself—if someone is, join them! Once you’ve found someone, let one of your tutors know and they will set up a meeting for you to collaborate in.

Now, the moment you’ve been waiting for—you finally get to make a kaleidoscope, and we’ll be using you and your partners shape functions from the previous exercise to do it! Don’t be scared, this is actually kind of straightforward if you’ve got the hang of the previous parts of this lab.

The main difference between a kaleidoscope and Part 2, is that you want to iterate the process many times (to simulate the multiple reflections which happen inside the kaleidoscope). To that end, we need to modify our draw loop so it looks like the following:

// put this in your draw loop
translate(windowWidth/2, windowHeight/2);
var numRotations = 10;
for(var i = 0; i < numRotations; i++) {
  rotate(TWO_PI/numRotations);
  // put your cool shape drawing code in here
}

If you haven’t already, you should copy your own and your partners shape functions from the previous exercise into your sketch.js file and call both of them inside the for loop, after the rotate function.

This code uses the “translate by width/2, height/2 then rotate” trick to make the canvas rotate around the centre point. Why does this work?

Now, do one of the following things:

  1. Add some sort of dynamic behaviour to your shape drawing code (i.e. use mouseX or frameCount somewhere)
  2. Add another persons shape to your code
  3. Add in another loop, but this time rotating in the opposite direction
  4. Do something entirely different — be creative!

When you get a kaleidoscope sketch that you’re happy with, commit & push it up to your fork on GitLab — and then share it with the rest of the class on Teams. Check out what other students have done, and think about how they did it. While these labs aren’t assessable, you really should make the most of them opportunities to develop your skills!

Have a think (and play around!) to find out what shapes work best as a building block for this kaleidoscope process? What makes them work so well?

Part 4: break it down!

Here’s some kaleidoscope code which looks much more like the traditional kids toy tube thing we talked about in the introduction.

Open up a cocoding session on p5live (have one person make the session, and have the other join). Copy and paste the code bellow in so you can work on it together — try and make it your own, be creative!

This sketch uses the p5 push() and pop() functions (which “save” and “restore” the current transformation) but these are different from the Array push() and (pop() that we talked about in the week 4 lecture. Because naming things is hard, and those names (push and pop) are re-used in a bunch of ways across all different types of programming.

Even though it looks complicated, this is a relatively simple extension to the stuff you did in this lab, the only addition is that it uses an image mask to draw only one “pizza slice” shaped part of the canvas, but to re-draw it many times in a radial pattern (just like a real kaleidoscope). There’s a bit of stuff in there that we haven’t covered in lectures yet (mostly the image masking stuff) so don’t worry if you don’t understand all of it just yet. Still, it’s quite pretty—so definitely have a play with it and break it down if you get the chance.

Summary

Congratulations! In this lab you:

  • learnt about transforms: translate, rotate & scale
  • wrote your own functions to package up “drawing” units
  • built a kaleidoscope

Updated:    11 Jan 2021 / Responsible Officer:    Head of School / Page Contact:    Charles Martin