© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
J. MeyerProgramming 101https://doi.org/10.1007/978-1-4842-8194-9_1

1. Basics

Jeanine Meyer1  
(1)
Mt Kisco, NY, USA
 

Abstract

The goal of this chapter is to get you started. The programming example will be a static drawing of two cartoonish figures, as shown in Figure 1-1. Be aware that the examples in subsequent chapters will increase in complexity, as we will be producing programs that are highly interactive and, possibly, involving random effects, reading files, and exhibiting behavior based on various conditions.

A sketch diagram of the daddy logo page has two logos. One is skinny with two dark dots as eyes, a small curve at the bottom as lips, and a hair layer on the top. The other one is fat with two dark dots as eyes, a small curve at the bottom as lips, and a hair layer on the top.

Figure 1-1

Fat and skinny Daddy logos

The Daddy logo is a version of a drawing my father would make, often as his signature on a letter or note or artwork. I hope that you will design or recall a drawing or symbol that has meaning to you and makes you happy the same way this cartoonish peanut-shaped, bald guy makes me.

We will need to do some work to start us off and get to the point that the coding is clear, but it is not too difficult. The traditional first task in using any programming language is to get the program to display the phrase “Hello, world.” This works well in demonstrating several important concepts, including what happens if the programmer makes certain types of errors. Because of the features built into Processing, you can produce a pretty fancy version of “Hello, world.”

Be patient with me and with yourself. At the end of the chapter, you will be able to implement your own Daddy logo.

Programming Concepts

This section, included in each chapter, is to provide a general introduction to concepts. I begin with comparing and contrasting programming languages with natural languages.

Programming Languages and Natural Languages

Programming languages have some similarities with natural languages, but they also have significant differences. Programming languages are defined by rules just as a natural language’s grammar defines what is proper English, Spanish, or other language. A program contains statements of different types just as we find in English (or Spanish, etc.), and there also are ways to construct compound statements. Statements in programming languages contain terms and expressions involving terms. In programming languages, programmers often come up with our own names for things. The names must follow certain rules, but these are not unduly restrictive. This is a difference from natural languages, in which we mainly use the official words of the language, whereas in programming, we are extending the language all the time.

A more significant difference between programming languages and natural languages is that the rules must be obeyed at all times when using programming languages! Consider that we all frequently utter grammatically incorrect statements when we speak and yet generally are understood. This is not the situation in programming. The good news in the case of Processing, and certain other languages, is that the Processing system generally indicates where an error occurs. The development environments for Processing and other computer languages are themselves computer programs, and they do not exhibit any impatience while we fix errors and try the program again. I will give some examples of statements, right after I introduce the concept of values and variables.

Values and Variables

Programming involves containers or buckets where we can store specific types of things (values). These kinds (types) of things are called data types. The following are some examples of data:
Int           integer (e.g., 10)
float         decimal value (e.g., 5.3)
Boolean       logical values (e.g., true/false)
Char          single character (e.g., 'a')
String        a string of characters (e.g., "hello world")

String should start with a capitalized “S”. The B in Boolean can be upper or lowercase. The data type is named for George Boole, an English mathematician credited with originating symbolic algebra.

Our programs can include literal values such as 5, 100.345, and “Hello” in the code. In addition, a feature in all programming languages is what is termed variables. A variable is a construct for associating a name of our choosing with a value. We can initialize the variable, change it, and use it in an expression; that is, the value associated, often termed in the variable, can vary, that is, change. Using variables makes our programs less mysterious. Moreover, we can define one variable in terms of another, making relationships explicit and preventing certain errors. In Processing, Java, and some, but not all, programming languages, variables need to be declared, or set up before use. One characteristic of variables is termed scope, which indicates what code has access (e.g., global variables vs. local variables), but that is best explained later.

The following are examples of Processing statements. Explanation is given in comments and later.
int classSize; // this declares, that is, sets up classSize to
                // be a variable.
classSize = 21; //assigns the value 21 to the variable classSize.
classSize = classSize + 5; //takes whatever is the current value held in
               // the variable classSize
               // and adds 5 to it and resets classSize to the new value
float score = 0; //declares the variable score AND
                 // assigns it a value. This is called initialization.
if (score == 0) {
      text("You did not score anything.", 100,100);
      text("Try again.", 100,300);
}

The // indicates that the rest of the line is a comment, meaning that Processing ignores it. It is intended for readers of the code, including you, to make things clear. You also can use the delimiters /* and */ for long comments.

Note

My examples, because they are surrounded by explanations, tend not to have as many comments as I would use outside of teaching and writing books.

There are rules for variable and function names in all programming languages. Generally, they must start with a letter, uppercase or lowercase, and cannot contain spaces. The most important guidance for naming is that the names should have meaning for you. The programming language will accept single character names or names with no apparent meaning, but these will not be helpful when you are trying to recall what you were trying to do. So-called camel casing, as in classSize, can be helpful.

A single equal sign (=) means assignment and is used in what are called, naturally enough, assignment statements and initialization statements. The statement
classSize = classSize + 5;
will seem less illogical if you read it as
classSize is assigned or gets the total of the current value of classSize plus 5.

A double equal sign (==) is a comparison operator and often appears in an if statement. Think of it as like < or <=.

The if statement is an example of a compound statement. The expression score == 0 is interpreted as a comparison. If the value of the variable score is equal to zero, then the statement within the brackets is executed. If the value of score is greater than zero or less than zero, nothing happens. Again, you will see many more statements in the context of examples.

Functions

Programming work in any language is structured into units. One important way of structuring code comes with different names: function, procedure, subroutine, method. These are ways of packaging one or more statements into one unit. You will read about functions in the “Processing Programming Features” section and methods in the “Under the Covers” section. Briefly, functions are defined, and functions are invoked. I can give you directions , perhaps orally, perhaps by text, to my house, which is analogous to defining a function. At that point, I am not directing you to come to my house. At some later time, I can direct you to go to my house, and this is analogous to invoking the function.

Programs can be considerably shorter as well as easier to modify through the use of functions and variables, so understanding both of these concepts is important. You do not need to accept this or understand this right now. It will be demonstrated later by my sketch for displaying two Daddy logos that takes just one statement more than displaying the Daddy logo just once.

Specifying Positions and Angles

Displaying drawings and images and text on the screen requires a coordinate system. The coordinate system used by most computer languages and many graphical tools is similar to what we learned (but might or might not remember) from high school geometry, with one big difference. Horizontal positions, sometimes called x positions, are specified starting from the left. Vertical positions, sometimes called y, are specified starting from the top of the screen. Figure 1-2 shows the coordinate system with a small circle at the 100, 200 location.

An illustration of the rectangular box has the x-axis and y-axis coordinate system. It has two coordinate points. They are 0 comma 0 which represents the value of x and y is 0. The points 100 comma 200 which represent the value of x is 100 and y is 200.

Figure 1-2

Coordinate system

If you say to yourself “This is upside down,” then I know you understood. Another important point is that the unit is very small, so if your code positions something at 100, 200 and later at 101, 201, you probably will not detect the difference. Your intuition regarding this will improve with experience.

Note

As a teaser, Processing has facilities for 3D as well as 2D. We get to 3D in later chapters.

In this chapter, my Daddy logo has a smile made by specifying an arc of an ellipse. To produce the arc, I need to write code to indicate a starting angle and an ending angle of the arc. The system used in most computer languages is not the standard one in which a right angle is 90 degrees, a U-turn is a 180, and snowboarders do 1800s. (I am writing this during the Olympics, and yes, snowboarders did tricks measuring 1800 and bigger.) It might be upsetting to realize this, but the notion of degrees with a circle consisting of 360 degrees was invented by people. I typically offer my students extra credit to identify where and when this happened. Instead, in most programming languages, we use a measure called radians. Think of wrapping a circle with lengths equal to one radius. How many lengths will this take? You know the answer: It is not a whole number, it is 2 times π, where π is an irrational number often approximated by 3.14159. In our programming, we will use the built-in values TWO_PI, PI, HALF_PI, and QUARTER_PI. You will see radians in use, so be patient.

Colors

There are different ways to specify colors in computer languages and computer applications, and Processing supports more than one. In this text, we stick with grayscale and RGB (red/green/blue). Because of how these values are stored, the range of grayscale is from 0 (black) to 255 (white), and the values for redness, greenness, and blueness are specified by a number from 0 to 255. This approach is used in many applications. If you want to use a certain color that you see in a photo, you can open the image file in Adobe Photoshop or the online Pixlr or some other graphics tool and use the eye drop on the pixel (picture element) you want, and an information window will tell you the RGB value. See also the mention of the Color Selector in the “Things to Look Up” section.

Development Environment

Programmers need to prepare programs and test programs. We also need to save our work to come back to it another time. We might need to send the program to someone else. Processing has what is termed an integrated development environment, the Processing Development Environment (PDE), which provides a way to prepare and make changes to a program as well as test it and save it. To give you a different example, Hypertext Markup Language (HTML) documents containing JavaScript are prepared and saved using a text editor, such as Sublime. The resulting files are opened (and run) using a browser, such as Chrome. In the Appendix, I will show you how to use an editor for p5.js, which is a version of JavaScript incorporating Processing features.

Role of Planning

I close this first “Programming Concepts” section by noting that preparing programs such as a Processing sketch generally involves planning and design. It might be best to step away from the keyboard. Some of the plans might need to be modified when you get to writing the code, but it is best to have plans!

Under the Covers

As I indicated earlier, Processing is a language built on Java. This means that the Processing code you write is Java code that the development environment puts into a larger Java program prepared for handling Processing sketches. In Java, there are no functions, but, instead, what are termed methods. I will introduce methods for our use in Processing in Chapter 4.

The PDE (Processing Development Environment) makes use of libraries, collections of methods holding the built-in functions of Processing, such as functions to draw a rectangle.

In the big Java program, there are calls to functions that we write, or, to put it more accurately, we code the body of the function. For example, all Processing sketches contain a function called setup, the purpose of which is to do what the name implies. It nearly always includes a statement that defines the width and height of the window, for example. The big Java program invokes the setup program once at the start of the sketch. Similarly, we can write the body of a function named draw. The Java program invokes this function over and over, the frequency defined by the frame rate, which can be reset by assigning a value to the built-in variable frameRate. This enables us to build applications producing animations and responding to events such as a user clicking the mouse button. There are many other functions for which we, the programmers, specify the response to an event, for example, keyPressed or mouseClick.

The Java program also defines default settings. Processing and other computer languages and many computer applications provide powerful features. If we needed to specify each aspect of each feature before anything happens, it would be tremendously burdensome. It is important to be aware that certain things can be adjusted, though, as you will see in our very first example later, with the discussion on default values for font, text size, fill color, and stroke color.

The design and capabilities of Processing provide us a way to get started creating and implementing our ideas quickly.

Processing Programming Features

In this section, I explain the concepts focusing on Processing features. There will be small coding examples to prepare for the larger (although not too large) examples covered later in the chapter.

To use Processing, you need to go to the processing.org website and follow the directions to download and install Processing on your computer.

Processing Development Environment

To describe the PDE in abstract terms is too difficult, so let’s get started. Once you have downloaded and installed Processing, open it. At the top of the PDE window, you will see the Processing File toolbar.

Click File, which will open a drop-down menu. Select New. The toolbar will change to hold more options. A window that looks like Figure 1-3 will appear on your screen. The number after sketch_ will be different than what you see here. I believe in saving early, and often so, at this point, you can think about where you want to save your Processing work in terms of the file system on your computer. I leave that to you. You also should give some thought to what you will name each sketch. I suggest the name first0 for this one. Click File, then select Save As…, and proceed with a file name and a location in the usual way for your operating system.

An illustration of the sketch underscore 171129a, processing 3.3.5 window has the tab sketch underscore 1711291 page. Here, the Java code has to be entered on the right side of the page has the number series starting from 1. At the bottom of the page has Console and Errors tab.

Figure 1-3

Window for new sketch

Using Save As… in the PDE produces a folder, in this case named first0, which contains a file named first0.pde. The examples explored in future chapters will consist of folders containing additional items. For example, a Processing sketch named myFamily that makes use of an image file aviva.jpg and an image file daniel.jpg will be a folder named myFamily containing a file named myFamily.pde and a folder named data that contains the two files aviva.jpg and daniel.jpg. The relationship of these files is shown in Figure 1-4.

A structure of myFamily is a folder and it has myFamily dot pde file and data folder. The data folder has two images which are aviva dot jpg and daniel dot jpg.

Figure 1-4

Typical file structure for a sketch

Functions

Processing uses the term function for grouping together one or more statements into something that can be invoked (called). Functions are defined with header statements and then the body, a sequence of statements, contained within brackets. You will see in this chapter and every chapter definitions for the setup function, a function that Processing expects the programmer to supply. The header is
void setup()

The term void indicates that this function does not produce or return a value. The opening and closing parentheses with nothing between them indicate that this function does not expect any parameters.

The Daddy logo example includes a function called daddy that does the work of drawing the cartoon. Its header is
void daddy(int x, int y, int w, int h)

The parameters are the things between the parentheses. The parameter list is the place for the programmer to give names and specify the data type. This means that when I wrote the code to invoke daddy, which is necessary because daddy was something I made up, not anything Processing expects, Processing will check that the values cited in the call are the correct type.

I feel obliged to show you an example of a function that does produce a value, a standard one supplied in many textbooks.
float calculateTax (float bill, float rate) {
     return (bill*rate);
}

The header indicates that this function calculates a floating-point value, sometimes called a decimal number. The code includes what is termed an expression: bill*rate. The asterisk indicates multiplication.

Because it generates a value, a call of this function can be used in an expression. With this function defined, I could write an expression (part of a statement) with something like this:
Total = 150.53 + calculateTax(150.53, .07);

Processing will assign the 150.53 to the parameter bill and the .07 to the parameter rate, perform the multiplication bill * rate, which in this case is 150.53 * .07, and return the result so it is available to be added to 150.53. The variable Total will be set to 161.0671.

I hope the names of these variables are suggestive. My examples are more complex and more interesting and, because context is given, more understandable, in later chapters.

Angles

Processing provides us built-in variables—PI, TWO_PI, HALF_PI, and QUARTER_PI—to use when requiring specification of angles. These names are case-sensitive. Figure 1-5 shows the designation of some angles.

A schematic diagram of a circle has some angles which are represented as P I, a negative value of 0.75 multiples P I, a negative value of quarter P I, 0 or 2 multiples P I, P I over 3, and 0.90 multiples P I. The above angle values are mentioned in a clockwise direction.

Figure 1-5

Diagram showing some angles in radians

In Processing, angles start at 0 and move clockwise around the circle as the number increases. Notice the location of PI/3. However, you can designate a negative angle. The angle labeled –PI/4 could also be specified as PI+.75PI or 1.75*PI.

Processing provides a function named radians for converting from the degree system to radian measure. So radians(90) will produce a floating-point number very close to PI/2, and radians(180) will produce a floating-point number very close to PI. We can go back and forth between degrees and radians, but I suggest building up your intuition in radians. One way to do that is to examine my code and change the smile. You get immediate feedback and can try again.

Implementing Hello, World

In Processing, we need to write a function named setup. Here is the code for my first try at a Hello, World program.
// a Hello, world program
void setup() {
    size(900,600);
    text("Hello, world",100,200);
}

It is not necessary, but it is good practice to put a comment at the start, as I did here. The // indicates a comment, which is ignored by Processing.

The first line of actual code is the header line of a function, which has several elements. The term setup gives a name to the function. As I indicated earlier, we define a setup function to get our sketch started. The parentheses, (), after the name indicate that there are no parameters to this function. Parameters are extra information passed to the function, and you will see examples of parameters in the Daddy logo example. The brackets, the opening { on the first line and the closing } on the last line, mark off the body, or contents, of the function. People follow different conventions for the location of the brackets. They do not have to be where they are but can instead be what you see here:
void setup()
     {size(900,600);
     text("Hello, world",100,200);}

My general advice is to not be skimpy about line breaks or blank lines. I also need to tell you that indentation is not required and is not interpreted by Processing, but I advise you to use indentation for functions and for compound statements such as the if and for loop constructs we see later because it will make your code easier for you to understand. There are Auto Format under edit and a keyboard shortcut (Command+T) for automatic indentation.

The first statement within the body of the function specifies the size of the display window. The width is set at 900 and the height at 600. When you run or execute the program, you will see what these settings produce.

The second and last statement within the body of the function does the work of displaying the string “Hello, world” at the position 100 pixel units from the left side of the display window and 200 pixel units from the top.

You should save the program, which you do by clicking File and then selecting Save. Select Save rather than Save As… to save the file in the same place as you indicated in the first Save As… command. Of course, you could wait to rename the program and then use Save As…, but my motto is to save early and often.

The next step is to try the program by running it. Do this by clicking on the play (triangle/arrow) button in the upper left of the screen shown in Figure 1-6.

A code of the first0 page has a file name is a Hello, world program, void setup left parenthesis right parenthesis left brace dot size left parenthesis 900 commas 600 right parenthesis semicolon dot text left parenthesis left double quotation Hello commas world right double quotation commas 100 commas 200 right parenthesis semicolon dot right brace

Figure 1-6

The first sketch

The result will be disappointing, but it is educational. You should see what is shown in Figure 1-7, namely, the phrase “Hello, world” in tiny, white letters.

An illustration of the first 0 window has the text of Hello commas world. The font size of the text is small.

Figure 1-7

Result of running first0

Now, perhaps you do not see anything. Perhaps the program did not even start. This could happen if you made any syntactic mistakes, or mistakes of form. To put it in practical terms, Processing can detect syntactic errors but cannot correct them. Examine Figure 1-8. I made a mistake, omitting a comma between the 100 and the 200. The Processing program shows that there is a problem in the statement indicating the call to the function text. The message, called an error message, does not say what I know happened: it does not say anything about a missing comma. It does say that the function text() expects three parameters. Error messages might not tell you everything, but they generally are helpful. One of the most common syntactic mistakes is a problem with brackets or parentheses. Processing can detect when there are too many or too few but does not indicate exactly where the problem is.

A code of the first 0 page has a Hello, world program, void setup left parenthesis right parenthesis left brace dot size left parenthesis 900 commas 600 right parenthesis semicolon dot text left parenthesis left double quotation Hello commas world right double quotation commas 100200 right parenthesis semicolon dot right brace.

Figure 1-8

Example of a syntactic mistake and error message

In addition to syntactic mistakes, we could make semantic mistakes, mistakes of meaning or faulty logic. If you or I had written “Hellowold,” the rules of Processing would accept it, but it might not be what we intended. Similarly, if we intended to draw a red circle and instead drew a blue one or if we produced a drawing with the left eye not on the face, that would be a semantic mistake. Processing does not help us notice or fix these. We are on our own.

You can say that the program shown in Figure 1-6 and producing the result shown in Figure 1-7 represents a semantic error. I will say it was a success—the desired message was displayed—but we can do better. Remember my mention of default values? The call to the text function makes use of the current settings for text size, text font, text color, and text alignment. I will show you an improvement. To encourage good habits, go to the File menu, select Save As…, and save with a new name, first1. The improved sketch will change the text size and the color. I leave font and alignment to you.

The Processing function fill() sets the color of a shape or the color of text, and the function stroke() sets the color of the outline of a shape. If we use just one number, the color is grayscale, or black to white. The value should be a number from 0 to 255, where 0 is black and 255 is white. If we use three numbers, the numbers specify the amounts of redness, greenness, and blueness. As with positions and angles, you will gain intuition on this as you use it.

Here is the complete code for the improved sketch; notice that two statements have been added to the original sketch, and I also changed the comment at the start.
// improved Hello, world program, setting size and color
void setup() {
     size(900,600);
     textSize(30); //bigger than default
     fill(250,0,250); //changed color for text
     text("Hello, world",100,200);
}
The call to the function textSize sets the new size. The call to the fill function sets the color. Save the sketch and then run this program; it will produce what is shown in Figure 1-9.

An illustration of the first 1 window has the text of Hello commas world. The font size of the text is medium and the text is in color.

Figure 1-9

Result of first1, the improved sketch

Because Processing facilitates much more than displaying text, I describe one more program here. Click File, select Save As…, and save this file with the name first2. Now modify the program with the addition of one more statement. I provide the whole sketch, but it is just the line with the call to the ellipse function that is to be added. The ellipse is centered at 180, 200. Its width is 300, and its height is 200. Ellipses can be specified in different ways depending on the setting of a variable named ellipseMode. You can look this up to see the possibilities.
// a Hello, world inside of ellipse
void setup() {
    size(900,600);
    ellipse(180,200,300,200);//I fiddled with these values
    textSize(30); //bigger than the default
    fill(250,0,250); //changed color for text
    text("Hello, world",100,200);
}
Do take my comment “I fiddled” seriously; that is, I tried a few things until the result was what I wanted. Save and run the program. You should see what is displayed in Figure 1-10.

An illustration of the first 2 windows has the text of Hello commas world. The font size of the text is medium and the text is in color. Here, the text has an oval borderline.

Figure 1-10

Hello, world inside an ellipse

Why is the ellipse white with a black border? The answer is that the default value for fill is 255, producing white, and the default for stroke is 0, producing black. I strongly urge you to put the book down (or close the window on whatever application you are reading the e-book version) and do some experiments. Put a call to the fill function and a call to the stroke function before the ellipse command. Change “Hello, world” to something else. Draw a circle instead of an ellipse. Try stuff!

This activity with Hello, world examples introduced the basics, but not every feature required for the Daddy logo project. Here is a list of what additional Processing constructs will be used, with short explanations.
  • Declaration of variables, including initialization. An example of this is

int skinnyFaceWidth = 60;
This sets skinnyFaceWidth as a variable of data type int and an initial value of 60. I say initial value, but in fact, this variable and many of the others do not change: they are not assigned different values.
  • The color data type and the color function: This is an unusual but acceptable situation of one name being used for two distinct things. In Processing, color is a data type similar to int or float. The color function is used to produce a value of data type color. The following code could appear:

color skinTone = color(255,224,189);
I advise you to not use the same name for different things even if they are related.
  • The ellipseMode function: Processing provides different ways to specify an ellipse. For example, a programmer can specify the center or the upper left corner. I use it here to introduce the idea. A call to

ellipseMode(CENTER);
means that the parameters specify the center of the ellipse. In different situations, you might find one way more natural than the other.
  • Expressions, making use of arithmetic operators: You will read later in the “Planning” section how my code defines certain variables in terms of other variables. For example, the center of the arc that is the mouth is set to be a certain distance, namely, one tenth of the height, further down the screen than the center of the ellipse that is the lower part of the peanut shape. My code converts (the technical term cast is used) the results to be rounded to an integer.

int mouthYoffset = int(.10*h);
  • Definition of a programmer-defined function, daddy, with parameters: Defining what are called programmer-defined functions is the main lesson of this chapter. The function I define is called daddy, and its parameters are used to specify the position and the dimensions of the Daddy figure.

  • Definition of the draw function and turning off the invocation of draw: In the Daddy logo example, the draw function calls the daddy function two times (wait for the next section). Normally, the draw function gets invoked over and over. How often draw is invoked is called the frame rate, and you can change this. It would not do any harm to repeat this, but I decided to show how to turn it off through the use of noLoop().

These all are best explained in the context of use, so be patient to read what follows.

Implementing the Daddy Logo

With the introduction using the Hello, world examples, and hoping you have done some noodling around in Processing on your own, I move on to the Daddy logo. I describe my thought process when planning the sketch and then explain declaration of variables, the use of expressions, color data type and color function, the draw function, and programmer-defined functions.

Planning

My approach to producing the peanut shape is to draw two ellipses, one slightly on top of the other, with no borders. Borders are turned off by a call to the function noStroke(). The drawing of borders is turned back on by a call to stroke with the desired color. I won’t quite call this a hack, but it is a trick. To make the mouth, I used the noFill() function because I just wanted the outline.

My plan is to define a function called daddy with parameters indicating the position of the Daddy logo cartoon and the width and height of the peanut-shaped figure. The two ellipses, eyes, mouth, and hair will each be placed using horizontal and vertical values derived from the parameters. I also will make use of global variables. I could have achieved the same effects by putting a lot of code inside the setup function because this is just a static drawing. However, I am using a function as well as defining the contents of draw and making use of variables to model good practices. This approach does require me to work out the relative position of the two ellipses (the upper and lower parts of the face) and the relative positions of each of the circles representing eyes, the arc that represents the mouth, and the two arcs that represent the one hair on the top of the head.

Doing this work, figuring out these relationships, allows me (through my code) to produce a Daddy or peanut shape at different horizontal and vertical positions and different widths and heights.

I define a programmer-defined function called daddy. The header line is
void daddy(int x, int y, int w, int h)
This defines daddy as a function expecting four parameters, each integer (whole numbers), with the names x, y, w, and h. You could think of parameters as additional information sent with the invocation of the function. Normally, I would choose longer names but decided that these were clear enough, standing for the horizontal position, the vertical position, the width, and the height. The parameters will each be referenced in the body of the function. Their values will be the values set by a call to the function. The function is called twice, both in the draw function:
daddy(ctrx,ctry,faceWidth, faceHeight);
daddy(3*ctrx, 2*ctry,skinnyFaceWidth, skinnyFaceHeight);

This is a chicken-and-egg situation. I haven’t told you what is inside my daddy function. All I can say now is that the first call of daddy will set the x appearing inside the function to the value of ctrx, the value of y appearing inside the function to the value of ctry, and so on for w and h. The ctrx and ctry are variables that I have named. They will be the horizontal coordinate and the vertical coordinate of the center of one of the two circles used in the Daddy cartoon.

The variables cited in these two lines are global variables, to be explained soon. Just from looking at these two statements, assuming that skinnyFaceWidth and skinnyFaceHeight are appropriately named, we can make a safe guess that the skinny Daddy figure is three times as far from the left and twice as far down the screen, and that is indeed what appears in Figure 1-1.

Execution of code starts with the setup function. The draw function is invoked next. In this particular case, the first statement in the draw function is executed, which means control goes to the daddy function. All the statements in the daddy function are executed with the parameters referenced in the call in the first statement. Then control returns to draw, and the second statement is executed. This means control goes again to the daddy function with all the statements executed with the new set of parameters. Control returns to draw, and the last statement is executed. As you see here, this last statement is noLoop();. The effect of this is to stop looping; that is, stop any further invocation of draw.

Note

I could have left off turning off looping and you would not have noticed. Processing would have drawn the two cartoons over and over in the same place.

Global variables are declared outside of functions, whereas local variables are declared inside of functions. Global variables are used inside of functions and persist, or stay around when a function completes. In contrast, local variables go away when the function completes. The benefits of local variables and the more elaborate scoping rules of many computer languages and many other features apply more in big, or at least bigger, programming projects involving more than one person than they do in teaching examples. Still, it is a good practice to think about what values you want to persist and what values are only used within a function.

Some of the expressions defining variables in terms of other variables produce floating-point numbers, which are then cast to integers. (I could have made everything integers but decided to do it this way mainly to show you casting.) The critical thing is that all the settings for the eyes and the mouth and the lower and upper ellipses that produce the peanut shape are defined in terms of x, y, w, and h. For example, inside the daddy function, there is the declaration with initialization of a local variable that will be used for the horizontal positioning of the eyes.
int eyeXoffset = int((15.0/80.0)*w);

This statement sets up eyeXoffset as a variable of data type int and initializes it to be a fraction of the value of w, which is the width of the upper ellipse. This value is rounded off to be an integer. How did I arrive at the fraction 15.0/80.0? Experimentation. Why don’t I write it 15/80? Because division of integers always rounds down to the largest integer not larger than the value. This means 15/80 produces 0, whereas 15.0/80.0 produces 0.1875. So although my code casts to integer when the calculation is over, I do not want the intermediate value to be an integer.

By the way, there are two eyes, but only one variable with the name eyeXoffset. If you examine the code, you will notice that in one place, the expression uses addition for eyeXoffset and in another, the expression indicates subtraction.

One last step in planning is to produce a function table. Table 1-1 shows the functions for the Daddy logo sketch.
Table 1-1

Daddy Logo Functions

Function name

Invoked by

Invokes

setup

Underlying Java program

 

draw

Underlying Java program

daddy

(two places)

daddy

draw

 

Daddy Logo Program

My daddyLogo sketch starts with comments.
// This produces a peanut-like shape that was a self-portrait by my father
// he sometimes used it as a signature.
// daddy using variables and function
// this version draws two different faces
Creating comments such as these at the start is a good practice. You also should put comments throughout the code. This is a case of “Do as I say, not as I do,” as I omit comments in the code because I produce Table 1-2 with an explanation of each statement.
Table 1-2

Code for Daddy Logo Sketch

int ctrx = 100;

Horizontal location for first face

int ctry = 160;

Vertical location

int faceWidth = 80;

Width of the lower part of first face

int faceHeight = 100;

Height of both parts of first face

int skinnyFaceWidth = 60;

Width of second face

int skinnyFaceHeight = 130;

Height of second face

int eyeSize = 10;

Eye size for both faces

color skinTone = color(255,224,189);

Color of faces

void setup()

Header for required setup function

{

Opens setup function

size(800,600);

Specifies size of window

}

Closes setup function

void draw()

Header for draw

{

Opens draw function body

daddy(ctrx,ctry,faceWidth, faceHeight);

Calls daddy function to make first face

daddy(3*ctrx, 2*ctry,skinnyFaceWidth,

skinnyFaceHeight );

Calls daddy function to make second face

noLoop();

Turns off looping: no more draw

}

Closes draw function

void daddy(int x,int y, int w, int h)

Header function for daddy function

{

 

noStroke();

Turns off outline to produce peanut shape by drawing two ellipses

fill(skinTone);

 

int eyeXoffset = int((15.0/80.0)*w);

Calculates x offset for eyes

int eyeYoffset = int(.35*h);

Calculates y offset for eyes

int mouthYoffset = int(.10*h);

Calculates y offset for mouth (note that there is no x offset, as the smile is in the middle)

int mouthWidth = int(.5*w);

Calculates the width of the ellipse that will be used for the mouth

int mouthHeight = int(.3*h);

Calculates the height of the ellipse that will be used for the mouth

int hairOffsetY = eyeYoffset*3;

Calculates the y offset of the hair

int hairRadius = 3*eyeSize;

Calculates the radius of the hairs

ellipse(x,y,1.2*w,h);

Draws lower ellipse

ellipse(x,y-h/2,w,h);

Draws upper ellipse

stroke(0);

Turns outline back on

fill(0);

Sets fill to black for the eyes

ellipse(x-eyeXoffset,y-eyeYoffset,

eyeSize,eyeSize);

Draws left eye (to the viewer’s left)

ellipse(x+eyeXoffset,y-eyeYoffset,

eyeSize,eyeSize);

Draws right eye

noFill();

Turns off fill in preparation for the hair and mouth

arc(x,y-hairOffsetY,hairRadius,

hairRadius,-PI/2,PI/2);

Draws the first part of the hair

arc(x,y-hairOffsetY-hairRadius,

hairRadius,hairRadius,PI/2,PI*3/2);

Draws the second part of the hair

stroke(240,0,0);

Sets the color of stroke to red for the mouth

arc(x,y+mouthYoffset,mouthWidth,mouthHeight,

QUARTER_PI,3*QUARTER_PI);

Draws the mouth

}

Closes daddy function

The sketch continues, first with the declaration of the global variables, then with the definitions of setup, draw, and daddy. The general procedure for programming in Processing requires me to define a setup and a draw. I chose to name and define a function I call daddy. The advantage of doing that is that I could put in multiple calls to the function and produce cartoons at distinct places in the display window of distinct widths and heights. If I tried to do this with what I call naked numbers, I would eventually produce the same thing but probably have some situations with eyes outside the head.

Note

When programmers need to refer to any built-in Processing function or variable, we need to use the name accurately, including case. However, when we make up our own names, it is totally up to us, as long as we are consistent. I could have decided that the width of the skinny face would be held in a variable named skinniW, but if I later referred to it as skinnyW, Processing would have called it an error. Therefore, misspelling of names is fine, if you are consistent. Also be willing to use longer names, perhaps with camel casing because that will help you understand your program and be consistent.

Table 1-2 explains the coding using a two-column table, as promised.

Things to Look Up

The examples in this chapter made use of ellipses and arcs, which are pieces of ellipses. Processing also supports drawing rectangles, triangles, and lines, and you can look these up. The functions are rect, triangle, and line. The Processing document provides an explanation and short examples, which you can try and then modify. There also is a way to define your own shapes using beginShape, vertex, and endShape. Shapes respond to the current fill and stroke settings. There will be examples of each of these in later chapters, but you can start your exploration now.

Processing provides alternative ways to specify an ellipse or a rectangle. Look up ellipseMode and rectMode. The default methods are different for ellipse and rectangle.

The Hello, world examples demonstrated some ways to modify how text is displayed. You can change fonts (see loadFont or createFont), and you can change the alignment of text using textAlign. You can set the size of the text, either in the createFont statement or using textSize.

As I mentioned, Processing does provide a function called radians that converts from degrees to radians. You can look it up and use it, but, again, I urge you to practice working directly with radians, using the built-in constants PI, HALF_PI, and so on.

The PDE, under Tools on the toolbar, has a Color Selector tool. This can provide the RGB values into your program.

How to Make This Your Own

With this and anything else, proceed slowly. You can copy all the code and make sure it runs and produces exactly what is shown in the picture. You then can do some or all of the following:
  • Add a third instance of the Daddy logo somewhere else in the window. This requires the addition of just one more statement to the draw function.

  • Change the values of the global variables, including those indicating widths, heights, and also skin color.

  • Change the daddy function itself while still thinking of it as some sort of face or head.
    • Add a nose, perhaps by using two lines. Look up line.

    • Make the smile bigger. You can make the arc cover more of the same ellipse, change the size of the ellipse, or do both.

    • Substitute a frown for the smile.

    • Make the hair longer. Add another hair or two.

    • Look up how to draw rectangles and add a hat.

  • Change the daddy function totally; that is, create a function that produces a small drawing with parameters setting the horizontal and vertical positions and other attributes such as width and height. How about pumpkins? How about houses? How about flowers? (For flowers, or anything with curved lines that are not arcs, you might want to wait for later chapters.) Remember the technique of defining variables in terms of other variables. This is critical.

What You Learned

You learned how to create a Processing sketch. This included the roles of setup and draw, although you will learn more about draw in later chapters. You also saw how to draw an ellipse and an arc, which is a piece of an ellipse. You learned the roles of fill, stroke, noFill, noStroke, and noLoop.

The most important concept in this chapter was how to expand the language by creating a function. Functions have a specific format, with a header giving the name, the return value (more on this in later chapters), and specification of the parameters. Another concept, perhaps equally important, is the notion of a variable, a way of associating a value with a name. This example did not show all the power of functions or variables but provided an introduction. One benefit of defining the function with parameters is that the relationships among the different values are specified, so there will be no eyes outside the head, for example. Another benefit was the ease in drawing two cartoons, not just one, and at different places in the window.

What’s Next

Chapter 2 introduces event handling: how to set up a response to mouse actions. It also introduces stochastic processing, a fancy way of modeling events that have a random or probabilistic aspect. The chapter provides examples of the for loop, a type of compound statement, and the use of expressions to produce polygons. There will be two examples. In one, you let your user, viewer, player, or audience click the mouse on the display window and a polygon will appear at that spot. The polygons start off as triangles and increase the number of sides until a set limit is reached and go then back again to triangles. The other example is what I categorize as a coin toss. However, I use two photos of family members. You can find and use photos of the head and the tail of an actual coin or any two photos you wish.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.206.171