Skip to content

Commit

Permalink
Merge pull request #865 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 Feb 27, 2024
2 parents dcf7057 + 6e133b9 commit 30941a6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 30 deletions.
16 changes: 10 additions & 6 deletions content/02_forces.html
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,11 @@ <h3 id="example-21-forces">Example 2.1: Forces</h3>
}
}
}</pre>
<p>Now that the class is written, I can create more than one <code>Mover</code> object.</p>
<pre class="codesplit" data-code-language="javascript">let moverA = new Mover();
<div class="avoid-break">
<p>Now that the class is written, I can create more than one <code>Mover</code> object.</p>
<pre class="codesplit" data-code-language="javascript">let moverA = new Mover();
let moverB = new Mover();</pre>
</div>
<p>But there’s an issue. Look again at the <code>Mover</code> object’s constructor:</p>
<pre class="codesplit" data-code-language="javascript">constructor() {
//{!2} Every object has a mass of 1 and a position of (width / 2, 30).
Expand Down Expand Up @@ -791,10 +793,12 @@ <h3 id="gravitational-attraction">Gravitational Attraction</h3>
<pre class="codesplit" data-code-language="javascript">// Made-up force
let force = createVector(0, 0.1);
mover.applyForce(force);</pre>
<p>I now have this:</p>
<pre class="codesplit" data-code-language="javascript">//{!1} Attraction force between two objects
<div class="avoid-break">
<p>I now have this:</p>
<pre class="codesplit" data-code-language="javascript">//{!1} Attraction force between two objects
<strong>let force = attractor.attract(mover);</strong>
mover.applyForce(force);</pre>
</div>
<p>And so the <code>draw()</code> function can be written as shown here:</p>
<pre class="codesplit" data-code-language="javascript">function draw() {
background(255);
Expand Down Expand Up @@ -1015,8 +1019,8 @@ <h3 id="exercise-214">Exercise 2.14</h3>
}
}</pre>
<p>The <code>draw()</code> function is where I need to work some magic so that every body exerts a gravitational force on every other body. Right now, the code reads, “For every body <code>i</code>, update and draw.” To attract every other body <code>j</code> with each body <code>i</code>, I need to nest a second loop and adjust the code to say, “For every body <code>i</code>, attract every other body <code>j</code> (and update and draw).”</p>
<pre class="codesplit" data-code-language="javascript"> for (let i = 0; i &#x3C; bodies.length; i++) {
// For every body, check every body!
<pre class="codesplit" data-code-language="javascript"> //{!2} For every body, check every body!
for (let i = 0; i &#x3C; bodies.length; i++) {
for (let j = 0; j &#x3C; bodies.length; j++) {
let force = bodies[j].attract(bodies[i]);
movers[i].applyForce(force);
Expand Down
3 changes: 1 addition & 2 deletions content/04_particles.html
Original file line number Diff line number Diff line change
Expand Up @@ -1084,15 +1084,14 @@ <h3 id="example-47-a-particle-system-with-a-repeller">Example 4.7: A Particle Sy
}

function draw() {
background(100);
background(255);
emitter.addParticle();
// Apply a universal gravity.
let gravity = createVector(0, 0.1);
emitter.applyForce(gravity);
//{!1} Apply the repeller.
emitter.applyRepeller(repeller);
emitter.run();

repeller.show();
}

Expand Down
30 changes: 8 additions & 22 deletions content/05_steering.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,13 @@ <h3 id="the-steering-force">The Steering Force</h3>
<p>While I encourage you to consider how other forces such as friction and drag could be combined with steering behaviors, I’m going to focus only on steering forces for the time being. As such, I can include the concept of maximum speed as a limiting factor in the force calculation. First, I need to add a property to the <code>Vehicle</code> class setting the maximum speed:</p>
<div class="snip-below">
<pre class="codesplit" data-code-language="javascript">class Vehicle {

constructor() {
this.position = createVector();
this.velocity = createVector();
this.acceleration = createVector();
// Maximum speed
this.maxspeed = ????;
}
</pre>
}</pre>
</div>
<p>Then, in the desired velocity calculation, I’ll scale according to maximum speed:</p>
<pre class="codesplit" data-code-language="javascript">let desired = p5.Vector.sub(target, this.position);
Expand All @@ -126,7 +124,6 @@ <h3 id="the-steering-force">The Steering Force</h3>
<p>In all this excitement, I’ve missed one last step. What sort of vehicle is this? Is it a super-sleek race car with amazing handling? Or a large city bus that needs a lot of advance notice to turn? A graceful panda or a lumbering elephant? The example code, as it stands, has no feature to account for this variation in steering ability. For that, I need to limit the magnitude of the steering force. I’ll call this limit the maximum force (or <code>maxforce</code> for short):</p>
<div class="snip-below">
<pre class="codesplit" data-code-language="javascript">class Vehicle {

constructor() {
this.position = createVector();
this.velocity = createVector();
Expand All @@ -143,10 +140,8 @@ <h3 id="the-steering-force">The Steering Force</h3>
let desired = p5.Vector.sub(target, this.position);
desired.setMag(this.maxspeed);
let steer = p5.Vector.sub(desired, this.velocity);

//{!1} Limit the magnitude of the steering force.
steer.limit(this.maxforce);

this.applyForce(steer);
}</pre>
</div>
Expand Down Expand Up @@ -684,7 +679,7 @@ <h3 id="example-55-creating-a-path-object">Example 5.5: Creating a Path Object</
this.end = createVector(width, (2 * height) / 3);
}

//{!7} Display the path.
//{!1} Display the path.
show() {
strokeWeight(this.radius * 2);
stroke(0, 100);
Expand All @@ -702,10 +697,8 @@ <h3 id="example-55-creating-a-path-object">Example 5.5: Creating a Path Object</
<p>The first step is to predict (assuming a constant velocity) where that vehicle will be in the future:</p>
<pre class="codesplit" data-code-language="javascript">// Start by making a copy of the velocity.
let future = vel.copy();

//{!2} Look 25 pixels ahead by setting the magnitude.
// Look 25 pixels ahead by setting the magnitude.
future.setMag(25);

// Add the vector to the position to find the future position.
future.add(this.position);</pre>
<p>Once I have that position, it’s time to determine the distance from that predicted position to the path. If it’s very far away, the vehicle has strayed from the path and needs to steer back toward it. If the vehicle is on the path, all is well and the vehicle can continue on its way.</p>
Expand Down Expand Up @@ -745,12 +738,10 @@ <h3 id="example-55-creating-a-path-object">Example 5.5: Creating a Path Object</
<p>Or, more simply:</p>
<div data-type="equation">\vec{A}\cdot\vec{B}=||\vec{A}||\times\cos(\theta)</div>
<p>When <span data-type="equation">\vec{B}</span> is a unit vector, <span data-type="equation">||\vec{A}|| \times \cos(\theta)</span> is the same as the dot product of <span data-type="equation">\vec{A}</span> and <span data-type="equation">\vec{B}</span>. Turning <code>b</code> into a unit vector is as simple as calling <code>normalize()</code>. I can therefore bypass calculating <code>theta</code> with <code>angleBetween()</code> and simplify the code as follows:</p>
<pre class="codesplit" data-code-language="javascript">//{{!3} .line-through}
let theta = p5.Vector.angleBetween(a, b);
<pre class="codesplit" data-code-language="javascript"><s>let theta = p5.Vector.angleBetween(a, b);
let d = a.mag() * cos(theta);
b.setMag(d);

// Normalize <code>b</code> and use the dot product to set <code>b</code>’s length.
b.setMag(d);</s><s>
</s>//{!2} Normalize <code>b</code> and use the dot product to set <code>b</code>’s length.
b.normalize();
b.setMag(a.dot(b));
let normalPoint = p5.Vector.add(path.start, b);</pre>
Expand Down Expand Up @@ -1196,9 +1187,8 @@ <h3 id="combining-behaviors">Combining Behaviors</h3>
let steer = p5.Vector.sub(desired, this.velocity);
steer.limit(this.maxforce);

//{!1 .line-through}
this.applyForce(steer);
//{!1} Instead of applying the force, return the vector.
<s>this.applyForce(steer);</s><s>
</s> //{!1} Instead of applying the force, return the vector.
return steer;
}</pre>
<p>This change is subtle but incredibly important: it allows the strength of these forces to be weighted all in one place.</p>
Expand Down Expand Up @@ -1252,12 +1242,10 @@ <h3 id="flocking">Flocking</h3>
let separation = this.separate(boids);
let alignment = this.align(boids);
let cohesion = this.cohere(boids);

//{!3} Arbitrary weights for these forces (try different ones!)
separation.mult(1.5);
alignment.mult(1.0);
cohesion.mult(1.0);

//{!3} Apply all the forces.
this.applyForce(separation);
this.applyForce(alignment);
Expand All @@ -1272,10 +1260,8 @@ <h3 id="flocking">Flocking</h3>
sum.add(other.velocity);
}
sum.div(boids.length);

// The vehicle desires to go in that direction at maximum speed.
sum.setMag(this.maxspeed);

//{!3} Reynolds’s steering force formula
let steer = p5.Vector.sub(sum, this.velocity);
steer.limit(this.maxforce);
Expand Down

0 comments on commit 30941a6

Please sign in to comment.