mirror of
https://github.com/nature-of-code/noc-book-2
synced 2024-11-16 07:47:48 +01:00
Merge pull request #898 from nature-of-code/notion-update-docs
layout 5-9
This commit is contained in:
commit
1812f9f579
5 changed files with 12 additions and 7 deletions
|
@ -68,7 +68,7 @@
|
|||
<img src="images/05_steering/05_steering_2.png" alt="Figure 5.1: A vehicle with a velocity and a target">
|
||||
<figcaption>Figure 5.1: A vehicle with a velocity and a target</figcaption>
|
||||
</figure>
|
||||
<p>The vehicle’s goal and subsequent action is to seek the target. Thinking back to <a href="/forces#section-forces">Chapter 2</a>, you might begin by making the target an attractor and applying a gravitational force that pulls<br>the vehicle to the target. This would be a perfectly reasonable solution, but conceptually it’s not what I’m looking<br>for here.</p>
|
||||
<p>The vehicle’s goal and subsequent action is to seek the target. Thinking back to <a href="/forces#section-forces">Chapter 2</a>, you might begin by making the target an attractor and applying a gravitational force that pulls the vehicle to<br>the target. This would be a perfectly reasonable solution, but conceptually it’s not what I’m looking for here.</p>
|
||||
<p>I don’t want to simply calculate a force that pushes the vehicle toward its target; rather, I want to ask the vehicle to make an intelligent decision to steer toward the target based on its perception of its own state (its speed and the direction in which it’s currently moving) and its environment (the location of the target). The vehicle should consider how it desires to move (a vector pointing to the target), compare that goal with how it’s currently moving (its velocity), and apply a force accordingly. That’s exactly what Reynolds’s steering force formula says:</p>
|
||||
<div data-type="equation">\text{steering force} = \text{desired velocity} - \text{current velocity}</div>
|
||||
<p>Or, as you might write in p5.js:</p>
|
||||
|
@ -1046,8 +1046,9 @@ function draw() {
|
|||
let diff = p5.Vector.sub(this.position, other.position);
|
||||
diff.normalize();
|
||||
}</pre>
|
||||
<p>This isn’t enough. I have a fleeing vector now, but what I really need is the average of the fleeing vectors for all the vehicles that are too close. How do I compute an average? Add up all the vectors and divide by the total:</p>
|
||||
<pre class="codesplit" data-code-language="javascript"> //{!1 .bold} Start with an empty vector.
|
||||
<div class="avoid-break">
|
||||
<p>This isn’t enough. I have a fleeing vector now, but what I really need is the average of the fleeing vectors for all the vehicles that are too close. How do I compute an average? Add up all the vectors and divide by the total:</p>
|
||||
<pre class="codesplit" data-code-language="javascript"> //{!1 .bold} Start with an empty vector.
|
||||
let sum = createVector();
|
||||
//{!1 .bold} We have to keep track of how many vehicles are too close.
|
||||
let count = 0;
|
||||
|
@ -1071,6 +1072,7 @@ function draw() {
|
|||
//{.bold}
|
||||
sum.div(count);
|
||||
}</pre>
|
||||
</div>
|
||||
<p>Once I have the average vector (stored in the variable <code>sum</code>), that vector can be scaled to the maximum speed and become the desired velocity—the vehicle <em>desires</em> to move in that direction at maximum speed! (In fact, I really don’t have to divide by <code>count</code> anymore since the magnitude is set manually.) And once I have the desired velocity, it’s the same old Reynolds story—steering equals desired minus velocity:</p>
|
||||
<pre class="codesplit" data-code-language="javascript"> if (count > 0) {
|
||||
//{!1} Scale average to max speed
|
||||
|
|
|
@ -438,7 +438,7 @@ function setup() {
|
|||
}</pre>
|
||||
</div>
|
||||
<p>I don’t need <code>this.x</code> and <code>this.y</code> position variables anymore. The <code>Box</code> constructor takes in the starting x- and y-coordinates, passes them along to <code>Bodies.rectangle()</code> to create a new Matter.js body, and then forgets about them. As you’ll see, the body itself will keep track of its position behind the scenes. The body could technically keep track of its dimensions as well, but since Matter.js stores them as a list of vertices, it’s a bit more convenient to hold onto the width of the square in the <code>this.w</code> variable for when it comes time to draw the box.</p>
|
||||
<h3 id="step-3-draw-the-box-body">Step 3: Draw the <s>Box</s> Body</h3>
|
||||
<h3 id="step-3-draw-the-body">Step 3: Draw the Body</h3>
|
||||
<p>Almost there. Before I introduced Matter.js into the sketch, drawing <code>Box</code> was easy. The object’s position was stored in the variables <code>this.x</code> and <code>this.y</code>:</p>
|
||||
<pre class="codesplit" data-code-language="javascript"> // Draw the object by using <code>square()</code>.
|
||||
show() {
|
||||
|
|
|
@ -585,8 +585,8 @@ for (let i = 1; i < columns - 1; i++) {
|
|||
|
||||
//{!1} The rules of life!
|
||||
if (board[i][j] === 1 && neighborSum < 2) next[i][j] = 0;
|
||||
//{.continue}
|
||||
else if (board[i][j] === 1 && neighborSum > 3) next[i][j] = 0;
|
||||
//{.continue}
|
||||
else if (board[i][j] === 0 && neighborSum === 3) next[i][j] = 1;
|
||||
else next[i][j] = board[i][j];
|
||||
}
|
||||
|
|
|
@ -458,7 +458,7 @@ function setup() {
|
|||
</div>
|
||||
<h2 id="trees">Trees</h2>
|
||||
<p>The fractals presented so far in this chapter have been deterministic: they have no randomness baked in and will always produce the same outcome each time they’re run. While this has made for an excellent introduction to classic fractal patterns and the programming techniques behind drawing them, the results have appeared too precise to seem truly organic.</p>
|
||||
<p>In this section, I’ll take a step closer to the natural world, with a case study of a branching fractal tree. I’ll start with a deterministic version. Then I’ll introduce an element of randomness to illustrate techniques for generating stochastic (or nondeterministic) fractals, whose outcome can vary each time.</p>
|
||||
<p>In this section, I’ll take a step closer to the natural world, with a case study of a branching fractal<br>tree. I’ll start with a deterministic version. Then I’ll introduce an element of randomness to illustrate techniques for generating stochastic (or nondeterministic) fractals, whose outcome can vary<br>each time.</p>
|
||||
<h3 id="the-deterministic-version">The Deterministic Version</h3>
|
||||
<p>Figure 8.17 outlines a deterministic set of production rules for drawing a fractal tree.</p>
|
||||
<figure>
|
||||
|
@ -826,7 +826,9 @@ B → BBB</span></td>
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>This type of drawing framework is often referred to as <strong>turtle graphics</strong> (from the old days of Logo programming). Imagine a turtle sitting on your p5.js canvas, able to accept a small set of commands: turn left, turn right, move forward, draw a line, and so on. While p5.js isn’t set up to operate this way by default, I can emulate a turtle graphics engine fairly easily with <code>translate()</code>, <code>rotate()</code>, and <code>line()</code>. Here’s how I would convert this L-system’s alphabet into p5.js code:</p>
|
||||
<div class="avoid-break">
|
||||
<p>This type of drawing framework is often referred to as <strong>turtle graphics</strong> (from the old days of Logo programming). Imagine a turtle sitting on your p5.js canvas, able to accept a small set of commands: turn left, turn right, move forward, draw a line, and so on. While p5.js isn’t set up to operate this way by default, I can emulate a turtle graphics engine fairly easily with <code>translate()</code>, <code>rotate()</code>, and <code>line()</code>. Here’s how I would convert this L-system’s alphabet into p5.js code:</p>
|
||||
</div>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
|
|
|
@ -1018,6 +1018,7 @@ let populationSize = 150;</pre>
|
|||
this.fitness = 0;
|
||||
this.position = createVector(x, y);
|
||||
this.velocity = createVector();
|
||||
|
||||
this.acceleration = createVector();
|
||||
}</pre>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue