|
Chapter: Visual
Representations
of Code
Drawing Irregular Shapes
Fortunately we are not limited to drawing only 2D primitives in
Processing, but we can in fact draw any 2D shape that we can imagine.
In order to draw irregular or non-primitive 2D shapes we use two main
functions, beginShape() and endShape() issued in that particular order,
in conjunction with several calls to another function called vertex().
We're going to start off by experimenting with this feature by drawing
a speech bubble surrounding the “Hello World” text in our sketch.
The beginShape() function tells Processing to start recording the
following set of points that are about to be issued until the
endShape() function tells Processing to stop recording. Between these
two functions we are going to supply Processing with a set of special X
and Y coordinates that will be parameters in a call to the
vertex() function. The vertex() function accepts parameters in various
formats of which we are most interested in the X and Y parameter
format, which will be used to determine where (in terms of X and Y) the
point (or vertex) to which the function is referring to will be placed.
By adding the following statements in the particular order listed below
we will be able to draw a speech bubble:
beginShape();
//Start the shape in the middle of the Display Window's x axis
vertex(width/2, (height/4)*3-35);
vertex(width/2-70, (height/4)*3-35);
vertex(width/2-80, (height/4)*3-25);
vertex(width/2-80, (height/4)*3+5);
vertex(width/2-70, (height/4)*3+15);
//The following statement marks the point where the shape
//starts to mirror itself
vertex(width/2, (height/4)*3+15);
//Notice how the X parameters are mirrored from this point, The Y
//parameters do not change from their mirrored counterparts
vertex(width/2+70, (height/4)*3+15);
vertex(width/2+80, (height/4)*3+5);
vertex(width/2+80, (height/4)*3-25);
vertex(width/2+70, (height/4)*3-35);
//this is the arrowhead that points out of the
//speech bubble towards the smiley face
vertex(width/2 + 50, (height/4)*3-35);
vertex(width/2 + 40, (height/4)*3-55);
vertex(width/2 + 30, (height/4)*3-35);
//the end of the shape is the same as
//the beginning
vertex(width/2, (height/4)*3-35);
endShape();
Although at first this might appear to be a little confusing and a lot
of typing, upon closer inspection you may notice that it is in fact
repetitious and more of copy, paste and modify effort. So lets have a
look at what's going on here.
Each vertex
position can be mapped to a vertex() in the code.
In the above illustration we can see that beginShape() has started
recording the various points that make up the irregular shape of the
speech bubble, which we subsequently define for the beginShape() and
endShape() functions one vertex at a time. The first vertex is located
along the center of the Display Window's X axis followed by the Y
parameter for this vertex which is 35 pixels above the center of the
text that says “Hello World”. Of course we could just as easily have
typed in the values explicitly such as:
vertex(320, 325);
But using this method of explicit programming does not leave much room
for changes and could subsequently lead to the extremely time consuming
task of changing each explicitly determined point in your program
manually, if it is deemed that such a change is necessary at a later
stage.
From the next vertex on we can use the Display Window's width and
height system variables and the text's X and Y position as a starting
point from which we can place every vertex that follows relative to the
position of the previous vertex and in relation to the other elements
making up the program.
Using this method of implicit programming also makes it easier for us
to “mirror” the coordinates of the irregularly shaped speech bubble
across the center of it's own Y axis. As you will notice once we get to
the vertex marked as “the point where the shape starts to mirror
itself” it's just a simple question of copying and pasting the previous
code excluding the first vertex statement, changing the negative values
associated with the vertices' X parameters to positive values, and
reversing the order of the statements in a mirrored fashion.
Using an implicit style of programming can also make patterns in your
code easier to identify.
This can save quite a bit of time as it is not necessary to work out
the specific coordinate of each vertex individually all we need to know
is half of the coordinates that make up the shape and since we are
mirroring the shape on the X axis we simply change the negative values
associated with X to positive values. Once we have all the vertices
mirrored on the right hand side (excluding the last vertex) we can then
start to plot the points of the arrow head of the speech bubble that
points to the smiley face implying that it's saying “Hello World”.
This part of the shape is pretty straight forward because we already
know that we will need three points to make the triangular shape of the
arrowhead and we already know the Y positions of two of these points
because they will be at the same height of the first and last vertices
of the speech bubble. So it's just a case of simple trail and error to
determine what looks best in adding the remaining parameters to the
next three vertex() functions. Once that's complete we can close the
shape by placing the last vertex at the same location of the first
vertex.
Finally to end the shape you must use the endShape() function.
You might have noticed that the image on page 75 has a speech bubble
with a thick blue outline around it. This is due to the strokeWeight()
function, and it controls how thick or thin a stroke is rendered. It
accepts a number as a parameter, I don't recommend setting this number
too high as you might find it causing undesirable effects on your
sketch. The higher the number the thicker the stroke. Add the following
statement before the statements that draw the speech bubble:
strokeWeight(8);
You might remember that in order to have a black outline around the
face's eyes the stroke() function had to be set to an RGB value of
0,0,0 (or black), so although the strokeWeight() function has done it's
job by increasing the thickness of the stroke surrounding the speech
bubble, the effects of it might not be so obvious. Changing the stroke
and fill colors are functions that you might need to run several times
within a single sketch to achieve the desired result which is precisely
what we are about to do. Add the following statement before the
previous statement:
stroke(50,127,255);
This changes the stroke color for the speech bubble to a little bit of
red, about 50 percent green and full blue. In order to change the fill
color of the speech bubble to white you must add the fill()
function before the drawing of the speech bubble. A statement to
determine the speech bubble's fill color as white would look like
either one of the following two fill statements:
fill(255,255,255);
//or
fill(255);
Either option is perfectly acceptable, the latter is used for
determining a greyscale value from 0 (which is black) to 255 (which is
white). When dealing with greyscale values, including black and white,
the latter is the more widely adopted method as only one parameter is
needed as opposed to three parameters used to determine RGB color
values.
The Stroke
Caps are over lapping on the first and last vertex of the speech bubble
in the current version of the Sketch.
The section of the speech bubble where the first and last vertices of
the shape overlap has a slight blemish caused by the default stroke
caps setting. Stroke Caps determine how the end of a stroke is drawn
for example is it round or flat, and they become most evident when
dealing with heavily weighted strokes such as the stroke surrounding
the speech bubble. Fortunately we have a function in Processing for
controlling how stroke caps are drawn, as you might have guessed the
function is called strokeCap() and it accepts the parameters ROUND,
SQUARE or PROJECT.
Different types of stroke caps in Processing, which are very similar in
effect to that of a vector illustration package.
Remember that Processing is case sensitive so you must type the
parameter's name with the correct casing. ROUND is the default
parameter that causes strokes in Processing to have a beveled end,
SQUARE will end the stroke with a flat end and PROJECT will tend to
render the end of the stroke slightly past it's destined coordinates,
like ROUND but with a flat end. We are going to use SQUARE to fix the
speech bubble. Add the following statement after the strokeWeight()
function call:
strokeCap(SQUARE);
|
|