Parameterized Drawing

Review

Last week we saw that we can make simple drawings by using functions like rect(), ellipse(), and triangle():

In [1]:
rect(10, 30, 20, 50);
Sketch #1:

Sketch #1 state: Loading...

Setup and Draw

Now, we learn about creating two special functions, setup() and draw():

In [2]:
void setup() {
    
}

void draw() {
    rect(10, 30, 20, 50);
}
Sketch #2:

Sketch #2 state: Loading...

Notice that we put our old drawing functions inside the curly brackets of the draw function.

One big difference is that in the original drawing, the rectangle was drawn once. In this new version, the draw() is called over and over forever. That means that this rectangle is being redrawn about 30 times a second!

Why would we want to do that?

Consider the following code:

In [4]:
void setup() {
    
}

void draw() {
    background(0);
    rect(mouseX - 10, mouseY - 25, 20, 50);
}
Sketch #4:

Sketch #4 state: Loading...

If you move your mouse around in the canvas, what happens? Why? How could you make this better?

Parameterized Face

In Chapter 2, we see how to draw a "parameterized" face. That simply means that the face is being drawn based on a single "parameter"... head size.

First, let's take a look at the original code:

In [5]:
/*------------------------------------------------------------
Copyright (c) 2013, friends of Ed (An Apress Company)
All rights reserved.

The code provided here accompanies the book:

Processing: Creative Coding and Generative Art in Processing 2
By Ira Greenberg, Dianna Xu, and Deepak Kumar
friends of Ed (An APress Company), 2013
ISBN-13 978-1430244646
Please refer to the associated README for a full disclaimer.
------------------------------------------------------------*/
// algorithmic_face.pde, chapter 2
// Algorithmic approach to drawing a face.

// Simple Algorithmic Face
size(600, 800);
background(0);
stroke(255);
noFill();
// draw ellipses from top left corner
ellipseMode(CORNER); 

// BEGIN DECLARE/INITIALIZE VARIABLES
// HEAD 
float headHeight = 600;
float headWidth = headHeight*5/7;
float head_x = (width-headWidth)/2;
float head_y = (height-headHeight)/2;

// EYES
float eyeWidth = headWidth/5;
float eyeHeight = eyeWidth/2;
float irisDiam = eyeHeight;
float pupilDiam = irisDiam/3;
float eye_y = head_y+headHeight/2-eyeHeight/2;
// left
float leftEye_x = head_x+eyeWidth;
float leftIris_x = leftEye_x + eyeWidth/2-irisDiam/2;
float leftPupil_x = leftEye_x + eyeWidth/2-pupilDiam/2;
// right
float rightEye_x = head_x+eyeWidth*3;
float rightIris_x = rightEye_x + eyeWidth/2-irisDiam/2;
float rightPupil_x = rightEye_x + eyeWidth/2-pupilDiam/2;

//EYEBROWS
float eyeBrowWidth = eyeWidth*1.25;
float eyeBrowHeight = eyeHeight/4;
float eyeBrow_y = eye_y - eyeHeight - eyeBrowHeight/2;
// left
float leftEyeBrow_x = leftEye_x - (eyeBrowWidth-eyeWidth);
// right
float rightEyeBrow_x = rightEye_x;

// NOSE
float nose_x = head_x+eyeWidth*2;
float nose_y = head_y + headHeight - headHeight/4;

// MOUTH
float mouthWidth = eyeWidth*1.5;
float mouthHeight = headHeight/12;
float mouth_x = leftIris_x+irisDiam/2+eyeWidth/4;
float mouth_y = nose_y + mouthHeight;

// EARS
float earWidth = eyeHeight*1.5;
float earHeight = headHeight/4;
float ear_y = eyeBrow_y;
// left
float leftEar_x = head_x-earWidth/2;
// right
float rightEar_x = head_x+headWidth-earWidth/2;

// BEGIN DRAWING
// Draw head
ellipse(head_x, head_y, headWidth, headHeight); 
// left eye
ellipse(leftEye_x, eye_y, eyeWidth, eyeHeight);
// Draw left iris
ellipse(leftIris_x, eye_y, irisDiam, irisDiam);
// Draw left pupil
ellipse(leftPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
// Draw right eye
ellipse(rightEye_x, eye_y, eyeWidth, eyeHeight); 
// Draw right iris
ellipse(rightIris_x, eye_y, irisDiam, irisDiam);
// Draw right pupil
ellipse(rightPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
// Draw left eyebrow
rect(leftEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
// Draw right eyebrow
rect(rightEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
// Draw nose
triangle(nose_x, nose_y, nose_x+eyeWidth, nose_y, nose_x + eyeWidth/2, nose_y-eyeWidth);
// Draw Mouth - top lip
arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, PI, TWO_PI);
// Draw Mouth - bottom lip
arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, 0, PI);
// Draw Mouth – crease
line(mouth_x, mouth_y, mouth_x+mouthWidth, mouth_y);
// Draw left ear
arc(leftEar_x, ear_y, earWidth, earHeight, PI/2.3, PI*1.55);
// Draw right ear
arc(rightEar_x, ear_y, earWidth, earHeight, -PI/1.8, PI/1.8);
Sketch #5:

Sketch #5 state: Loading...

Scary!

But, the power of this code is that we can change a single number, and it will look completely different:

In [6]:
/*------------------------------------------------------------
Copyright (c) 2013, friends of Ed (An Apress Company)
All rights reserved.

The code provided here accompanies the book:

Processing: Creative Coding and Generative Art in Processing 2
By Ira Greenberg, Dianna Xu, and Deepak Kumar
friends of Ed (An APress Company), 2013
ISBN-13 978-1430244646
Please refer to the associated README for a full disclaimer.
------------------------------------------------------------*/
// algorithmic_face.pde, chapter 2
// Algorithmic approach to drawing a face.

// Simple Algorithmic Face
size(600, 800);
background(0);
stroke(255);
noFill();
// draw ellipses from top left corner
ellipseMode(CORNER); 

// BEGIN DECLARE/INITIALIZE VARIABLES
// HEAD 
float headHeight = 100;
float headWidth = headHeight*5/7;
float head_x = (width-headWidth)/2;
float head_y = (height-headHeight)/2;

// EYES
float eyeWidth = headWidth/5;
float eyeHeight = eyeWidth/2;
float irisDiam = eyeHeight;
float pupilDiam = irisDiam/3;
float eye_y = head_y+headHeight/2-eyeHeight/2;
// left
float leftEye_x = head_x+eyeWidth;
float leftIris_x = leftEye_x + eyeWidth/2-irisDiam/2;
float leftPupil_x = leftEye_x + eyeWidth/2-pupilDiam/2;
// right
float rightEye_x = head_x+eyeWidth*3;
float rightIris_x = rightEye_x + eyeWidth/2-irisDiam/2;
float rightPupil_x = rightEye_x + eyeWidth/2-pupilDiam/2;

//EYEBROWS
float eyeBrowWidth = eyeWidth*1.25;
float eyeBrowHeight = eyeHeight/4;
float eyeBrow_y = eye_y - eyeHeight - eyeBrowHeight/2;
// left
float leftEyeBrow_x = leftEye_x - (eyeBrowWidth-eyeWidth);
// right
float rightEyeBrow_x = rightEye_x;

// NOSE
float nose_x = head_x+eyeWidth*2;
float nose_y = head_y + headHeight - headHeight/4;

// MOUTH
float mouthWidth = eyeWidth*1.5;
float mouthHeight = headHeight/12;
float mouth_x = leftIris_x+irisDiam/2+eyeWidth/4;
float mouth_y = nose_y + mouthHeight;

// EARS
float earWidth = eyeHeight*1.5;
float earHeight = headHeight/4;
float ear_y = eyeBrow_y;
// left
float leftEar_x = head_x-earWidth/2;
// right
float rightEar_x = head_x+headWidth-earWidth/2;

// BEGIN DRAWING
// Draw head
ellipse(head_x, head_y, headWidth, headHeight); 
// left eye
ellipse(leftEye_x, eye_y, eyeWidth, eyeHeight);
// Draw left iris
ellipse(leftIris_x, eye_y, irisDiam, irisDiam);
// Draw left pupil
ellipse(leftPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
// Draw right eye
ellipse(rightEye_x, eye_y, eyeWidth, eyeHeight); 
// Draw right iris
ellipse(rightIris_x, eye_y, irisDiam, irisDiam);
// Draw right pupil
ellipse(rightPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
// Draw left eyebrow
rect(leftEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
// Draw right eyebrow
rect(rightEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
// Draw nose
triangle(nose_x, nose_y, nose_x+eyeWidth, nose_y, nose_x + eyeWidth/2, nose_y-eyeWidth);
// Draw Mouth - top lip
arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, PI, TWO_PI);
// Draw Mouth - bottom lip
arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, 0, PI);
// Draw Mouth – crease
line(mouth_x, mouth_y, mouth_x+mouthWidth, mouth_y);
// Draw left ear
arc(leftEar_x, ear_y, earWidth, earHeight, PI/2.3, PI*1.55);
// Draw right ear
arc(rightEar_x, ear_y, earWidth, earHeight, -PI/1.8, PI/1.8);
Sketch #6:

Sketch #6 state: Loading...

Parameterized Functions

Now, let's combine what you know about setup() and draw() with this code.

  1. First, put all of the code that is done once inside the setup() function
  2. Put the rest of the code inside the draw() function
In [7]:
/*------------------------------------------------------------
Copyright (c) 2013, friends of Ed (An Apress Company)
All rights reserved.

The code provided here accompanies the book:

Processing: Creative Coding and Generative Art in Processing 2
By Ira Greenberg, Dianna Xu, and Deepak Kumar
friends of Ed (An APress Company), 2013
ISBN-13 978-1430244646
Please refer to the associated README for a full disclaimer.
------------------------------------------------------------*/
// algorithmic_face.pde, chapter 2
// Algorithmic approach to drawing a face.

// Simple Algorithmic Face

void setup() {
    size(600, 800);
    background(0);
    stroke(255);
    noFill();
    // draw ellipses from top left corner
    ellipseMode(CORNER); 
}

// BEGIN DECLARE/INITIALIZE VARIABLES
// HEAD 

void draw() {
    float headHeight = 600;
    float headWidth = headHeight*5/7;
    float head_x = (width-headWidth)/2;
    float head_y = (height-headHeight)/2;

    // EYES
    float eyeWidth = headWidth/5;
    float eyeHeight = eyeWidth/2;
    float irisDiam = eyeHeight;
    float pupilDiam = irisDiam/3;
    float eye_y = head_y+headHeight/2-eyeHeight/2;
    // left
    float leftEye_x = head_x+eyeWidth;
    float leftIris_x = leftEye_x + eyeWidth/2-irisDiam/2;
    float leftPupil_x = leftEye_x + eyeWidth/2-pupilDiam/2;
    // right
    float rightEye_x = head_x+eyeWidth*3;
    float rightIris_x = rightEye_x + eyeWidth/2-irisDiam/2;
    float rightPupil_x = rightEye_x + eyeWidth/2-pupilDiam/2;

    //EYEBROWS
    float eyeBrowWidth = eyeWidth*1.25;
    float eyeBrowHeight = eyeHeight/4;
    float eyeBrow_y = eye_y - eyeHeight - eyeBrowHeight/2;
    // left
    float leftEyeBrow_x = leftEye_x - (eyeBrowWidth-eyeWidth);
    // right
    float rightEyeBrow_x = rightEye_x;

    // NOSE
    float nose_x = head_x+eyeWidth*2;
    float nose_y = head_y + headHeight - headHeight/4;

    // MOUTH
    float mouthWidth = eyeWidth*1.5;
    float mouthHeight = headHeight/12;
    float mouth_x = leftIris_x+irisDiam/2+eyeWidth/4;
    float mouth_y = nose_y + mouthHeight;

    // EARS
    float earWidth = eyeHeight*1.5;
    float earHeight = headHeight/4;
    float ear_y = eyeBrow_y;
    // left
    float leftEar_x = head_x-earWidth/2;
    // right
    float rightEar_x = head_x+headWidth-earWidth/2;

    // BEGIN DRAWING
    // Draw head
    ellipse(head_x, head_y, headWidth, headHeight); 
    // left eye
    ellipse(leftEye_x, eye_y, eyeWidth, eyeHeight);
    // Draw left iris
    ellipse(leftIris_x, eye_y, irisDiam, irisDiam);
    // Draw left pupil
    ellipse(leftPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
    // Draw right eye
    ellipse(rightEye_x, eye_y, eyeWidth, eyeHeight); 
    // Draw right iris
    ellipse(rightIris_x, eye_y, irisDiam, irisDiam);
    // Draw right pupil
    ellipse(rightPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
    // Draw left eyebrow
    rect(leftEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
    // Draw right eyebrow
    rect(rightEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
    // Draw nose
    triangle(nose_x, nose_y, nose_x+eyeWidth, nose_y, nose_x + eyeWidth/2, nose_y-eyeWidth);
    // Draw Mouth - top lip
    arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, PI, TWO_PI);
    // Draw Mouth - bottom lip
    arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, 0, PI);
    // Draw Mouth – crease
    line(mouth_x, mouth_y, mouth_x+mouthWidth, mouth_y);
    // Draw left ear
    arc(leftEar_x, ear_y, earWidth, earHeight, PI/2.3, PI*1.55);
    // Draw right ear
    arc(rightEar_x, ear_y, earWidth, earHeight, -PI/1.8, PI/1.8);
}
Sketch #7:

Sketch #7 state: Loading...

What is different between this code and the original face?

Creating your own functions

Let's move all of that code for drawing a face into its own function, drawFace()

Note that draw and setup are specially named functions. But drawFace() can be named anything.

In [8]:
/*------------------------------------------------------------
Copyright (c) 2013, friends of Ed (An Apress Company)
All rights reserved.

The code provided here accompanies the book:

Processing: Creative Coding and Generative Art in Processing 2
By Ira Greenberg, Dianna Xu, and Deepak Kumar
friends of Ed (An APress Company), 2013
ISBN-13 978-1430244646
Please refer to the associated README for a full disclaimer.
------------------------------------------------------------*/
// algorithmic_face.pde, chapter 2
// Algorithmic approach to drawing a face.

// Simple Algorithmic Face

void setup() {
    size(600, 800);
    background(0);
    stroke(255);
    noFill();
    // draw ellipses from top left corner
    ellipseMode(CORNER); 
}

// BEGIN DECLARE/INITIALIZE VARIABLES
// HEAD 

void drawFace(float headHeight) {

    //float headHeight = 600;
    float headWidth = headHeight*5/7;
    float head_x = (width-headWidth)/2;
    float head_y = (height-headHeight)/2;

    // EYES
    float eyeWidth = headWidth/5;
    float eyeHeight = eyeWidth/2;
    float irisDiam = eyeHeight;
    float pupilDiam = irisDiam/3;
    float eye_y = head_y+headHeight/2-eyeHeight/2;
    // left
    float leftEye_x = head_x+eyeWidth;
    float leftIris_x = leftEye_x + eyeWidth/2-irisDiam/2;
    float leftPupil_x = leftEye_x + eyeWidth/2-pupilDiam/2;
    // right
    float rightEye_x = head_x+eyeWidth*3;
    float rightIris_x = rightEye_x + eyeWidth/2-irisDiam/2;
    float rightPupil_x = rightEye_x + eyeWidth/2-pupilDiam/2;

    //EYEBROWS
    float eyeBrowWidth = eyeWidth*1.25;
    float eyeBrowHeight = eyeHeight/4;
    float eyeBrow_y = eye_y - eyeHeight - eyeBrowHeight/2;
    // left
    float leftEyeBrow_x = leftEye_x - (eyeBrowWidth-eyeWidth);
    // right
    float rightEyeBrow_x = rightEye_x;

    // NOSE
    float nose_x = head_x+eyeWidth*2;
    float nose_y = head_y + headHeight - headHeight/4;

    // MOUTH
    float mouthWidth = eyeWidth*1.5;
    float mouthHeight = headHeight/12;
    float mouth_x = leftIris_x+irisDiam/2+eyeWidth/4;
    float mouth_y = nose_y + mouthHeight;

    // EARS
    float earWidth = eyeHeight*1.5;
    float earHeight = headHeight/4;
    float ear_y = eyeBrow_y;
    // left
    float leftEar_x = head_x-earWidth/2;
    // right
    float rightEar_x = head_x+headWidth-earWidth/2;

    // BEGIN DRAWING
    // Draw head
    ellipse(head_x, head_y, headWidth, headHeight); 
    // left eye
    ellipse(leftEye_x, eye_y, eyeWidth, eyeHeight);
    // Draw left iris
    ellipse(leftIris_x, eye_y, irisDiam, irisDiam);
    // Draw left pupil
    ellipse(leftPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
    // Draw right eye
    ellipse(rightEye_x, eye_y, eyeWidth, eyeHeight); 
    // Draw right iris
    ellipse(rightIris_x, eye_y, irisDiam, irisDiam);
    // Draw right pupil
    ellipse(rightPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
    // Draw left eyebrow
    rect(leftEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
    // Draw right eyebrow
    rect(rightEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
    // Draw nose
    triangle(nose_x, nose_y, nose_x+eyeWidth, nose_y, nose_x + eyeWidth/2, nose_y-eyeWidth);
    // Draw Mouth - top lip
    arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, PI, TWO_PI);
    // Draw Mouth - bottom lip
    arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, 0, PI);
    // Draw Mouth – crease
    line(mouth_x, mouth_y, mouth_x+mouthWidth, mouth_y);
    // Draw left ear
    arc(leftEar_x, ear_y, earWidth, earHeight, PI/2.3, PI*1.55);
    // Draw right ear
    arc(rightEar_x, ear_y, earWidth, earHeight, -PI/1.8, PI/1.8);
}

void draw() {
    drawFace(500);
}
Sketch #8:

Sketch #8 state: Loading...

Putting it all together

Finally, we take advantage of the draw function being called over and over again... we change how the face is drawn each time!

In [12]:
/*------------------------------------------------------------
Copyright (c) 2013, friends of Ed (An Apress Company)
All rights reserved.

The code provided here accompanies the book:

Processing: Creative Coding and Generative Art in Processing 2
By Ira Greenberg, Dianna Xu, and Deepak Kumar
friends of Ed (An APress Company), 2013
ISBN-13 978-1430244646
Please refer to the associated README for a full disclaimer.
------------------------------------------------------------*/
// algorithmic_face.pde, chapter 2
// Algorithmic approach to drawing a face.

// Simple Algorithmic Face

void setup() {
    size(600, 800);
    background(0);
    stroke(255);
    noFill();
    // draw ellipses from top left corner
    ellipseMode(CORNER); 
}

// BEGIN DECLARE/INITIALIZE VARIABLES
// HEAD 

void drawDoug(float headHeight) {

    //float headHeight = 600;
    float headWidth = headHeight*5/7;
    float head_x = (width-headWidth)/2;
    float head_y = (height-headHeight)/2;

    // EYES
    float eyeWidth = headWidth/5;
    float eyeHeight = eyeWidth/2;
    float irisDiam = eyeHeight;
    float pupilDiam = irisDiam/3;
    float eye_y = head_y+headHeight/2-eyeHeight/2;
    // left
    float leftEye_x = head_x+eyeWidth;
    float leftIris_x = leftEye_x + eyeWidth/2-irisDiam/2;
    float leftPupil_x = leftEye_x + eyeWidth/2-pupilDiam/2;
    // right
    float rightEye_x = head_x+eyeWidth*3;
    float rightIris_x = rightEye_x + eyeWidth/2-irisDiam/2;
    float rightPupil_x = rightEye_x + eyeWidth/2-pupilDiam/2;

    //EYEBROWS
    float eyeBrowWidth = eyeWidth*1.25;
    float eyeBrowHeight = eyeHeight/4;
    float eyeBrow_y = eye_y - eyeHeight - eyeBrowHeight/2;
    // left
    float leftEyeBrow_x = leftEye_x - (eyeBrowWidth-eyeWidth);
    // right
    float rightEyeBrow_x = rightEye_x;

    // NOSE
    float nose_x = head_x+eyeWidth*2;
    float nose_y = head_y + headHeight - headHeight/4;

    // MOUTH
    float mouthWidth = eyeWidth*1.5;
    float mouthHeight = headHeight/12;
    float mouth_x = leftIris_x+irisDiam/2+eyeWidth/4;
    float mouth_y = nose_y + mouthHeight;

    // EARS
    float earWidth = eyeHeight*1.5;
    float earHeight = headHeight/4;
    float ear_y = eyeBrow_y;
    // left
    float leftEar_x = head_x-earWidth/2;
    // right
    float rightEar_x = head_x+headWidth-earWidth/2;

    // BEGIN DRAWING
    // Draw head
    ellipse(head_x, head_y, headWidth, headHeight); 
    // left eye
    ellipse(leftEye_x, eye_y, eyeWidth, eyeHeight);
    // Draw left iris
    ellipse(leftIris_x, eye_y, irisDiam, irisDiam);
    // Draw left pupil
    ellipse(leftPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
    // Draw right eye
    ellipse(rightEye_x, eye_y, eyeWidth, eyeHeight); 
    // Draw right iris
    ellipse(rightIris_x, eye_y, irisDiam, irisDiam);
    // Draw right pupil
    ellipse(rightPupil_x, eye_y+eyeHeight/2-pupilDiam/2, pupilDiam, pupilDiam);
    // Draw left eyebrow
    rect(leftEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
    // Draw right eyebrow
    rect(rightEyeBrow_x, eyeBrow_y, eyeBrowWidth, eyeBrowHeight);
    // Draw nose
    triangle(nose_x, nose_y, nose_x+eyeWidth, nose_y, nose_x + eyeWidth/2, nose_y-eyeWidth);
    // Draw Mouth - top lip
    arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, PI, TWO_PI);
    // Draw Mouth - bottom lip
    arc(mouth_x, mouth_y-mouthHeight/2, mouthWidth, mouthHeight, 0, PI);
    // Draw Mouth – crease
    line(mouth_x, mouth_y, mouth_x+mouthWidth, mouth_y);
    // Draw left ear
    arc(leftEar_x, ear_y, earWidth, earHeight, PI/2.3, PI*1.55);
    // Draw right ear
    arc(rightEar_x, ear_y, earWidth, earHeight, -PI/1.8, PI/1.8);
}

void draw() {
    background(0);
    drawDoug(600 - mouseX);
}
Sketch #11:

Sketch #11 state: Loading...