Skip to content

Commit

Permalink
Notion - Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
shiffman committed Feb 12, 2024
1 parent 7e3f646 commit b077a69
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 30 deletions.
8 changes: 6 additions & 2 deletions content/00_randomness.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,15 @@ <h3 id="example-01-a-traditional-random-walk">Example 0.1: A Traditional Random
this.y += ystep;
}</pre>
<p>Taking this further, I could get rid of <code>floor()</code> and use the <code>random()</code> function’s original floating-point numbers to create a continuous range of possible step lengths from –1 to 1:</p>
<pre class="codesplit" data-code-language="javascript"> step() {
<div class="avoid-break">
<pre class="codesplit" data-code-language="javascript"> step() {
//{!2} Any floating-point number from –1 to 1
let xstep = random(–1, 1);
let ystep = random(–1, 1);
this.x += xstep;
this.y += ystep;
}</pre>
</div>
<p>All of these variations on the traditional random walk have one thing in common: at any moment in time, the probability that the walker will take a step in a given direction is equal to the probability that the walker will take a step in any other direction. In other words, if there are four possible steps, there is a 1 in 4 (or 25 percent) chance the walker will take any given step. With nine possible steps, it’s a 1 in 9 chance (about 11.1 percent).</p>
<p>Conveniently, this is how the <code>random()</code> function works. p5.js’s random-number generator (which operates behind the scenes) produces a <strong>uniform distribution</strong> of numbers. You can test this distribution by counting each time a random number is picked and graphing those values.</p>
<div data-type="example">
Expand Down Expand Up @@ -248,7 +250,8 @@ <h3 id="exercise-02">Exercise 0.2</h3>
<li>From 0.6 to 0.7 (10 percent) → Dancing</li>
<li>From 0.7 to 1.0 (30 percent) → Sleeping</li>
</ul>
<pre class="codesplit" data-code-language="javascript">let num = random(1);
<div class="avoid-break">
<pre class="codesplit" data-code-language="javascript">let num = random(1);

// If the random number is less than 0.6
if (num &#x3C; 0.6) {
Expand All @@ -260,6 +263,7 @@ <h3 id="exercise-02">Exercise 0.2</h3>
} else {
print("Sleep!");
}</pre>
</div>
<p>Now let’s apply this methodology to the random walker so it tends to move in a particular direction. Here’s an example of a <code>Walker</code> object with the following probabilities:</p>
<ul>
<li>Chance of moving up: 20 percent</li>
Expand Down
22 changes: 12 additions & 10 deletions content/02_forces.html
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,18 @@ <h3 id="parsing-formulas">Parsing Formulas</h3>
</ul>
</div>
<p>Open up any high school physics textbook and you’ll find diagrams and formulas describing various forces—gravity, electromagnetism, friction, tension, elasticity, and more. For the rest of this chapter, I’m going to consider three forces—friction, drag, and gravitational attraction—and show how to model them with p5.js. The point I’d like to make here is not that these are fundamental forces that you always need in your simulations. Rather, I want to demonstrate these forces as case studies for the following process:</p>
<ol>
<li>Understanding the concept behind a force</li>
<li>Deconstructing the force’s formula into two parts:
<ol>
<li>How do you compute the force’s direction?</li>
<li>How do you compute the force’s magnitude?</li>
</ol>
</li>
<li>Translating that formula into p5.js code that calculates a vector to be passed through a <code>Mover</code> object’s <code>applyForce()</code> method</li>
</ol>
<div class="avoid-break">
<ol>
<li>Understanding the concept behind a force</li>
<li>Deconstructing the force’s formula into two parts:
<ol>
<li>How do you compute the force’s direction?</li>
<li>How do you compute the force’s magnitude?</li>
</ol>
</li>
<li>Translating that formula into p5.js code that calculates a vector to be passed through a <code>Mover</code> object’s <code>applyForce()</code> method</li>
</ol>
</div>
<p>If you can follow these steps with the example forces I’ll provide here, then hopefully when you find yourself googling <em>atomic nuclei weak nuclear force</em> at 3 AM, you’ll have the skills to take what you find and adapt it for p5.js.</p>
<h3 id="friction">Friction</h3>
<p>Let’s begin with friction and follow the preceding steps. Whenever two surfaces come into contact, they experience <strong>friction</strong>. Friction is a <strong>dissipative force</strong>, meaning it causes the kinetic energy of an object to be converted into another form, giving the impression of loss, or dissipation.</p>
Expand Down
4 changes: 2 additions & 2 deletions content/03_oscillation.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ <h2 id="angles">Angles</h2>
</figure>
</div>
<p>The catch is that, by default, p5.js measures angles not in degrees but in <strong>radians</strong>. This alternative unit of measurement is defined by the ratio of the length of the arc of a circle (a segment of the circle’s circumference) to the radius of that circle. One radian is the angle at which that ratio equals 1 (see Figure 3.3). A full circle (360 degrees) is equivalent to <span data-type="equation">2\pi</span> radians, 180 degrees is equivalent to <span data-type="equation">\pi</span> radians, and 90 degrees is equivalent to <span data-type="equation">\pi/2</span> radians.</p>
<p>The formula to convert from degrees to radians is as follows:</p>
<div data-type="equation">\text{radians} = {2\pi \times \text{degrees} \over 360}</div>
<div data-type="note">
<h3 id="what-is-pi">What Is Pi?</h3>
<p>The mathematical constant <strong>pi</strong> (or the Greek letter <span data-type="equation">\pi</span>) is a real number defined as the ratio of a circle’s circumference (the distance around the outside of the circle) to its diameter (a straight line that passes through the circle’s center). It’s equal to approximately 3.14159 and can be accessed in p5.js with the built-in <code>PI</code> variable.</p>
</div>
<p>The formula to convert from degrees to radians is as follows:</p>
<div data-type="equation">\text{radians} = {2\pi \times \text{degrees} \over 360}</div>
<p>Thankfully, if you prefer to think of angles in degrees, you can call <code>angleMode(DEGREES)</code>, or you can use the convenience function <code>radians()</code> to convert values from degrees to radians. The constants <code>PI</code>, <code>TWO_PI</code>, and <code>HALF_PI</code> are also available (equivalent to 180, 360, and 90 degrees, respectively). For example, here are two ways in p5.js to rotate a shape by 60 degrees:</p>
<pre class="codesplit" data-code-language="javascript">let angle = 60;
rotate(radians(angle));
Expand Down
18 changes: 10 additions & 8 deletions content/06_libraries.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h3 id="living-root-bridges-photo-by-arshiya-urveeja-bose">Living root bridges (
<p>These activities have yielded a set of motion simulations, allowing you to creatively define the physics of the worlds you build (whether realistic or fantastical). But, of course, you and I aren’t the first or only people to do this. The world of computer graphics and programming is full of prewritten code libraries dedicated to physics simulations.</p>
<p>Just try searching <em>open source physics engine</em> and you could spend the rest of your day poring over a host of rich and complex codebases. This begs the question: If an existing code library takes care of physics simulation, why should you bother learning how to write any of the algorithms yourself? Here’s where the philosophy behind this book comes into play. While many libraries provide out-of-the-box physics to experiment with (super-awesome, sophisticated, and robust physics at that), there are several good reasons for learning the fundamentals from scratch before diving into such libraries.</p>
<p>First, without an understanding of vectors, forces, and trigonometry, it’s easy to get lost just reading the documentation of a library, let alone using it. Second, even though a library may take care of the math behind the scenes, it won’t necessarily simplify your code. A great deal of overhead may be required in understanding how a library works and what it expects from you code-wise. Finally, as wonderful as a physics engine might be, if you look deep down into your heart, you’ll likely see that you seek to create worlds and visualizations that stretch the limits of the imagination. A library may be great, but it provides only a limited set of features. It’s important to know when to live within those limitations in the pursuit of a creative coding project and when those limits will prove to be confining.</p>
<p>This chapter is dedicated to examining two open source physics libraries for JavaScript: <a href="https://brm.io/matter-js">Matter.js</a> and <a href="http://haptic-data.com/toxiclibsjs">Toxiclibs.js</a>. I don’t mean to imply that these are the only libraries you should use for any and all creative coding projects that could benefit from a physics engine (see <a href="#allow-break-other-physics-libraries">“Other Physics Libraries”</a> for alternatives, and check the book’s website for ports of the chapter’s examples to other libraries). However, both libraries integrate nicely with p5.js and will allow me to demonstrate the fundamental concepts behind physics engines and how they relate to and build upon the material I’ve covered so far.</p>
<p>This chapter is dedicated to examining two open source physics libraries for JavaScript: <a href="https://brm.io/matter-js">Matter.js</a> and <a href="http://haptic-data.com/toxiclibsjs">Toxiclibs.js</a>. I don’t mean to imply that these are the only libraries you should use for any and all creative coding projects that could benefit from a physics engine (see <a href="#other-physics-libraries">“Other Physics Libraries”</a> for alternatives, and check the book’s website for ports of the chapter’s examples to other libraries). However, both libraries integrate nicely with p5.js and will allow me to demonstrate the fundamental concepts behind physics engines and how they relate to and build upon the material I’ve covered so far.</p>
<p>Ultimately, the aim of this chapter isn’t to teach you the details of a specific physics library, but to provide you with a foundation for working with <em>any</em> physics library. The skills you acquire here will enable you to navigate and understand documentation, opening the door for you to expand your abilities with any library you choose.</p>
<h2 id="why-use-a-physics-library">Why Use a Physics Library?</h2>
<p>I’ve made the case for writing your own physics simulations (as you’ve learned to do in the previous chapters), but why use a physics library? After all, adding any external framework or library to a project introduces complexity and extra code. Is that additional overhead worth it? If you just want to simulate a circle falling down because of gravity, for example, do you really need to import an entire physics engine and learn its API? As the early chapters of this book hopefully demonstrated, probably not. Lots of scenarios like this are simple enough for you to get by writing the code yourself.</p>
Expand All @@ -46,13 +46,15 @@ <h2 id="why-use-a-physics-library">Why Use a Physics Library?</h2>
<p>That’s easy enough, but how about calculating the circles’ velocities after the collision? This is where I’m going to stop the discussion. Why, you ask? It’s not that understanding the math behind collisions isn’t important or valuable. (In fact, I’m including additional examples on the website related to collisions without a physics library.) The reason for stopping is that life is short! (Let this also be a reason for you to consider going outside and frolicking for a bit before sitting down to write your next sketch.) You can’t expect to master every detail of physics simulation. And while you might enjoy learning about collision resolution for circles, it’s only going to make you want to work with rectangles next. And then with strangely shaped polygons. And then curved surfaces. And then swinging pendulums colliding with springy springs. And then, and then, and then . . .</p>
<p>Incorporating complex features like collisions into a p5.js sketch while still having time to spend with friends and family—that’s the reason for this chapter. People have spent years developing solutions to these kinds of problems, and beautiful JavaScript libraries like Matter.js and Toxiclibs.js are the fruits of those efforts. You don’t need to reinvent the proverbial wheel, at least for now.</p>
<p>In conclusion, if you find yourself describing an idea for a p5.js sketch and the word <em>collisions</em> comes up, then it’s likely time to learn to use a physics engine.</p>
<div data-type="note">
<h3 id="allow-break-other-physics-libraries">allow-break Other Physics Libraries</h3>
<p>A multitude of other physics libraries are worth exploring alongside this chapter’s two case studies, each with unique strengths that may offer advantages in certain kinds of projects. In fact, when I first began writing this book, Matter.js didn’t exist, so the physics engine I initially used to demonstrate the examples was Box2D. It was (and likely still is) the most well-known physics engine of them all.</p>
<p><a href="https://box2d.org/">Box2D</a> began as a set of physics tutorials written in C++ by Erin Catto for the Game Developers Conference in 2006. Since then, Box2D has evolved into a rich and elaborate open source physics engine. It’s been used for countless projects, most notably highly successful games such as the award-winning <em>Crayon Physics</em> and the runaway hit <em>Angry Birds</em>.</p>
<p>One important feature of Box2D is that it’s a true physics engine: it knows nothing about computer graphics and the world of pixels, and instead does all its measurements and calculations in real-world units like meters, kilograms, and seconds. It’s just that its “world” (a key term in Box2D) is a 2D plane with top, bottom, left, and right edges. You tell it things like “The gravity of the world is 9.81 newtons per kilogram, and a circle with a radius of 4 meters and a mass of 50 kilograms is located 10 meters above the world’s bottom.” Box2D will then tell you things like “One second later, the rectangle is at 5 meters from the bottom; two seconds later, it’s 10 meters below,” and so on.</p>
<p>While this provides for an amazingly accurate and robust physics engine (one that’s highly optimized and fast for C++ projects), it also necessitates lots of complicated code to translate back and forth between Box2D’s physics world and the world you want to draw—the pixel world of the graphics canvas. This creates a tremendous burden for the coder. I will, as best I can, continue to maintain a set of Box2D-compatible examples for this book (there are several JavaScript ports), but I believe the relative simplicity of working with a library like Matter.js that is native to JavaScript and uses pixels as the unit of measurement will make for a more intuitive and friendly bridge from my p5.js examples.</p>
<p>Another notable library is <a href="https://p5play.org/">p5play</a>, a project initiated by Paolo Pedercini and currently led by Quinton Ashley that was specifically designed for game development. It simplifies the creation of visual objects—known as sprites—and manages their interactions (namely, collisions and overlaps). As you may have guessed from the name, p5play is tailored to work seamlessly with p5.js. It uses Box2D under the hood for physics simulation.</p>
<div class="allow-break">
<div data-type="note">
<h3 id="other-physics-libraries">Other Physics Libraries</h3>
<p>A multitude of other physics libraries are worth exploring alongside this chapter’s two case studies, each with unique strengths that may offer advantages in certain kinds of projects. In fact, when I first began writing this book, Matter.js didn’t exist, so the physics engine I initially used to demonstrate the examples was Box2D. It was (and likely still is) the most well-known physics engine of them all.</p>
<p><a href="https://box2d.org/">Box2D</a> began as a set of physics tutorials written in C++ by Erin Catto for the Game Developers Conference in 2006. Since then, Box2D has evolved into a rich and elaborate open source physics engine. It’s been used for countless projects, most notably highly successful games such as the award-winning <em>Crayon Physics</em> and the runaway hit <em>Angry Birds</em>.</p>
<p>One important feature of Box2D is that it’s a true physics engine: it knows nothing about computer graphics and the world of pixels, and instead does all its measurements and calculations in real-world units like meters, kilograms, and seconds. It’s just that its “world” (a key term in Box2D) is a 2D plane with top, bottom, left, and right edges. You tell it things like “The gravity of the world is 9.81 newtons per kilogram, and a circle with a radius of 4 meters and a mass of 50 kilograms is located 10 meters above the world’s bottom.” Box2D will then tell you things like “One second later, the rectangle is at 5 meters from the bottom; two seconds later, it’s 10 meters below,” and so on.</p>
<p>While this provides for an amazingly accurate and robust physics engine (one that’s highly optimized and fast for C++ projects), it also necessitates lots of complicated code to translate back and forth between Box2D’s physics world and the world you want to draw—the pixel world of the graphics canvas. This creates a tremendous burden for the coder. I will, as best I can, continue to maintain a set of Box2D-compatible examples for this book (there are several JavaScript ports), but I believe the relative simplicity of working with a library like Matter.js that is native to JavaScript and uses pixels as the unit of measurement will make for a more intuitive and friendly bridge from my p5.js examples.</p>
<p>Another notable library is <a href="https://p5play.org/">p5play</a>, a project initiated by Paolo Pedercini and currently led by Quinton Ashley that was specifically designed for game development. It simplifies the creation of visual objects—known as sprites—and manages their interactions (namely, collisions and overlaps). As you may have guessed from the name, p5play is tailored to work seamlessly with p5.js. It uses Box2D under the hood for physics simulation.</p>
</div>
</div>
<h2 id="importing-the-matterjs-library">Importing the Matter.js Library</h2>
<p>In a moment, I’ll turn to working with Matter.js, created by Liam Brummitt in 2014. But before you can use an external JavaScript library in a p5.js project, you need to import it into your sketch. As you’re already quite aware, I’m using the official p5.js web editor for developing and sharing this book’s code examples. The easiest way to add a library is to edit the <em>index.html</em> file that’s part of every new p5.js sketch created in the editor.</p>
Expand Down
Loading

0 comments on commit b077a69

Please sign in to comment.