Skip to content

Commit

Permalink
Merge pull request #329 from nature-of-code/notion-update-docs
Browse files Browse the repository at this point in the history
[Notion] Update docs
  • Loading branch information
shiffman authored Jun 9, 2023
2 parents a895606 + ac2328f commit 3c7cd5e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 66 deletions.
5 changes: 4 additions & 1 deletion content/02_forces.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
<h1 id="chapter-2-forces">Chapter 2. Forces</h1>
<p>In the final example of Chapter 1, I demonstrated how to calculate a dynamic acceleration based on a vector pointing from a circle on the canvas to the mouse position. The resulting motion resembled a magnetic attraction between shape and mouse, as if some <em>force</em> was pulling the circle in toward the mouse. In this chapter, I’ll detail the concept of a force and its relationship to acceleration. The goal, by the end of this chapter, is to build a simple physics engine and understand how objects move around a canvas responding to a variety of environmental forces.</p>
<div data-type="note">
<h3 id="a-physics-engine-is-a-computer-program-or-code-library-that-simulates-the-behavior-of-objects-in-a-physical-environment-in-our-case-the-objects-are-two-dimensional-shapes-and-the-environment-is-a-rectangular-canvas-physics-engines-can-be-developed-to-be-highly-precise-requiring-high-performance-computing-or-real-time-using-simple-and-fast-algorithms">A physics engine is a computer program (or code library) that simulates the behavior of objects in a physical environment. In our case, the objects are two-dimensional shapes, and the environment is a rectangular canvas. Physics engines can be developed to be highly precise (requiring high-performance computing) or real-time (using simple and fast algorithms).</h3>
<h3 id="----what-is-a-physics-engine----a-physics-engine-is-a-computer-program-or-code-library-that-simulates-the-behavior-of-objects-in-a-physical-environment-in-our-case-the-objects-are-two-dimensional-shapes-and-the-environment-is-a-rectangular-canvas-physics-engines-can-be-developed-to-be-highly-precise-requiring-high-performance-computing-or-real-time-using-simple-and-fast-algorithms--">
What is a physics engine?
A physics engine is a computer program (or code library) that simulates the behavior of objects in a physical environment. In our case, the objects are two-dimensional shapes, and the environment is a rectangular canvas. Physics engines can be developed to be highly precise (requiring high-performance computing) or real-time (using simple and fast algorithms).
</h3>
</div>
<h2 id="forces-and-newtons-laws-of-motion">Forces and Newton’s Laws of Motion</h2>
<p>Let’s begin by taking a conceptual look at what it means to be a force in the real world. Just like the word “vector,” the term “force” can have a variety of meanings. It can indicate a powerful physical intensity, as in “They pushed the boulder with great force,” or a powerful influence, as in “They’re a force to be reckoned with!” The definition of <strong><em>force</em></strong> that I’m interested in for this chapter is more formal and comes from Sir Isaac Newton’s three laws of motion:</p>
Expand Down
39 changes: 19 additions & 20 deletions content/03_oscillation.html
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ <h2 id="properties-of-oscillation">Properties of Oscillation</h2>
<figcaption></figcaption>
</figure>
<p>This pattern of oscillating back and forth around a central point is known as <strong><em>simple harmonic motion</em></strong> (or, to be fancier, “the periodic sinusoidal oscillation of an object”). The code to achieve it is remarkably simple, but before I get into it, I’d like to introduce some of the key terminology related to oscillation (and waves).</p>
<p>Simple harmonic motion can be expressed as any position (in this case, the <span data-type="equation">x</span> position) as a function of time, with the following two elements:</p>
<p>When a moving object exhibits simple harmonic motion, its position (in this case, the <span data-type="equation">x</span> position) can be expressed as a function of time, with the following two elements:</p>
<ul>
<li><strong><em>Amplitude</em></strong>: The distance from the center of motion to either extreme</li>
<li><strong><em>Period</em></strong>: The duration (time) for one complete cycle of motion</li>
Expand Down Expand Up @@ -699,7 +699,7 @@ <h2 id="trigonometry-and-forces-the-pendulum">Trigonometry and Forces: The Pendu
</figure>
<p></p>
<p>When the pendulum swings, its arm and bob are essentially rotating around the fixed point of the pivot. Its motion can therefore be described in terms of <em>angular</em> acceleration and velocity, the change of the arm’s angle <span data-type="equation">\theta</span> relative to the pendulum’s resting position (see Figure 3.11). In Chapter 2, I discussed how forces cause an object to accelerate. Two main forces will contribute to my model pendulum’s angular acceleration vector.</p>
<p>The first force is gravity. As shown in Figure 3.11, this force is a vector that points straight down. If there were no arm connecting the bob and the pivot, the bob would simply fall to the ground under the influence of this force. Obviously, that isn’t what happens. Instead, the fixed length of the arm creates the second force—tension. Combined together, the resulting net force (which I’ll denote as <span data-type="equation">F_p</span> (see Figure 3.12) points toward the pendulum’s resting position, perpendicular to the arm. Together, this net pendulum force, the result of gravity and tension, causes the pendulum swing back and forth.</p>
<p>The first force is gravity. As shown in Figure 3.11, this force is a vector that points straight down. If there were no arm connecting the bob and the pivot, the bob would simply fall to the ground under the influence of this force. Obviously, that isn’t what happens. Instead, the fixed length of the arm creates the second force—tension. Combined together, the resulting net force (which I’ll denote as <span data-type="equation">F_p</span> (see Figure 3.12) points toward the pendulum’s resting position, perpendicular to the arm. This net pendulum force, the result of gravity and tension, causes the pendulum swing back and forth.</p>
<p>To actually calculate the pendulum’s angular acceleration, I’m going to use Newton’s second law of motion, but with a little trigonometric twist. The key is to recognize the relationship between the gravity and the net pendulum force, as shown in Figure 3.12.</p>
<figure>
<img src="images/03_oscillation/03_oscillation_12.png" alt="Figure 3.12: A diagram of pendulum showing \sin(\theta) = F_p / F_g">
Expand Down Expand Up @@ -759,7 +759,7 @@ <h2 id="trigonometry-and-forces-the-pendulum">Trigonometry and Forces: The Pendu
<pre class="codesplit" data-code-language="javascript">this.r = 125;</pre>
<p>I also know the bob’s current angle relative to the pivot: it’s stored in the variable <code>angle</code>. Between the arm length and the angle, what I have is a polar coordinate for the bob: <span data-type="equation">(r,\theta)</span>. What I really need is a Cartesian coordinate, but luckily I already know how to use sine and cosine to convert from polar to Cartesian. And so:</p>
<pre class="codesplit" data-code-language="javascript">this.bob = createVector(r * sin(this.angle), r * cos(this.angle));</pre>
<p>Notice that I’m using <code>sin(this.angle)</code> for the <span data-type="equation">x</span> value and <code>cos(this.angle)</code> for the <span data-type="equation">y</span>. This is the opposite of what I showed you in the “Polar vs. Cartesian Coordinates” section earlier in the chapter. The reason for this is that I’m now looking for the top angle of a right triangle pointing down, as depicted in Figure 3.13. This angle lives between the y-axis and the hypotenuse, instead of the angle between the x-axis and the hypotenuse, as you saw earlier in Figure 3.8.</p>
<p>Notice that I’m using <code>sin(this.angle)</code> for the <span data-type="equation">x</span> value and <code>cos(this.angle)</code> for the <span data-type="equation">y</span>. This is the opposite of what I showed you in the “Polar vs. Cartesian Coordinates” section earlier in the chapter. The reason for this is that I’m now looking for the top angle of a right triangle pointing down, as depicted in Figure 3.13. This angle lives between the y-axis and the hypotenuse, instead of between the x-axis and the hypotenuse, as you saw earlier in Figure 3.8.</p>
<p>Right now, the value of <code>this.bob</code> is assuming that the pivot is at point (0, 0). To get the bob’s position relative to wherever the pivot <em>actually</em> happens to be, I can just add <code>pivot</code> to the <code>bob</code> vector:</p>
<pre class="codesplit" data-code-language="javascript">this.bob.add(this.pivot);</pre>
<p>Now all that remains is the little matter of drawing a line and circle (you should be more creative, of course).</p>
Expand All @@ -769,7 +769,7 @@ <h2 id="trigonometry-and-forces-the-pendulum">Trigonometry and Forces: The Pendu
circle(this.position.x, this.position.y, 16);</pre>
<p>Before I put everything together, there’s one last little detail I neglected to mention. Or really, lots of little details. Think about the pendulum arm for a moment. Is it a metal rod? A string? A rubber band? How is it attached to the pivot point? How long is it? What’s its mass? Is it a windy day? There are a lot of questions that I could continue to ask that would affect the simulation. I choose to live, however, in a fantasy world, one where the pendulum’s arm is some idealized rod that never bends and where the mass of the bob is concentrated in a single, infinitesimally small point.</p>
<p>Even though I prefer not to worry myself with all of these questions, there’s a critical missing piece here related to the calculation of angular acceleration. To keep things simple, in the derivation of the pendulum’s acceleration, I assumed that the length of the pendulum’s arm is 1. In reality, however, the length of the pendulum’s arm affects the acceleration of the pendulum due to the concepts of torque and moment of inertia. <strong><em>Torque</em></strong> is a measure of the rotational force acting on an object. In the case of a pendulum, torque is proportional to both the mass and the length of the arm (<span data-type="equation">M \times r</span>). The <strong><em>moment of inertia</em></strong> of a pendulum is a measure of how difficult it is to rotate the pendulum around the pivot point. It’s proportional to the square of the length of the arm (<span data-type="equation">r^2</span>).</p>
<p>By dividing the torque by the moment of inertia (<span data-type="equation">Mr / r^2 ⇒ M / r</span>), I can calculate the angular acceleration of the pendulum more accurately. In fact, I can continue to ignore mass, as it has no actual effect on the acceleration: it scales the force of gravity, which contributes to the force of the pendulum (<span data-type="equation">F_p)</span>, but it also divides the force of the pendulum (<span data-type="equation">A = F_p / M</span>) to calculate the acceleration. (This is the same reason different objects dropped from the Leaning Tower of Pisa fall at the same rate, as discussed in Chapter 2.) Therefore, setting aside mass, all that’s left is to divide by <code>r</code>. (For a more involved explanation, visit <a href="http://calculuslab.deltacollege.edu/ODE/7-A-2/7-A-2-h.html">The Simple Pendulum website</a>.)</p>
<p>By dividing the torque by the moment of inertia (<span data-type="equation">Mr / r^2 ⇒ M / r</span>), I can calculate the angular acceleration of the pendulum more accurately. In fact, I can continue to ignore mass, as it has no actual effect on the acceleration: it scales the force of gravity, which contributes to the force of the pendulum (<span data-type="equation">F_p)</span>, but it also divides the force of the pendulum (<span data-type="equation">A = F_p / M</span>) to calculate the acceleration. (This is the same reason different objects dropped from the Leaning Tower of Pisa fall at the same rate, as discussed in Chapter 2.) Therefore, setting aside mass, all that’s left is to divide by <code>r</code>. (For a more involved explanation, visit the <a href="http://calculuslab.deltacollege.edu/ODE/7-A-2/7-A-2-h.html">"Simple Pendulum" article</a> linked from the book’s website.)</p>
<pre class="codesplit" data-code-language="javascript">// Same formula as before but now dividing by r
this.angleAcceleration = (-1 * gravity * sin(this.angle)) / r;</pre>
<p>Finally, a real-world pendulum is going to experience some amount of friction (at the pivot point) and air resistance. As it stands, the pendulum would swing forever with the given code. To make it more realistic, I can slow the pendulum down with a "damping" trick. I say <em>trick</em> because rather than model the resistance forces with some degree of accuracy (as I did in Chapter 2), I can achieve a similar result simply by reducing the angular velocity by some arbitrary amount during each cycle. The following code reduces the velocity by 1 percent (or multiplies it by 0.99) each frame of animation:</p>
Expand Down Expand Up @@ -823,7 +823,7 @@ <h3 id="example-310-swinging-pendulum">Example 3.10: Swinging Pendulum</h3>
}

show() {
//{!1} Where is the bob relative to the origin? Polar to Cartesian coordinates will tell us!
//{!1} Applying polar to cartesian conversion. Instead of creating a new vector each time, I'll use set() to update the bob's position.
this.bob.set(this.r * sin(this.angle), this.r * cos(this.angle));
this.bob.add(this.pivot);

Expand All @@ -836,7 +836,7 @@ <h3 id="example-310-swinging-pendulum">Example 3.10: Swinging Pendulum</h3>
circle(this.bob.x, this.bob.y, this.ballr * 2);
}
}</pre>
<p><em>(Note that the version of the example posted on the website has additional code to allow the user to grab the pendulum and swing it with the mouse.)</em></p>
<p>Note that the version of the example posted on the book’s website has additional code to allow the user to grab the pendulum and swing it with the mouse.</p>
<div data-type="exercise">
<h3 id="exercise-312">Exercise 3.12</h3>
<p>String together a series of pendulums so that the bob of one is the pivot point of another. Note that doing this may produce intriguing results but will be wildly inaccurate physically. Simulating an actual double pendulum involves sophisticated equations. You can read about them in the <a href="https://scienceworld.wolfram.com/physics/DoublePendulum.html">Wolfram Research article on double pendulums</a> or watch my video on coding a double pendulum (<a href="https://thecodingtrain.com/challenges/93-double-pendulum">Coding Train Challenge #93</a>).</p>
Expand All @@ -851,7 +851,7 @@ <h3 id="exercise-313">Exercise 3.13</h3>
<img src="images/03_oscillation/03_oscillation_14.png" alt=" ">
<figcaption> </figcaption>
</figure>
<p>Using trigonometry, how do you calculate the magnitude of the <strong><em>normal force</em></strong> depicted here (the force perpendicular to the incline on which the sled rests)? You can consider the magnitude of <span data-type="equation">F_\text{gravity}</span> to be a known constant. Look for a right triangle to help get you started, after all, the “normal” force is a component of the force of gravity. If it helps to draw over the diagram and make more right triangles, go for it!</p>
<p>Using trigonometry, how do you calculate the magnitude of the <strong><em>normal force</em></strong> depicted here (the force perpendicular to the incline on which the sled rests)? You can consider the magnitude of <span data-type="equation">F_\text{gravity}</span> to be a known constant. Look for a right triangle to help get you started. After all, the “normal” force is a component of the force of gravity. If it helps to draw over the diagram and make more right triangles, go for it!</p>
<figure>
<img src="images/03_oscillation/03_oscillation_15.png" alt="">
<figcaption></figcaption>
Expand All @@ -876,8 +876,7 @@ <h2 id="spring-forces">Spring Forces</h2>
<p>The extension is a measure of how much the spring has been stretched or compressed: as shown in Figure 3.15, it’s the difference between the current length of the spring and the spring’s resting length (its equilibrium state). Hooke’s law therefore says that if you pull on the bob a lot, the spring’s force will be strong, whereas if you pull on the bob a little, the force will be weak. Mathematically, the law is stated as follows:</p>
<div data-type="equation">F_{spring} = -kx</div>
<p>Here <span data-type="equation">k</span> is the “spring constant.” Its value scales the force, setting how elastic or rigid the spring is. Meanwhile, <span data-type="equation">x</span> is the extension, the current length minus the rest length.</p>
<p>Now remember, force is a vector, so you need to calculate both magnitude and direction.</p>
<p>For the code, I‘ll start with the following three variables, two vectors for the anchor and bob positions and one rest length.</p>
<p>Now remember, force is a vector, so you need to calculate both magnitude and direction. For the code, I‘ll start with the following three variables: two vectors for the anchor and bob positions, and one rest length.</p>
<pre class="codesplit" data-code-language="javascript">// Picking arbitrary values for the positions and rest length
let anchor = createVector(0, 0);
let bob = createVector(0, 120);
Expand Down Expand Up @@ -1015,23 +1014,23 @@ <h3 id="example-311-a-spring-connection">Example 3.11: A Spring connection</h3>
<div data-type="exercise">
<h3 id="exercise-315">Exercise 3.15</h3>
<p>Before running to see the example online, take a look at this <code>constrainLength</code> method and see if you can fill in the blanks.</p>
<pre class="codesplit" data-code-language="javascript">constrainLength(b, minlen, maxlen) {
<pre class="codesplit" data-code-language="javascript">constrainLength(bob, minlen, maxlen) {
//{!1} Vector pointing from Bob to Anchor
let dir = p5.Vector.sub(______,______);
let d = dir.mag();
let direction = p5.Vector.sub(bob.position, this.anchor);
let length = direction.mag();

//{!1} Is it too short?
if (d &#x3C; minlen) {
dir.setMag(________);
if (length &#x3C; minlen) {
direction.setMag(minlen);
//{!1} Keep position within constraint.
b.position = p5.Vector.add(______, ______);
b.velocity.mult(0);
bob.position = p5.Vector.add(this.anchor, direction);
bob.velocity.mult(0);
//{!1} Is it too long?
} else if (____________) {
dir.setMag(_________);
} else if (length > maxlen) {
direction.setMag(maxlen);
//{!1} Keep position within constraint.
b.position = p5.Vector.add(______, ______);
b.velocity.mult(0);
bob.position = p5.Vector.add(this.anchor, direction);
bob.velocity.mult(0);
}
}</pre>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,24 @@ function setup() {
bob = new Bob(width / 2, 100);
}


function draw() {
background(255);

// Apply a gravity force to the bob
let gravity = createVector(0, 2);
bob.applyForce(gravity);


// Update bob
bob.update();
bob.handleDrag(mouseX, mouseY);

// Connect the bob to the spring (this calculates the force)
spring.connect(bob);

// Constrain spring distance between min and max
spring.constrainLength(bob, 30, 200);

// Update bob
bob.update();

// Draw everything
spring.showLine(bob); // Draw a line between spring and bob
bob.show();
Expand All @@ -42,10 +44,6 @@ function mousePressed() {
bob.handleClick(mouseX, mouseY);
}

function mouseDragged() {
bob.handleDrag(mouseX, mouseY);
}

function mouseReleased() {
bob.stopDragging();
}
}
Loading

0 comments on commit 3c7cd5e

Please sign in to comment.