[`height`](https://p5js.org/reference/#/p5/height) --- **Setting** [`background()`](https://p5js.org/reference/#/p5/background)

[`fill()`](https://p5js.org/reference/#/p5/fill)

[`noFill()`](https://p5js.org/reference/#/p5/noFill)

[`noStroke()`](https://p5js.org/reference/#/p5/noStroke)

[`stroke()`](https://p5js.org/reference/#/p5/stroke) --- **2D Primitives** [`line()`](https://p5js.org/reference/#/p5/line)

[`point()`](https://p5js.org/reference/#/p5/point) --- **Structure** [`setup()`](https://p5js.org/reference/#/p5/setup)

[`draw()`](https://p5js.org/reference/#/p5/draw)

[`noLoop()`](https://p5js.org/reference/#/p5/noLoop) --- **Loading & Displaying** [`text()`](https://p5js.org/reference/#/p5/text) ``` We know that your statements are executed in order from top to bottom; this is the typical **_flow of execution_** in a computer program. When you call a function such as `background()` or `point()`, your program jumps over to the definition of the function and begins executing statements in the function’s body in order from top to bottom. Once finished, your program jumps back out of the program and picks up where it left off. ```javascript function setup() { createCanvas(200, 200) } function draw() { background(220) // jumped over to the definition of background // ... and we're back point(100, 100) // ... } ``` ```javascript // add sim ``` Let’s revisit our first simulation of a constellation and tidy it up a bit using functions. I think we can break the simulation into two core pieces: drawing outer space and drawing stars. The process of taking a problem and breaking into simpler pieces is known as **_decomposition_**. **Example 3.1 Decomposing a constellation** When you press the play button for this sketch, p5 calls your `setup()` function once, which calls `createCanvas()` once. Then, p5 calls your `draw()` function repeatedly, which calls `drawSpace()` and `drawConstellation()` each time it executes. They in turn call other drawing functions before they finish executing and it’s time to `draw()` the next frame to the canvas. ```javascript // add sim ``` It is much easier to keep track of what’s going on in your programs when you write code with descriptive names like `drawConstellation()`. We’ll use the JavaScript community’s convention of naming new functions and variables with multiple words separated by capitalization as opposed to spaces. In this naming convention, called “camelCase”, the first word is all lowercase and subsequent words begin with a capital letter. ** Exercise 3.7** Rewrite one of your previous sketches and organize it using new functions you define. It may not be obvious at first how to delineate between different parts of your code, and there are probably multiple ways to do so elegantly. ** Exercise 3.8** Rewrite one of your previous sketches and organize it using new functions you define. It may not be obvious at first how to delineate between different parts of your code, and there are probably multiple ways to do so elegantly. ## Input/Output The functions we’ve defined thus far do a nice job of bundling instructions together and organizing code, but they’re a bit limited. You can customize a function by adding a required input, or **_parameter_**, to its header. Let’s add a parameter to the `drawConstellation()` function. ```javascript function drawConstellation(starColor) { stroke(starColor) strokeWeight(3) point(20, 120) point(55, 130) point(90, 127) point(125, 115) point(150, 135) point(150, 85) point(175, 100) } ``` Now, you can specify what color you want to draw your constellation by providing an argument when you call the function. Arguments are assigned to parameters, and you can have more than one! For example, you could write a version of `drawConstellation()` that lets you specify the color and size of stars that are drawn. ```javascript function drawConstellation(starColor, starSize) { stroke(starColor) strokeWeight(starSize) point(20, 120) point(55, 130) point(90, 127) point(125, 115) point(150, 135) point(150, 85) point(175, 100) } ``` Now you can customize the size and color of stars when you call `drawConstellation()`. Parameters are part of a function’s definition and only exist within a function’s body. The region of a program where a variable exists is called its **_scope_**. In our `drawConstellation()` example, the rest of the sketch has no idea what `starSize` means. Any variables you declare inside of a function are also invisible to the outside world; their scope is the function body. Let’s revisit one of our abstract paintings from the last chapter and tidy up the code a little. **Example 3.2 Decomposing an abstract painting** The variables `x` and `y` only exist inside the body of the `paintCanvas()` function. They are examples of **_local variables_**, meaning they only exist locally inside of the function where they were created. By contrast, variables you declare at the top of your sketch are visible throughout your code and are known as **_global variables_**. The meteor sketch was our first encounter with variables in the global scope. **Example 3.3 Revisiting global variables** It’s convenient for us to define the variables `x` and `y` in the global scope since we’re referring to the same meteor when we draw it and when we update its position. Global variables can be helpful when used sparingly, but they can be hard to keep track of as your programs grow in size. It’s often better practice to produce, or **_return_**, values on the fly and assign them to local variables. Let’s see this in action with the collision example from the last chapter. **Example 3.4 Introducing mathematical functions** The `millis()` function on line 6 is like a stopwatch built into p5; it returns the number of milliseconds that have passed since a sketch started its execution. We can use it to increase the value of `x` locally instead of globally. The JavaScript functions `s()` and `d()` are equivalent to the mathematical functions $ s(x)=0.5x+50 $ and $ d(x)=-0.5x+150 $, respectively. When you call either function with an argument, they assign the argument to the parameter `x` and use `x` to compute a return value. On line 7 of the previous example, it may seem strange to call `s()` with an argument `x` when `x. also happens to be the name of the function's parameter Aligning variable and parameter names in this way can be helpful to clarify your intent, but it isn’t required. Also on line 7 above, note that the value returned from `s(x)` is assigned the `y` parameter of `drawShuttle()`. Using the return value from one function as the argument for another is known as **_composition_**; we’ll discuss the idea in more detail in the next section. For now, let's draw some more images.

```{panels} :column: col-12 :card: border-2 :body: text-center

John Henry Thompson

[John Henry Thompson](http://www.johnhenrythompson.com/) is an inventor and teacher. John Henry combines technology with art to help people express themselves and learn about the world. He led the development of several applications for artists along with Lingo, a programming language for building such applications. ```## Graphing with p5 Let’s continue drawing with functions by visualizing them as a set of points. Keep in mind that the $ y $-axis points downward in computer graphics by default. **Example 3.5a Drawing a set of points** I can see the basic shape of the graph, but what gives with all of that empty space? Let’s draw the points a bit closer together by decreasing the value of our increment `dx`. **Example 3.5b Bonus points** Much better. But what if we changed the shape of the graph a bit by changing the value of `a`? **Example 3.5c Back to square one** Oof, the points on the graph are once again separated by empty space. We can continue adjusting the value of `dx` each time we draw a graph, but I think this is a nice opportunity to present another one of p5’s drawing capabilities: **_shapes_**. More precisely, we can connect a set of points, called vertices, using line segments to create a polygon. The following sketch draws the simplest polygon, a triangle. **Example 3.6a A triangle** This object isn’t quite a polygon, however, because the vertices don’t enclose a region of space. You can connect the final and initial vertices by adding the `CLOSE` argument to `endShape()`. **Example 3.6b An enclosed triangle** p5 fills the interior of shapes with the color white by default. You can set the fill color for shapes by calling the `fill()` function like so. **Example 3.6c A colorful triangle** Back to our graph, let’s try to make our code more flexible by swapping out individual points for vertices connected by tiny line segments. That way, we are guaranteed to cover any gaps introduced by changing the graph’s shape. We aren’t concerned with the area enclosed by the graph just yet, so we won’t add the `CLOSE` argument to `endGraph()`. **Example 3.7 Graphing with line segments** The variable `width` keeps track of the width of the drawing canvas; `height` keeps track of its height. You could make the sketchbook function a little more like a graphing calculator by removing the default fill from the shape you just created. To do so, add a call to `noFill()` at the beginning of your `graph()` function. ```javascript function graph() { noFill() beginShape() // add vertices... } ``` It’s worth taking a moment to present another loop syntax that can help to clarify our code. In the previous example we wrote the following: ```javascript let dx = 1 let x = 0 while (x < width) { vertex(x, f(x)) x += dx } ``` Let’s focus on the basic structure of the loop by removing the variable dx and the call to `vertex()`: ```javascript let x = 0 while (x < width) { // do stuff x += 1 } ``` This steady, sequential increment has shown up repeatedly in our sketches. It turns out that the pattern can also be expressed using a **_for loop_**. ```javascript for (let x = 0; x < width; x += 1) { // do stuff } ``` The loop header now completely describes the iteration. Start from $ 0 $, stop at $ 200 $, and count by $ 1 $’s. When you know that your loop is meant to repeat a specific number of times, `for` loops can help to clarify that intent. By way of contrast, `while` loops are especially useful when you aren’t sure how many iterations a process may need to complete. ```javascript while (stillLearning) { learn() } ``` OK, let’s put `for` loops to work drawing graphs. **Example 3.8 Drawing a graph with a `for` loop** ** Exercise 3.9** Simulate a ball flying through the air along a parabolic path. Use a mathematical model like $ f(x)=a(x-h)^{2}+k $ to describe the ball’s motion. Try setting a to a small negative number and choose a point $ (h,k) $ as the peak of its flight. Decompose your simulation into a few functions including one that returns a value. The following code snippet may be a helpful template for describing your ball’s path. ```javascript function f(x) { let a = 0 let h = 0 let k = 0 return a * (x - h) ** 2 + k } ``` # 3.3 Combination and Composition We’ve seen that mathematical functions are useful for modeling all sorts of phenomena, and that they are easy to express in a way that computers can execute. In this section, we’ll use financial modeling to explore a few ways that functions can work together. ## Combination **Adding Functions** Given a pair of functions, it’s simple to combine their outputs using an arithmetic operation. Let’s say you invest in a pair of companies by buying shares of their stock and becoming a part-owner. The stock price of the first company, Acme Corporation, is currently $ \$ 100 $ and increases $ 7 \% $ annually, which we can express with the function $ A(t) = 100 \cdot 1.07^{t} $. In this equation, $ A(t) $ is the price of one share $ t $ years after you bought the share for $ \$ 100 $. The second company, Whitewhale Consolidated Interests, also has a stock price modeled using an exponential function, in this case $ W(t)=80 \cdot 1.09^{t} $, which gives the price of one share $ t $ years after you bought it for $ \$ 80 $. The value of your set of stocks, called a **_portfolio_**, at some time in the future is the sum of the prices of your Acme and Whitewhale shares at that future time. We can express this relationship algebraically as $ P(t)=A(t)+W(t) $ where $ P(t) $ is the value of your portfolio. So, how much would your portfolio be worth in twenty years? ```{panels} :column: col-12 :card: border-0 **Individual Stocks** $ A(t) = 100 \cdot 1.07^{t} $ $ W(t) = 80 \cdot 1.09^{t} $ **Portfolio** $ P(t) = A(t) + W(t) $ **Projection** $ P(20) = A(20) + W(20) $ $ P(20) = ( 100 \cdot 1.07^{20} ) + ( 80 \cdot 1.09^{20}) $ $ P(20) = 386.96 + 448.35 $ $ P(20) = 835.51 $ ``` Given you originally purchased the stocks for $ \$ 180 $, you made a profit of $ \$ 835.31 - \$ 180 = \$ 655.31 $. Not too shabby! **Multiplying Functions** Let’s shift our focus to another example of combining functions, this time based on budgeting. I love working from cafés because I run into friends and meet new people while enjoying a change of scenery. Coffees add up, though, so I try to limit my café spending to $ \$ 24 $ each week. An economist might model the situation using an equation like the following. $$ B = P \cdot Q $$ My café budget must equal the price of each cup of coffee, $ P $, multiplied by the quantity of those coffees, $ Q $, that I purchase. If we assume that each coffee costs $ \$ 4 $ after tax and tip, then we can easily solve for the number of coffees that I can order each week if I am to stay within my budget. ```{panels} :column: col-12 :card: border-0 :body: text-center $ 24 = 4 \cdot Q $ $ \frac{24}{4} = Q $ $ 6 = Q $ ``` Now let’s imagine the café is steadily raising coffee prices to reflect the increased prices of all of the goods and services upon which it depends. This economic scenario is known as **_inflation_**. Each year, the overall price for each cup of coffee will increase by $ 2 \% $. Now, price is a function of time $ P(t) $. If I continued buying 6 cups of coffee each week, my budget would steadily increase as follows. ```{panels} :column: col-12 :card: border-0 :body: text-center $ P(t) = 4 \cdot 1.02^{t} $ $ Q(t) = 6 $ $ B(t) = P(t) \cdot Q(t) $ ``` My weekly café budget, $ B(t) $, is now the product of two functions, $ P(t) $ and $ Q(t) $. Let’s check in to see how my budget is doing ten years from now. ```{panels} :column: col-12 :card: border-0 :body: text-center $ B(10) = P(10) \cdot Q(10) $ $ B(10) = (4 \cdot 1.02^{10}) \cdot 6 $ $ B(10) = 29.25 $ ``` If I continued with business as usual, I would be more than $ 20 \% $ over my original budget! I may decide that this budget increase is fine or that I need to change my behavior in order to achieve my original financial goal. Either way, a little analysis can help me to plan. ## Composition Mathematical functions are input/output processes, and we can link them together like machines on an assembly line. Using the output of one function as the input to another is known as **_composition_**. Let’s build up this mathematical machinery with a minimal example before applying the concept in the exercises. **Figure 3.11 The composition of two functions $ f $ and $ g $** ``` // add figure ``` First, let’s define these functions as the following. ```{panels} :column: col-12 :card: border-0 :body: text-center $ f(x) = x^{2}+5 $ $ g(x)=3x-4 $ ``` Next, we’ll evaluate $ f(7) $ to produce the value $ f(7) = (7)^{2} + 5 = 54 $. Finally, let’s take that $ 54 $ and pass it as the input to $ g $, producing $ g(54) = 3(54) - 4 = 158 $. We mathematicians typically express compositions using the notation $ g(f(x)) $ or $ (g \circ f)(x) $, both read "$ g $ of $ f $ of $ x $". In the previous example, we evaluated the composition $ g(f(7)) $ in two steps. You could also simplify the composition algebraically to start. The output of the function $ f $ has become the input to the function $ g $, so you can replace $ g $’s argument $ x $ with $ f(x) $. ```{panels} :column: col-12 :card: border-0 :body: text-center $ f(x) = x^{2} + 5 $ $ g(x) = 3x - 4 $ $ g(f(x)) = 3 \cdot f(x) - 4 $ ``` Now, it’s easy to substitute $ f(x) $ as follows. ```{panels} :column: col-12 :card: border-0 :body: text-center $ g(f(x)) = 3 (x^{2}+5) - 4 $ $ g(f(x)) = 3x^{2} + 15 - 4 $ $ g(f(x)) = 3x^{2} + 11 $ ``` Evaluating $ g(f(x)) $ is just a matter of substituting a number for $ x $ into this final expression and computing the value. ```{panels} :column: col-12 :card: border-0 :body: text-center $ g(f(7)) = 3(7)^{2} + 11 $ $ g(f(7)) = 3(49) + 11 $ $ g(f(7)) = 158 $ ``` Composing functions in code maps neatly to the mathematical notation we just covered. **Example 3.5a Composing two functions** ## String Interlude JavaScript's data type for text is called a **_string_**. You can create strings by putting alphanumeric characters and even emoji between pairs of single `''` or double `""` quotes. Let's display a string on the canvas by passing one as the first argument to p5's `text()` function. **Example 3.5b Displaying strings** You could also combine, or **_concatenate_**, strings with other strings using the `+` operator. **Example 3.6a Concatenating strings with strings** Let’s end our brief introduction to strings by concatenating the left-hand side of our equation, a string, with the right-hand side, a floating point number. **Example 3.6b Concatenating strings with numbers** Now that we can visualize our algebraic work, let's return to composition. Composition, as with any new mathematical technique, requires careful consideration to use correctly. Let’s compose the function $ g(x) = 3x-4 $ with the function $ h(x) = \frac{1}{x} $. ```{panels} :column: col-12 :card: border-0 :body: text-center $ g(x) = 3x - 4 $ $ h(x) = \frac{1}{x} $ $ h(g(x)) = \frac{1}{g(x)} = \frac{1}{3x - 4} $ ``` Now, let’s try evaluating $ h(g(\frac{4}{3})) $. ```{panels} :column: col-12 :card: border-0 :body: text-center $ h(g(\frac{4}{3})) = \frac{1}{3(\frac{4}{3}) - 4} $ $ h(g(\frac{4}{3})) = \frac{1}{4 - 4} $ $ h(g(\frac{4}{3})) = \frac{1}{0} $ ``` Uh oh. Division by zero is undefined, so the denominator of $ h(x) $ can’t be $ 0 $. Since $ g(\frac{4}{3}) = 0 $, we need to restrict the domain of the composition $ h(g(x)) $ to all real numbers except $ \frac{4}{3} $. $$ D : \{ n \: | \: n \in \mathbb{R} \: and \: n \ne \frac{4}{3} \} $$ ** Exercise 3.10** Compose the functions $ a(x) = \sqrt{x} + 2 $ and $ b(x) = 7x + 11 $ both ways. That is, find the algebraic expressions for $ a(b(x)) $ and $ b(a(x)) $ and note their domain and range. Does the order of composition matter? Explain why or why not in plain English. ## Inverses Revisited Let’s conclude this section by considering a special case of composition: a function and its inverse. I’ll define the function $ q $ as $ q(x) = 3x + 5 $ and its inverse $ q^{-1}(x) = \frac{x-5}{3} $. Frist, let’s evaluate the composition $ q(q^{-1}(10)) $ by starting with the inner function. ```{panels} :column: col-12 :card: border-0 :body: text-center $ q^{-1}(10) = \frac{10 - 5}{3} = \frac{5}{3} $ $ q( \frac{5}{3}) = 3(\frac{5}{3}) + 5 = 5 + 5 = 10 $ ``` Interesting. Our input of $ 10 $ produced an output of $ 10 $. I wonder if that’s just a coincidence. Let’s try another input value, this time something negative. ```{panels} :column: col-12 :card: border-0 :body: text-center $ q^{-1}(-4) = \frac{-4 - 5}{3} = \frac{-9}{3} = -3 $ $ q(-3) = 3(-3) + 5 = -9 + 5 = -4 $ ``` OK, two for two. How about we see what happens when we compose these inverses algebraically? ```{panels} :column: col-12 :card: border-0 :body: text-center $ q(q^{-1}(x)) = 3 \cdot q^{-1}(x) + 5 $ $ q(q^{-1}(x)) = 3( \frac{x-5}{3}) + 5 $ $ q(q^{-1}(x)) = x - 5 + 5 $ $ q(q^{-1}(x)) = x $ ``` How about that? Composing a function and its inverse results in... nothing happening at all. The output value is just the input! If you think about this result, it has some intuitive appeal. Inverting a function requires applying each operation in reverse. If you run a process forward, then immediately reverse each step, you wind up right where you started. OK, I think you’re ready to apply composition as part of a quick financial analysis. ** Exercise 3.11** Imagine opening a small business that specializes in data visualization. Let’s say you charge $ \$ 30 $ per hour to help local organizations to communicate their work by making interactive charts and simulations. Write a short program that calculates how much tax you would owe at the end of a year based on the number of hours that you work. For simplicity, assume all of your income is taxed at $ 15 \% $. Hint: write two functions and compose them. ** Exercise 3.12** In this exercise, you will write another program that more accurately reflects income taxes in the United States. Use the marginal tax rates in Table 3.7 to compute the amount of income tax you owe. This system is a little complex, so let’s walk through a slightly simplified example together. If you worked $ 2,000 $ hours and earned $ \$ 60,000 $, then your income would be taxed as follows. ```{panels} :column: col-6 :card: border-0 :body: text-right $ \$ 9,950 $ at $ 10 \% $ $ \$ 40,525 - \$ 9,951 = \$ 30,574 $ at $ 12 \% $ $ \$ 60,000 - \$ 40,526 = \$ 19,474 $ at $ 22 \% $ --- ``` All together, you would owe $ \$ 9,950 \times 0.10 + \$ 30,574 \times 0.12 + \$19,474 \times 0.22 = \$ 8,948.16 $. From a taxable income of $ \$ 60,000 $, your **_effective tax rate_** would be the following: $$ \frac{ \$ 8,948.16 }{ \$ 60,000 } = 0.149 = 14.9 \% $$ Hint: write two functions and use composition again, this time accounting for different tax brackets. If-statements and inequalities are your friends here. **Table 3.7 United States single filer tax rates for 2021 *Courtesy* irs.gov** ```{list-table} :header-rows: 1 * - Income ($) - Rate (%) * - $ \$ 0 $ to $ \$ 9,950 $ - $ 10 \% $ * - $ \$ 9,951 $ to $ \$ 40,525 $ - $ 12 \% $ * - $ \$ 40,526 $ to $ \$ 86,375 $ - $ 22 \% $ * - $ \$ 86,375 $ to $ \$ 164,925 $ - $ 24 \% $ * - $ \$ 164,926 $ to $ \$ 209,425 $ - $ 32 \% $ * - $ \$ 209,426 $ to $ \$ 523,600 $ - $ 35 \% $ * - $ > \$ 523,600 $ - $ 37 \% $ ``` # 3.4 Vectors Now that you have a handle on mapping numerical inputs to numerical outputs, I’d like to introduce a new mathematical object that has a starring role in applications from finance to physics to artificial intelligence: the **_vector_**. We’ll get acquainted with vectors by using them to simulate motion in this section. ## `p5.Vector` A vector is a powerful abstraction that takes different forms depending upon the application. We will explore several of these applications together in this book series. For starters, let’s focus on **_Euclidean vectors_**, which you can think of as arrows pointing in space. **Figure 3.12 A Euclidean vector $ \vec{AB} $** The vector $ \vec{AB} $ starts from its **_initial point_** $ A $ and ends at its **_terminal point_** $ B $. Mathematicians use an arrow $ \vec{} $ to denote a vector quantity and distinguish it from numbers, points, or any other mathematical objects. We call $ A $ and $ B $ the vector’s **_tail_** and **_tip_**, respectively. You could draw this vector anywhere in two-dimensional space, but how about we pin the tail on the origin to start? **Figure 3.13 A vector from the origin** The vector $ \vec{OP} $ now tells us where the point $ P $ is relative to the origin $ O $. Let’s consider the specific case of a point $ P $ located at coordinates $ (150,50) $. We could write the point’s **_position vector_** $ \vec{p} $ using either of the following notation schemes: ```{panels} :column: col-12 :card: border-0 :body: text-center **_Row vector:_** $ \vec{p} = (150,50) $ **_Column vector:_** $ \vec{p} = \begin{bmatrix} 150 \\ 50 \end{bmatrix} $ ``` I will typically write vector names with single, lowercase letters such as $ \vec{p} $ in this book for brevity. Row vectors are easier to fit on a line of text, so I will default to that notation. We will work with column vectors extensively in Chapter 8. **Figure $ \pi $ A position vector** $ \vec{p} $ is an arrow that extends $ 150 $ units to the right and $ 50 $ units down. Its horizontal extent, called its $ x $-component, is $ 150 $ and its vertical extent, called its $ y $-component, is $ 50 $. Taken together, we can see that vectors have a length, or **_magnitude_**, and point in some **_direction_**. We will put these intuitive ideas on firmer footing in the next chapter. Our vector $ \vec{p} $’s components $ (150,50) $ are just real numbers, also known as **_scalars_**. As such, each component supports all of the arithmetic we covered in Chapter 1. We’ll see these arithmetic abilities in action shortly. Let’s begin our journey into programming with vectors by steadily enhancing our meteor sketch. Fortunately for us, p5 includes vectors out-of-the-box. **Example 3.7 Hello, `p5.Vector`** Line 8 of the sketch above creates a new `p5.Vector` **_object_** by calling the `createVector()` function. Objects are containers for data, such as our vector’s $ x $ and $ y $-components, and functions intended to operate on that data. The two arguments passed to `createVector()` set the new vector’s $ x $ and $ y $-components. On line 12, we access the `position` vector’s $ x $ and $ y $-components using `.` known as the dot operator. The dot operator is our entry point to accessing an object’s data and calling its functions. Computer programmers use the **_Unified Modeling Language (UML)_** to visualize the design of software systems. The following UML diagram describes the blueprint for our position object, called its **_class_**. **Figure 3.15 UML class diagram of `p5.Vector`** ``` // add figure ``` `p5.Vector` objects created using this blueprint contain additional data and functions, but we’ll stick with this subset of the class for now as we lay some foundations in vector arithmetic. It’s worth noting that functions bundled with a class are also known as **_methods_**. The distinction isn’t particularly meaningful for us, so I will continue calling them functions. ## Vector Addition All we need to get started with vectors is addition. Recall how we represented addition with natural numbers by snapping blocks together. **Figure 3.16 Block addition** Visually, we just placed one stack of blocks on top of the other and counted the number of blocks in the combined stack. Vector addition works similarly, but instead of stacking blocks, we place arrows next to each other “tip to tail”. **Figure 3.17 Vector addition** ``` // add figure ``` Let’s walk through this operation together. First, imagine taking a stroll starting from $ \vec{a} $’s tail and continuing until you reach its tip. Once there, continue from $ \vec{b} $’s tail until you reach its tip. That’s all there is to vector addition! Now that you’ve seen vector addition, let’s perform the operation by hand to get a feel for the mechanics. When we add two vectors, we add their corresponding components: $ x $’s with $ x $’s and $ y $’s with $ y $'s. ```{panels} :column: col-12 :card: border-0 :body: text-center $ \color{#785ef0}{\vec{a}} = (\color{#785ef0}{1}, \color{#785ef0}{2}) $ $ \color{#fe6100}{\vec{b}} = (\color{#fe6100}{3}, \color{#fe6100}{1}) $ $ \color{#785ef0}{\vec{a}} + \color{#fe6100}{\vec{b}} = (\color{#785ef0}{1} + \color{#fe6100}{3}, \color{#785ef0}{2} + \color{#fe6100}{1}) $ $ \color{#785ef0}{\vec{a}} + \color{#fe6100}{\vec{b}} = (\color{#ffb000}{4}, \color{#ffb000}{3}) $ ``` $ \vec{a} + \vec{b} $ is the **_resultant vector_** produced by adding $ \vec{a} $ and $ \vec{b} $ and it describes a more direct path: given the same arrangement of $ \vec{a} $ and $ \vec{b} $, imagine flying in a straight line from $ \vec{a} $’s tail to $ \vec{b} $’s tip. Your initial and terminal points are the same, which means that the $ x $ and $ y $-components are the same. Let’s give the resultant vector a name $ \vec{c} $ and state $ \vec{c} = \vec{a} + \vec{b} $. **Figure 3.18 Vector addition** Two vectors are equal when their corresponding $ x $ and $ y $-components are equal. Using our previous result from vector addition, we can state the following: ```{panels} :column: col-12 :card: border-0 :body: text-center $ \vec{a} + \vec{b} = (4,6) $ $ \vec{c} = (4,6) $ $ \vec{d} = (4,6) $ $ \vec{a} + \vec{b} = \vec{c} = \vec{d} $ ``` ** Exercise 3.13** Prove whether or not vector addition is commutative. That is, does $ \vec{a} + \vec{b} = \vec{b} + \vec{a} $? Use a concrete example to guide your intuition, then prove your result in general for a pair of vectors such as the following: ```{panels} :column: col-12 :card: border-0 :body: text-center $ \vec{a} = (a_x, a_y) $ $ \vec{b} = (b_x, b_y) $ ``` The subscripts $ _x $ and $ _y $ denote a vector's $ x $ and $ y $-components, respectively. ** Exercise $ \pi $** Prove whether or not vector addition is associative. In other words, does $ (\vec{a} + \vec{b}) + \vec{c} = \vec{a} + (\vec{b} + \vec{c}) $? ## Vector Motion Now that you have vector addition under your belt, let’s apply this operation to set your meteor in motion. **_Velocity_** is a change in position, and **_velocity vectors_** enable us to specify how the $ x $ and $ y $-components of a `position` vector should change. If you know where you are, and you know how you intend to move, then you can figure out where you will end up. **Figure 3.19 Vector motion** Let’s see `position` and velocity `vectors` working together to move our meteor. **Example 3.8 Meteor Motion** This sketch introduces a few new ideas. First, notice that I declared the variables `position` and `velocity` on lines $ 1 $ and $ 2 $, but I didn’t assign them values until lines $ 6 $ and $ 7 $. p5 can’t create `p5.Vector` objects until your sketch begins running, so any calls you make to `createVector()` must occur within the body of the `setup()` or `draw()` functions. We only needed to create the vectors once in this sketch, so I called `createVector()` in the body of `setup()`. Next, let’s have a look at line $ 13 $. I used the dot operator `.` to call the `add()` function which belongs to the `position` vector. Behind the scenes, calling `position.add(velocity)` updates `position.x` and `position.y` by adding `velocity.x` and `velocity.y`, respectively. You could achieve the same result manually: ```javascript position.x = position.x + velocity.x position.y = position.y + velocity.y ``` Now, let’s compare this pair of statements to our call to the `add()` function: ```javascript position.add(velocity) ``` Much better. Objects enable us to write code that is often clearer, more concise, and more expressive than we could without them. We’ll play with `p5.Oscillator` objects in the next chapter, and you will define classes of your own in Chapter 5. In the meantime, let’s move forward to multiplication. ## Scalar Multiplication The next stop on our introduction to vector arithmetic is **_scalar multiplication_**. Given a vector $ \vec{v} = (1,2) $ you can multiply both components by a scalar value such as $ 5 $. ```{panels} :column: col-12 :card: border-0 :body: text-center $ 5\vec{v} = (5 \cdot 1, 5 \cdot 2) $ $ 5\vec{v} = (5, 10) $ ``` In code, you can multiply a vector by a scalar like so: `velocity.mult(5)`. ** Exercise 3.15** Use a system of linear inequalities to create regions of the canvas that scale the meteor’s velocity up or down. For example, consider the following code snippet: ```javascript if (position.x > 95 && position.x < 105) { velocity.mult(1.001) } ``` Next up, how about we use vector multiplication to turn our meteor into a celestial ping-pong ball? **Example 3.9 Celestial ping-pong** When we call `velocity.mult(-1)` on line 14, the `velocity` vector’s components are both multiplied by $ -1 $, so the meteor begins traveling in the opposite direction. ** Exercise 3.16** Grab something to write with and draw a picture of the initial `velocity` vector from Example 3.9 and label its components. Then, draw the vector produced after multiplying `velocity` by $ -1 $ and label the transformed vector. ** Exercise 3.17** Given $ \vec{a} = (3,5) $ and $ \vec{b} = (1,2) $ draw the following: First, draw a picture of $ \vec{a} + (-\vec{b}) $ and the resultant vector from this operation. Next, draw $ \vec{a} $ and $ \vec{b} $ with their tails pinned to the origin. Draw the vector pointing from $ \vec{b} $'s tip to $ \vec{a} $'s tip. What do you notice about this vector and the resultant vector you drew a moment ago? ## Paintball OK, we’ve found our footing with vector arithmetic, so let’s have some fun using this new toolkit. Turning a meteor into a ping-pong ball got me thinking about arcade games, and I have a classic game in mind for the next section. Let’s work towards that goal by making our bounces a bit more flexible. In Example 3.9, we reversed the ball’s `velocity` vector when the value of its `position` vector met a logical condition. My question is this: how can we bounce off of the walls of the canvas in a more realistic fashion? Let’s see what happens if we simply widen the left and right boundaries. **Example 3.10 Widening the walls** Now the ball flies past the top and bottom of the screen before bouncing. How about we set another condition to handle those boundaries? **Example 3.11 Raising the roof** This result is more realistic but the bounce still doesn’t seem very natural. When the ball hits the bottom edge of the canvas, we definitely need to reverse the $ y $-component of its `velocity`. But why does it begin traveling to the left? When we detect a collision with the top or bottom edges of the canvas, let’s limit our scalar multiplication to the `velocity` vector’s $ y $-component and leave its $ x $-component unchanged. **Example 3.12 Isolating components** Now we’re almost in business! ** Exercise 3.18** Edit Example 3.12 so that the ball bounces correctly off of the left and right edges of the canvas. OK, our ball bounces around the canvas just fine now, so let’s play with that effect. First, I’m going to move the call to `background()` into the `setup()` function so that we can see the entire path traveled by the ball. Then I’ll set the stroke based on the ball’s `position`. **Example 3.13 Paintball** ** Exercise 3.19** Revisit your abstract painting from Chapter 2. Instead of looping over each pixel on the canvas, paint the image using the paintball from Example 3.13. # 3.5 TRON We’ll conclude this chapter with a look at *Tron*, a classic 1982 science fiction film that imagines a digital world shared by different lifeforms. The team behind Tron made many technical breakthroughs while working on the film including Perlin noise, a computer-based technique used to generate textures that appear natural. **_Perlin noise_** stands out among the team’s accomplishments for its broad application in generative art. In this section, we will apply Perlin noise to paint trails of light in our interpretation of a video game from the film. ## `map()` and `noise()` It’s time to journey into the Tron computer system. In the film, human Users are digitized and uploaded into a computer where they interact with Programs they have written. Within the vast digital space of the Tron system, the Grid is envisioned as a general purpose research platform where Users and Programs interact. Let’s commence our research by writing our first Program. ```{panels} :column: col-12 :card: border-2 **** **System:** A simulation environment in the Tron computer system where Programs ride vehicles called light cycles. ``` ```{panels} :column: col-12 :card: border-2 **$ \mapsto $** **Model:** The Grid is an empty, two-dimensional surface that is $ 200 $ pixels wide and $ 200 $ pixels high. A light cycle is a point of light that travels up, left, down, or right. ``` ```{panels} :column: col-12 :card: border-2 **** **Data:** The first Program’s `position` and `velocity` vectors are `p5.Vector` objects. The initial values of these vectors are $ \vec{p} = (100,100) $ and $ \vec{v} = (1,2) $. ``` ```{panels} :column: col-12 :card: border-2 **** **Algorithm:** First, update `position` by adding `velocity`. Then check to see if the `velocity` vector needs to change due to a collision with the edge of the Grid. Finally, draw a point at the Program’s `position`. ``` Let’s extend the code in Example 3.13 to leave a unique mark as the trailblazing first Program travels about the Grid. Recall that mixing different amounts of red, green, and blue (RGB) light is similar to mixing different pigments of paint. We can map the Program’s position to its color by calling the `map()` function as follows. **Example $ \pi $ The First Program** Red and green light combine to make yellow light, and we can generate fiery colors by combining different RGB values. The steady color transition visible along our Program’s trail is called a **_color gradient_**. Let’s examine how we achieved this gradient effect. On line $ 31 $, the `map()` function maps `position.x` from the interval $ [0,200] $, which covers all possible $ x $-coordinates within the Grid, to the interval $ [150,255] $, which covers the upper portion of possible red values. Line $ 32 $ performs the same task for green values. **Figure 3.20 A visual `map()`** ``` // add figure ``` Now that you’ve seen `map()` in action, we’ll use it as we explore another system for mapping numerical values to color values called the hue, saturation, and brightness (HSB) color system. If you’ve seen a color wheel before, then you are already familiar with the HSB color system. **Figure 3.21 HSB Color Courtesy p5.js** ``` // add figure ``` **_Hue_** describes the color type (e.g., orange or blue) -- $ [0, 360] $ **_Saturation_** describes the vibrancy (e.g., full color or washed out) -- $ [0, 100] $ **_Brightness_** describes brightness... :) -- $ [0, 100] $ In p5, you can call `colorMode(HSB)` to use HSB values when you call `background()`, `stroke()`, and `fill()`. Use the tool below to explore how different values for hue, saturation, and brightness combine to make color. For starters, let’s change our Program’s hue as it travels from left to right. **Example 3.15 HSB Program** ** Exercise 3.20** Use the `map()` function to change the Program’s saturation and/or brightness as it moves. You can base your color mappings on `position`, `velocity`, or a combination of the two. We now have multiple ways to generate color based on gameplay, but they’re all utterly predictable. The Program’s position maps to its color value using a few arithmetic operations, so the colors in any region of the Grid are always the same. Let’s mix things up a bit by introducing randomness.

```{panels} :column: col-12 :card: border-2 :body: text-center

Ken Perlin

[Ken Perlin](https://mrl.cs.nyu.edu/~perlin/) is a Professor of Computer Science at NYU. While working on the original *Tron* film, Ken invented an algorithm to generate realistic textures using random numbers. He earned an Academy Award for Technical Achievement for this breakthrough in 1997. ```p5 provides an implementation of Perlin noise that we can use by calling the `noise()` function. To get started, let’s graph `noise()` to get a sense of the function’s behavior. The function’s [documentation](https://p5js.org/reference/#/p5/noise) states that it returns values in the interval $ [0,1] $ which will be difficult to see. This is a good opportunity to use `map()` to scale those outputs and make better use of our canvas. **Example 3.16a Graphing Noise** The graph certainly looks noisy! Notice that the graph changes each time you run the sketch. Given the same set of input values, `noise()` generates different outputs during each successive run. This result may seem more like a curiosity than a tool to start, so let’s steadily reveal the full picture. Let’s draw a pair of noise graphs, our original graph from Example 3.16a and a version that is scaled horizontally. **Example 3.16b Tuning Noise** On line 22 of this sketch, all of the `x` values are multiplied by a factor of $ 0.1 $ before being passed to `noise()`. As a result, the inputs to `noise()` are in the interval $ [0,20] $ instead of $ [0,200] $ as in the original graph. **Figure 3.22 Scaling inputs to `noise()`** ``` // add figure ``` The second noise graph is less chaotic than the first because its inputs are packed more closely together. The closer the inputs, the closer the outputs. Scaling the inputs to `noise()` in this way enables us to tune the outputs to achieve different results. Let’s apply `noise()` to give our Program unique hues as it traverses the Grid. **Example 3.17 Noisy Program** ** Exercise 3.21** Use the `map()` and `noise()` functions to change the Program’s velocity from within your update() function. Now that you’ve set your digital world in motion, let’s join in the fun as the first Users. ## Keyboard Events The Grid is up and running, but there’s a problem: we can’t play! We can incorporate User interaction by defining a special function called `keyPressed()`. Any code placed in the body of `keyPressed()` will execute when p5 detects that you’ve pressed a key on your keyboard. ```javascript function keyPressed() { // only runs when a key is pressed } ``` p5 keeps track of the most recent key that was pressed in the variable `key`. Note that you will need to click on the drawing canvas before p5 can detect your key presses. You can check for individual key presses by adding an if statement to the body of `keyPressed()` as in the following example: **Example 3.18 Hello, keys** Let’s use the same approach to set the User’s velocity vector so that it points directly up, left, down, or right when they press the `'w'`, `'a'`, `'s'`, or `'d'` key, respectively. **Figure 3.23 Mapping keys to velocities** ``` // add figure ``` **Example 3.19a Hello, User** The `p5.Vector` class provides a `set()` function that enables us to set a vector’s components with a single statement such as `velocity.set(1, 0)`. Let’s use `set()` to clean up our `keyPressed()` function a bit. **Example 3.19b Setting vector components** The keys `'w'`, `'a'`, `'s'`, or `'d'` are often used to control velocity in computer games, but our keyboards do have those nice arrow keys just sitting there. You can detect presses on these special keys by swapping the key variable for `keyCode` and checking for a few key codes. **Figure 3.24 Mapping key codes to velocities** ``` // add figure ``` **Example 3.20 `keyCode` Control** OK, I think we’re ready to enter the next phase of our research: game design. Bouncing off of the walls is fun, but we now have all of the tools needed to build a real video game. Let’s create a minimal version of *Light Cycles* outlined below. ```{panels} :column: col-12 :card: border-2 **** **System:** A simulation environment in the Tron computer system where Users ride vehicles called light cycles. ``` ```{panels} :column: col-12 :card: border-2 **$ \mapsto $** **Model:** The Grid is an empty, two-dimensional surface that is $ 200 $ pixels wide and $ 200 $ pixels high. A light cycle is a point of light that travels up, left, down, or right. ``` ```{panels} :column: col-12 :card: border-2 **** **Data:** The User’s `position` and `velocity` vectors are `p5.Vector` objects. The initial values of these vectors are $ \vec{p} = (100,100) $ and $ \vec{v} = (1,0) $. ``` ```{panels} :column: col-12 :card: border-2 **** **Algorithm:** First, update `velocity` by checking for key presses. Then update `position` by adding `velocity`. After that, check to see if the User’s light cycle is destroyed due to a collision with the edge of the Grid. Finally, draw a point at the User’s `position`. ``` Instead of scaling `velocity.x` or `velocity.y when` the User collides with the wall, we will set the value of the boolean variable `gameOver` to `true`. When the game ends, we can pause the sketch by calling `noLoop()`. All together now: **Example 3.21 Game Over** The `textAlign()` function on line 19 makes it easier to center the `GAME OVER` message in the middle of the Grid. This is a big step forward for our game, but we still have a ways to go. In the real Light Cycles game, Users can also destroy their vehicles if they collide with the trail of light they emit, known as a **_jetwall_**. We need a way to keep track of every position a User has visited on the Grid so that we can check for collisions. It’s time to introduce another object that can store all of these position values. ## Arrays Interlude An **_array_** is a list of data that provides functions for reading, writing, searching, sorting, and many other useful tasks. We will get better acquainted with these objects in the next chapter. For now, let’s focus on the following functionality: **Figure 3.25 UML class diagram of `Array`** ``` // add figure ``` The following code snippet creates an array that contains string **_elements_** representing the first five letters of the Greek alphabet: ```javascript let alphabet = ['α', 'β', 'γ', 'δ', 'ε'] ``` You can also add elements to the end of an array by calling its `push()` function like so: ```javascript alphabet.push('ζ') ``` Let’s do a quick before-and-after comparison. **Example 3.23 Displaying string arrays** OK, we can create arrays and add elements to them. Now let’s turn to the task of working with individual array elements. We can quickly iterate over the elements of an array using a `for…of` statement as in the following code snippet: ```javascript let alphabet = ['α', 'β', 'γ', 'δ', 'ε'] for (let a of alphabet) { if (a === 'ε') { text("Epsilon is here!", 100, 100) } } ``` This loop syntax starts from the beginning of the alphabet array and assigns each element to the variable `a` one at time. Let’s see `for…of` in action alongside a traditional `for` loop. **Example 3.24 Constellation generator** ** Exercise 3.22** Revisit your meteor sketch from Chapter 1 and turn it into a meteor shower using vectors, noise, and arrays. ## Light Cycles $ \alpha $ Now that we can store `p5.Vector` objects in an array, we can keep track of a User’s jetwall as they roam the Grid. The most recent iteration of our Light Cycles game is missing three key components that we can incorporate quickly. First, we need an empty array to keep track of each `position` the User visits. ```javascript let jetWall = [] ``` Next, we need to add each `position` to the `jetWall` array. The `position` variable is constantly changing, so we’ll call its `copy()` function to take a snapshot. ```javascript let gridCell = position.copy() jetWall.push(gridCell) ``` And finally, we need to iterate over the `jetWall` array to determine whether or not the User has collided with a previous `position`. We can call the `equals()` function to compare `position` to each `gridCell` in the `jetWall`. ```javascript for (let gridCell of jetWall) { if (position.equals(gridCell)) { gameOver = true } } ``` OK, let’s integrate all of these components into the next iteration of the game. ```{panels} :column: col-12 :card: border-2 **** **System:** A simulation environment in the Tron computer system where Users ride vehicles called light cycles. ``` ```{panels} :column: col-12 :card: border-2 **$ \mapsto $** **Model:** The Grid is an empty, two-dimensional surface that is $ 200 $ pixels wide and $ 200 $ pixels high. A light cycle is a point of light that travels up, left, down, or right. ``` ```{panels} :column: col-12 :card: border-2 **** **Data:** The User’s `position` and `velocity` vectors are `p5.Vector` objects. The initial values of these vectors are $ \vec{p} = (100,100) $ and $ \vec{v} = (1,0) $, respectively. ``` ```{panels} :column: col-12 :card: border-2 **** **Algorithm:** First, update `velocity` by checking for key presses. Then update `position` by adding `velocity`. After that, check to see if the User’s light cycle is destroyed due to a collision with the edge of the Grid or a jetwall. Finally, draw a point at the User’s `position`. ``` **Example 3.24 Jetwalls** ** Exercise 3.23** Display the User’s score at the end of the game. You can access the length of an array using the dot operator as in `jetWall.length`. ** Exercise 3.24** Add a second User and display the winner’s score at the end of the game. It’s been quite a ride, but you now have a solid foundation with functions. These building blocks enable us to design and reason about complex systems piece by piece. The functions introduced in the next chapter are guaranteed to set your world spinning.

--- *Tron*, *Light Cycles*, and other terms referenced from the film are © Walt Disney Studios. Their use in this chapter is educational and thus considered fair use. --- # Reference - [*The Nature of Code*](https://natureofcode.com) / Introduction and Chapter 1 - [*Precalculus*](https://openstax.org/details/books/precalculus) / Chapters 1 and 2