Chapter 3: Draw

  1. The Display Window
    1. Example 3-1: Draw a Window
    2. Example 3-2: Draw a Point
  2. Basic Shapes
  3. Drawing Order
    1. Example 3-9: Control Your Drawing Order
    2. Example 3-10: Put it in Reverse
  4. Shape Properties
    1. Example 3-11: Set Stroke Weight
    2. Example 3-12: Set Stroke Caps
    3. Example 3-13: Set Stroke Joins
  5. Drawing Modes
    1. Example 3-14: On the Corner
  6. Color
    1. Example 3-16: Control Fill and Stroke
    2. Example 3-18: Set the Transparency
  7. Custom Shapes
    1. Example 3-19: Draw an Arrow
    2. Example 3-20: Draw Close the Gap
    3. Example 3-21: Create Some Creatures
  8. Comments
  9. Robot1: Draw

Chapter 3: Drawing with Processing

The Display Window (DW)

Output from the Processing Development Environment are put to the Display Window (DW).

The DW is measured in Pixels in a grid of tiny square dots, the smallest element that can be represented on a computer's display screen.

The grid of pixels is measured from the upper left corner starting with 0,0 to the lower right corner with width-1, height-1. That's because its easier to do math in computer coding when you start counting from 0 instead of 1. (There's even a technical name for math errors in code because of this oddity: "OFF By One Error")

PROCESSING

Extra 3-1: Draw a Window (1)

size(100, 100);
Display Window

PROCESSING

Extra 3-1: Draw a Window (2)

size(500, 500);
Bigger display window

PROCESSING

Extra 3-1: Draw a Window (3)

size(500, 100);
Wide display window

Draw A Point

We can set any pixel in the DW with point(x,y), where x and y are the coordinates of the point

PROCESSING

Extra 3-2: Draw a Point

size(500, 100);
point(250,50);
Resulting Display Window

PROCESSING

Extra 3-2: Draw a Point Animated

int x = 0;

void setup() {
  size(500, 100);
}

void draw() {
  point(x, 50);
  x = x + 2;
}
Resulting Display Window

PROCESSING

Extra 3-2: Draw a Point Animated with More Space

int x = 0;

void setup() {
  size(500, 100);
}

void draw() {
  point(x, 50);
  x = x + 3;
}
Resulting Display Window

Basic Shapes

PROCESSING

Example 3-3: Draw a Line

size(200, 200);
line(10, 10, 90, 90); 
Resulting Display Window

line(x1, y1, x2, y2)
starting location x, starting location y,
ending location x, ending location y

PROCESSING

Basic Shapes: Triangle

size(200, 200);
triangle(10, 190, 190, 190, 190, 10);
Resulting Display Window

triangle(x1, y1, x2, y2, x3, x4)
point 1 location x, point 1 location y,
point 2 location x, point 2 location y,
point 3 location x, point 3 location y

PROCESSING

Basic Shapes: Quad

size(200, 200);
quad(80, 20, 180, 80, 100, 180, 20, 100);
Resulting Display Window

quad(x1, y1, x2, y2, x3, y3, x4, y4)
point 1 location x, point 1 location y,
point 2 location x, point 2 location y,
point 3 location x, point 3 location y,
point 4 location x, point 4 location y,

PROCESSING

Basic Shapes: Rect

size(200, 200);
rect(50, 50, 100, 75); 
Resulting Display Window

rect(x, y, w, h)
origin location x, origin location y,
width, height

PROCESSING

Basic Shapes: Ellipse

size(200, 200);
ellipse(100, 100, 150, 150);
Resulting Display Window

ellipse(x, y, w, h)
origin location x, origin location y,
width, height

PROCESSING

Basic Shapes: Arc

size(200, 200);
arc(100, 100, 150, 150, 0, PI*1.5);
Resulting Display Window

This is a weird one. It measures out in units of Pi, called radians, and the starting point on the ellipse is on the far left edge.
arc(x, y, w, h, start, stop)
origin location x, origin location y,
width, height
start, stop - in radians!

Radians Compared to Degrees

Radians are weird.

PROCESSING

Basic Shapes: Better Arc

size(200, 200);
arc(100, 100, 150, 150, radians(45), radians(270));
Resulting Display Window

Here's a version of arc() using the function radians(N) that will return a value of PI for a given value of N degrees.

There's something peculiar about this too. Can you tell what it is?

Drawing Order

It matters what sequence you write out the code as to how a shape will be displayed relative to another shape. The later in the sequence in the code, the higher in the layering order, or the more on top it will be

PROCESSING

Example 3-9: Controlling Your Drawing Order

size(500, 100);
ellipse(250, 0, 190, 190);
rect(50, 20, 400, 50);
Resulting Display Window

The rect appears in front of the ellipse

PROCESSING

Example 3-10: Put It In Reverse

size(500, 100);
rect(50, 20, 400, 50);
ellipse(250, 0, 190, 190);
Resulting Display Window

The ellipse appears in front of the rect

Shape Properties: Stroke

Stroke Weight

Measured in pixels

PROCESSING

Example 3-11: Set Stroke Weight

size(500,100);
ellipse(50, 50, 80, 80);
strokeWeight(5);
ellipse(150, 50, 80, 80);
strokeWeight(10);
ellipse(250, 50, 80, 80);
strokeWeight(15);
ellipse(350, 50, 80, 80);
strokeWeight(20);
ellipse(450, 50, 80, 80);
Resulting Display Window

Stroke Caps

How the end of a line is drawn

PROCESSING

Example 3-12: Set Stroke Caps

size(500,100);
strokeWeight(20);
line(20, 20, 80, 80);
strokeCap(SQUARE);
line(120, 20, 180, 80);
strokeCap(PROJECT);
line(220, 20, 280, 80);
strokeCap(ROUND);
line(320, 20, 380, 80);
Resulting Display Window

The default is ROUND. The values for strokeCap() must be (in capital letters only): SQUARE, PROJECT, ROUND.

Stroke Joins

How the corner of a rect or quad or arc is drawn

PROCESSING

Example 3-13: Set Stroke Joins

size(500,100);
strokeWeight(20);
rect(20, 20, 60, 60);
strokeJoin(ROUND);
rect(120, 20, 60, 60);
strokeJoin(BEVEL);
rect(220, 20, 60, 60);
strokeJoin(MITER);
rect(320, 20, 60, 60);
Resulting Display Window

The default is MITER. The values for strokeJoin() must be (in capital letters only): ROUND, BEVEL, MITER.

Drawing Modes

Another oddball gizmo for ellipses and arcs. By default, ellipses and arc are positioned by their centers. But you can change them to be drawn from their upper-left corner with ellipseMode(CORNER). The default mode is ellipseMode(CENTER), and there's even a way to do it by both corners (ellipseMode(CORNERS), which sets the upper left and lower right x,y values, rather than the width and height.

PROCESSING

Example 3-14: On the Corner

size(700,100);
rect(10, 10, 80, 80);
ellipse(140, 50, 80, 80);
arc(230, 50, 80, 80, 0, PI*1.5);
ellipseMode(CORNER);
rect(280, 10, 80, 80);
ellipse(280, 10, 80, 80);
rect(370, 10, 80, 80);
arc(370, 10, 80, 80, 0, PI*1.5);
ellipseMode(CORNERS);
rect(460, 10, 80, 80);
ellipse(460, 10, 460+80, 90);
rect(550, 10, 80, 80);
arc(550, 10, 550+80, 90, 0, PI*1.5);
Resulting Display Window

Color

There's several ways of declaring a color, and functions that will take a color value:

background()
fill()
stroke()
color()
- this is a special way of storing a color in a variable, more later...

Colors can be identified in one of two ways: as a gray value from 0 to 255 (28), or as an color value with varying shades of each color value for Red, Green, and Blue (RGB), also measured in values from 0 to 255. (NOTE: There's other ways to control color with colorMode(), but never mind for now. The good news is, if you're used to hexadecimal colors for the web, you can use those too.)

Resulting Display Window Color

PROCESSING

Spec Color: Black

size(200,100);
background(0);
Resulting Display Window Color

PROCESSING

Spec Color: Gray

size(200,100);
background(128);
Resulting Display Window Color

PROCESSING

Spec Color: White

size(200,100);
background(255);
Resulting Display Window Color

PROCESSING

Spec Color: Red

size(200,100);
background(255, 0, 0);
Resulting Display Window Color

PROCESSING

Spec Color: Purple

size(200,100);
background(128, 0, 128);
Resulting Display Window Color

PROCESSING

Spec Color: Orange

size(200,100);
background(#FF8800);

Hexadecimal Color

Hex color is fairly easy once you get used to it, probably a bit easier to work with, and easy to look up on the web and easier to cut and paste.

Hexadecimal numbers are annoted with the digits 0 thru 9, but since it's actually base 16 instead of 10, it uses A, B, C, D, E, and F to represent the numbers 10 thru 15.

Decimal Hexadecimal Decimal Hexadecimal Decimal Hexadecimal
0 0 9 9 32 20
1 1 10 A 33 21
2 2 11 B 72 48
3 3 12 C 108 6C
4 4 13 D 128 80
5 5 14 E 255 FF
6 6 15 F
7 7 16 10
8 8 17 11

In Hex color, there's three sets of hexadecimal values consisting of two characters each. So when we see:

#FFFFFF

We see white because the first set 'FF' tells the Red value of RGB to be full on, the second 'FF' tells Green to be full on, and the third 'FF' tells Blue to be full on

Hex RGB Result
Red Green Blue
#FFFFFF FF
255/255, 100%
FF
255/255, 100%
FF
255/255, 100%
White
#FF0000 FF
255/255, 100%
00
0/255, 0%
00
0/255, 0%
Red
#00FF00 00
0/255, 0%
FF
255/255, 100%
00
0/255, 0%
Green
#0000FF 00
0/255, 0%
00
0/255, 0%
FF
255/255, 100%
Blue
#FFFF00 FF
255/255, 100%
FF
255/255, 100%
00
0/255, 0%
Yellow
#FF8000 FF
255/255, 100%
80
128/255, 50%
00
0/255, 0%
Orange
#EEE5D3 EE
238/255, 93.3%
E5
229/255, 89.8%
D3
211/255, 82.7%
Tan-ish

Fills & Strokes

fill() and stroke() define the obvious fill and stroke of a shape. You can also turn oFF a stroke entirely with noStroke().

PROCESSING

Example 3-16: Control Fill and Stroke

size(400,100);
background(255);
stroke(255, 0, 0);
strokeWeight(10);
fill(0, 255, 0);
rect(20, 20, 60, 60);
ellipse(130, 50, 70, 70);
noStroke();
rect(20+80+80, 20, 60, 60);
ellipse(20+80+80+100, 50, 70, 70);
Resulting Display Window

Good News: There's A Color Selector

If trying to figure out that dark orange is fill(128, 0, 0) is not something that you can easily remember, or that puce is fill(114, 47, 55), then be glad that Processing has a built-in color picker.

Tools menu drop down OSX Color Picker

Setting Transparency

By adding a fourth parameter to a defined RGB color (or a second one to a grayscale color) you can control the transparency of a shape

PROCESSING

Example 3-18: Set Transparency

size(500,100);
background(255);
strokeWeight(20);
stroke(255, 0, 0);
line(0, 50, 500, 50);
stroke(0, 0, 128, 128);
fill(114, 47, 55, 128);
rect(220, 20, 60, 60);
Resulting Display Window

Custom Shapes

There's more shapes that can't be drawn with point(), line(), rect(), quad(), ellipse(), and arc() than can be.

One way to draw a more complex shape (but one without any curves) is to use vertex() combined with beginShape() and endShape(). A vertex() is defined by an x and y coordinate in the Display Window

The best way to plot these out in on graph paper with a pencil. In our book they have an example, let's try it...

PROCESSING

Example 3-19: Draw an Arrow

size(480, 120);
beginShape();
fill(153, 176, 180);
vertex(180, 82);
vertex(207, 36);
vertex(214, 63);
vertex(407, 11);
vertex(412, 30);
vertex(219, 82);
vertex(226, 109);
endShape();
Resulting Display Window

And, Processing has one more trick up its sleeve. If you don't create a shape with beginShape() and endShape() that is closed (that is, the last vertex isn't the same as the first vertex), then you can add a property to endShape(CLOSE) to close the shape.

PROCESSING

Example 3-20: Close the Gap

size(480, 120);
beginShape();
fill(153, 176, 180);
vertex(180, 82);
vertex(207, 36);
vertex(214, 63);
vertex(407, 11);
vertex(412, 30);
vertex(219, 82);
vertex(226, 109);
endShape(CLOSE);
Resulting Display Window

Do you see the pattern of something(ALLCAPS)? The text in ALLCAPS is a called reserved word, or a property that's pre-defined by the Processing language. Things like:

PROCESSING

Example 3-21: Create Some Creatures

size(480, 120);
// Left Creature
fill(153, 176, 180);
beginShape();
vertex(50, 120);
vertex(100, 90);
vertex(110, 60);
vertex(80, 20);
vertex(210, 60);
vertex(160, 80);
vertex(200, 90);
vertex(140, 100);
vertex(130, 120);
endShape();
fill(0);
ellipse(155, 60, 8, 8);

// Right Creature
fill(176, 186, 163);
beginShape();
vertex(370, 120);
vertex(360, 90);
vertex(290, 80);
vertex(340, 70);
vertex(280, 50);
vertex(420, 10);
vertex(390, 50);
vertex(410, 90);
vertex(469, 120);
endShape();
fill(0);
ellipse(345, 50, 10, 10);
Resulting Display Window

Arcs Again

I'm putting this here mostly to call attention to the converter and the diagram

size(200, 200);
arc(100, 100, 150, 150, 0, PI*1.5);

This is a weird one. It measures out in units of Pi, called radians, and the starting point on the ellipse is on the far left edge.
arc(x, y, w, h, start, stop)
origin location x, origin location y,
width, height
start, stop - in radians!

size(200, 200);
arc(100, 100, 150, 150, radians(0), radians(270));

Here's a version of arc() using the function radians(N) that will return a value of PI for a given value of N degrees.

Radians vs Degrees

0 starts at 3:00 o'clock and runs clockwise.

PI is half way around. PI x 2 is full way around. PI x .5 is a quarter way around.

radians(Degrees) returns the correct value in terms of PI for the Degree value, so:

radians(45)  =  PI x .25   =  QUARTER_PI
radians(90)  =  PI x .5  =  HALF_PI
radians(180)  =  PI
radians(270)   =  PI x 1.5  =  PI + HALF_PI
radians(360)  =  PI x 2  =  TWO_PI
radians(30)  =  0.523599 (out of 6.23319)

HINT: To draw an arc going counter-clockwise, use a negative starting value:

size(200,200);
// Left Pacman
arc(100,100,150,150,radians(-90),radians(180));
// Right Pacman
arc(300,100,150,150,radians(45),  radians(315));

Comments

Comments are a really big deal. Get used to commenting your code as you go along. It will save you countless hours of time when you come back to your code months later and wonder "What the hell was I trying to do here?"

Comments basically remove the commented text from being processed by the PDE, but the remain part of the Sketch file so you can keep track of your intentions

Comments are really simple, just put a double forward slash // in front of the comment. Whatever comes after the // will not be processed by the PDE until it reaches the end of the line. So this is a valid comment:

PROCESSING

Commenting with //

// This is a valid comment
size(100, 100); // This is also a valid comment	
// This: size(100, 100); won't get processed because it's inside the comment
// Any comments ends at the end of the line
/* The textbook doesn't cover this yet, but using 
   a forward slash followed by an asterisk starts a block of text 
   that's a comment. Anything written in the sketch will be a
   comment until it's closed with an asterisk followed by
   a double forward slash */
point(50, 50); 

One of the best places to use the multiline comment /* -- */ is at the top of a sketch, and use it to describe what the sketch is supposed to do, who did it, and when it was created.

PROCESSING

Commenting with /* */

/* Sketch to create a new Display Window 
   that's 100 by 100 pixels.
   Created by James Khazar
   August 15, 2017
   Modified by James Khazar
   August 30, 2017 */

size(100, 100);

Another nice feature of the PDE is that you can comment and uncomment text by putting the cursor anywhere in a line and typing Control/Command-/

Processing PDE with selected code

Very handy for de-bugging code

Robot 1: Draw

So here's the first robot from our book:

PROCESSING

Robot 1: Draw

size(720, 480);
smooth();
strokeWeight(2);
background(0, 153, 204);     // Blue background
ellipseMode(RADIUS);

// Neck
stroke(255);                 // Set stroke to white
line(266, 257, 266, 162);    // Left
line(276, 257, 276, 162);    // Middle
line(286, 257, 286, 162);    // Right

// Antennae
line(276, 155, 246, 112);    // Small
line(276, 155, 306, 56);     // Tall
line(276, 155, 342, 170);    // Medium

// Body
noStroke();                  // Disable stroke
fill(255, 204, 0);           // Set fill to orange
ellipse(264, 377, 33, 33);   // Antigravity orb
fill(0);                     // Set fill to black
rect(219, 257, 90, 120);     // Main body
fill(255, 204, 0);           // Set fill to yellow
rect(219, 274, 90, 6);       // Gray stripe

// Head
fill(0);                     // Set fill to black
ellipse(276, 155, 45, 45);   // Head
fill(255);                   // Set fill to white
ellipse(288, 150, 14, 14);   // Large eye
fill(0);                     // Set fill to black
ellipse(288, 150, 3, 3);     // Pupil
fill(153, 204, 255);         // Set fill to light blue
ellipse(263, 148, 5, 5);     // Small eye 1
ellipse(296, 130, 4, 4);     // Small eye 2
ellipse(305, 162, 3, 3);     // Small eye 3
Robot 1 Completed
Previous Chapter
Next Chapter