week02 01 repetition - UX-UI-Design-Lab/DesignAesthetics3 GitHub Wiki
agenda:
- variable
- system variables: width and height
- define your own variables - using var, let, const
- activity: drawing a grid system (modular design)
- for-statement (how to start, how to end, the interval)
- assignment2
variables
As we start drawing multiple components, a more efficient solution to manage the numbers would be desired. Variable in programming is a kind of container you can store a certain data (including numbers). Or you can think it as post-it where you may write a phone number for example. If you are asked to recall the number, you will simply take that post-it to refer to the phone number. If there is any changes in number, you will correct the number on the post-it, but as far as you can access the post-it, you can easily use that phone number.
In p5, there are some variables you can easily refer to the data in the current setting. For example, the canvas size - you can call width and height to get the current canvas's width and height.
function setup() {
createCanvas(400, 400);
}
function draw() {
console.log(width);
}
This will show the current canvas width = 400 in Console window.
It is useful when you want to use the current canvas size as a reference of frame. For example, I would like to draw a circle fully fit into the canvas (diameter = width) and exactly centered in the canvas (center_x = width/2).
circle(centerX, centerY, diameter); // this is the syntax
Originally I used to use 400 like this:
circle(200, 200, 400); // calculated 400/2
but, when the canvas size has been changed (ex. 600, 600) like this:
function setup() {
createCanvas(600, 600);
}
I should write the code again for the circle:
circle(300, 300, 600); // calculated 600/2
If there are many lines of code that depends on the canvas width or height, it is not convenient to change the numbers one by one manually (and it is really easy to make mistakes). It would be great to link those numbers into a variable that can be automatically changed its value (=data or number inside of that variable).
For that needs, there is a system variable - width and height.
circle(width/2, height/2, width); // this is actual code with variables
- change the canvas size into (400, 600) -- how does it change with your circle?
- try with ellipse(center_x, center_y, width, height) - can you see how the width and height variables work?
more of system variables
One of useful system variables you may want to remember is windowWidth and windowHeight. You can use it to set the canvas like this:
createCanvas(windowWidth, windowHeight);
it refers to the window size when the code runs and it doesn't automatically refresh (and redraw) if you change the browser window size during your code is running. (we will learn how to refresh screen later).
The other variables you may like is mouseX and mouseY -- the browser always detect where your mouse is and remember the location. For example, if you want to draw a circle centered on your mouse position:
circle(mouseX, mouseY, width/2);
(and this will give you lots of ideas how you can make some interesting interactive work!)
Make your own variable
As I explained variable is an empty container -- so why not making my own variable if needed? The process will be like this:
- decide a name, it can be meaningful but it doesn't matter if not. It can be short (one letter) or long (but not too long, because if you have a long word, it is easy to make a typo).
- define the variable (or declare the name of your choice as a variable). There are three different types of variable definition: var, let, const (I will explain the differences later).
- put a initial value, if not the variable may come with garbage in it. (literally anything can be in it, just because it reuse the computer's memory which has been gone through many other business before - of course metaphorically)
- update the value if needed
- use it where you need to recall the related data (value in it).
For example, I would like to make a variable for the width of my shape. I want to have the width of the shape as a half-size of the canvas size. Then, I want to use it to draw a rectangle and a circle with that variable. Here you go:
// decide a name, let's call it myWidth
// define the variable, I will use var (var-iable)
var myWidth;
// initial value, half of canvas width. I know I can use the system variable "width" here)
myWidth = width / 2;
// use the variable myWidth to draw a rectangle
rect(0, 0, myWidth, myWidth);
// use the variable myWidth to draw a circle, I will set the center as myWidth and the diameter with myWidth
circle(myWidth, myWidth, myWidth);
The other way you can define variables is using let
. It works almost same way but the scope of the variable is limited within the block (inside of { ... }
). For more information check the link below.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#scoping_rules
const
is another way to define/declare variables, but this is for the read-only variables. That means once you setup the value, you cannot update the value later. It is useful to use const
when you don't want to make a change of its value by mistake.
We will mostly use let
(but I may use var
for some special occasions).
activity: grid system
I want you to draw grid system. You can pick the number (between 3 to 16), for example 3, then make a 3 by 3 grid system. Provide lines to mark the grid - for example 3 by 3, you will draw 3 vertical lines to mark 3 columns and 3 horizontal lines to mark 3 rows. Think (and write) the coordinates (x, y) for each grid line.
Then we will draw that grid-system in p5.
Basically, we can create the grid system with n * 2 number of lines (when you pick the number n). For 3 by 3, you will draw 6 lines. For 16 by 16, you will draw 32 lines. But you can find a rule how to draw each line, like draw the next line XXX distanced. If you can see that number pattern, write the note on your sketch.
This is the first attempt:
// the first vertical line
line(0, 0, 0, 400);
// the second vertical line
line(400/3, 0, 400/3, 400);
// the third vertical line
line(400/3 * 2, 0, 400 /3 *2, 400);
// the first horizontal line
line(0, 0, 400, 0);
// the second horizontal line
line(0, 400/3, 400, 400/3);
// the third horizontal line
line(0, 400/3 * 2, 400, 400 /3 *2);
And I realize that I can use the system variable width, so rewrite the code
// the first vertical line
line(0, 0, 0, height);
// the second vertical line
line(width/3, 0, width/3, height);
// the third vertical line
line(width/3 * 2, 0, width /3 *2, height);
// the first horizontal line
line(0, 0, width, 0);
// the second horizontal line
line(0, height/3, width, height/3);
// the third horizontal line
line(0, height/3 * 2, width, height /3 *2);
Then, I can see a pattern: the changes happen with the multiples!
// the first vertical line
line(width/3 * 0, 0, width/3 * 0, height);
// the second vertical line
line(width/3 * 1, 0, width/3 * 1, height);
// the third vertical line
line(width/3 * 2, 0, width /3 *2, height);
I think it would be great to have something for width/3 * {0, 1, 2} changes. A variable would be great.
// make a variable for vertical line x-position
let positionX;
and assign value width/3 * something. So another variable is needed - I would call it "i" for indexing (0, 1, 2, ...)
// make a variable for indexing, 0, 1, 2, ..., but start with 0
let i = 0; // set the initial value as 0 when the variable is created
// and assign the value "width/3 * i" to positionX
positionX = width/3 *i;
Then, I need to find the way change the index from 0 to 2. Here we need to learn about for-statement.
for
statement
for
is used to create a loop - so you can repeat the code as many as you want.
https://p5js.org/reference/#/p5/for
The syntax of for is:
for(initial-condition; end-condition; how much to skip) {
what you want to repeat;
}
(NOTE: you don't need to put ; after }
)
What I plan is using the variable i
three times, from 0, 1, and 2. If I start with i=0, increasing i by +1 will work, until count 3. This is how you write that plan:
for (i = 0; i < 3; i++) {
- i < 3 means, until i is less than three - or count 3 then end the process.
- i++ means you will increate i value by adding number 1. It is same as i = i + 1; or i += 1; For this form, important thing is that
=
doesn't means equal, but "assign". It goes from the right side, first do i + 1 (old i plus one) and then put the outcome into (=) the left side (i, a new refreshed i). - if I forgot the declare the variable "i", I can do it inside of for when set up the initial value like
if(let i = 0; ...
I would like to draw the lines three times, so the complete code will look like this:
for(let i = 0; i < 3; i++) {
line(width/3 * i, 0, width/3 * i, height);
}
And we can make the code look simpler, by assign width/3*i
to the variable positionX
:
let positionX;
for(let i = 0; i < 3; i++) {
positionX = width/3 * i;
line(positionX, 0, positionX, height);
}
One step further, if I want to change the number of lines later, I think I can make that number of grid as a variable and replace "3" (currently 3-column grid system) with that variable (let's call it n, for n-grid system).
let positionX;
let n = 3; // start with 3-column system but I can change it later
for(let i = 0; i < n; i++) {
positionX = width/n * i;
line(positionX, 0, positionX, height);
}
Then, can you add three horizontal lines? Steps to follow:
-
have a variable for indexing i (=counter)
-
set up
for
with how to start, how to end, and how to skip between start to end.i = 0; i < 3; i++;
-
write the code you want to repeat, ex. I want to draw a line:
line(0, height/3 * i, width, height/3 * i);
-
or make another variable to calculate
height/3 * i
-
and/or make another variable to set the number of row and replace 3 with it.
let positionY; let m = 3; // start with 3-row system but I can change it later for(let i = 0; i < m; i++) { positionY = height/m * i; line(0, positionY, width, positionY); }
By now, can you draw by code the grid system you sketched? What do you need to change from the example above? Share your published link via Canvas.
Nested Loop
You can embed another loop inside of the loop. It is useful to plot 2-D space, when we want to repeat a certain amount shapes on X-axis (that will create a row of repeated shapes) and then want to repeat that row several times on Y-axis. (vice versa)
For example, I want to draw five rectangles, then the pseudo code will be like this:
for(let i = 0; i < 5; i++) {
circle(change_x, change_y, diameter);
}
If I want to draw this row of five circles several times (let's try four rows), I can repeat this whole for-statement.
for(let j = 0; j < 4; j++) {
for(let i = 0; i < 5; i++) {
circle(change_x, change_y, diameter);
}
}
Conceptually, it is easy. But how to link the changes (change_x, change_y) with the changes in i and j is something we need to think (and calculate about). The assignment will help you to try your first nested for.
assignment2: tessellation
I want you to draw a tessellation (2-d pattern) - you will repeat the unit shape(s) into the grid system of your choice.
The ideal condition would be the foreground figure (positive) and background figure are balanced; suggesting opposite meaning (so it may create a new meaning when they put together).
- for your inspiration: https://www.istockphoto.com/illustrations/triangle-tessellation