diff --git a/content/05_steering.html b/content/05_steering.html index d22c30a..2200132 100644 --- a/content/05_steering.html +++ b/content/05_steering.html @@ -68,7 +68,7 @@ Figure 5.1: A vehicle with a velocity and a target
Figure 5.1: A vehicle with a velocity and a target
-

The vehicle’s goal and subsequent action is to seek the target. Thinking back to Chapter 2, you might begin by making the target an attractor and applying a gravitational force that pulls
the vehicle to the target. This would be a perfectly reasonable solution, but conceptually it’s not what I’m looking
for here.

+

The vehicle’s goal and subsequent action is to seek the target. Thinking back to Chapter 2, you might begin by making the target an attractor and applying a gravitational force that pulls the vehicle to
the target. This would be a perfectly reasonable solution, but conceptually it’s not what I’m looking for here.

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:

\text{steering force} = \text{desired velocity} - \text{current velocity}

Or, as you might write in p5.js:

@@ -1046,8 +1046,9 @@ function draw() { let diff = p5.Vector.sub(this.position, other.position); diff.normalize(); } -

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:

-
  //{!1 .bold} Start with an empty vector.
+
+

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:

+
  //{!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);
   }
+

Once I have the average vector (stored in the variable sum), that vector can be scaled to the maximum speed and become the desired velocity—the vehicle desires to move in that direction at maximum speed! (In fact, I really don’t have to divide by count 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:

  if (count > 0) {
     //{!1} Scale average to max speed
diff --git a/content/06_libraries.html b/content/06_libraries.html
index 3e7a8bd..9ef7120 100644
--- a/content/06_libraries.html
+++ b/content/06_libraries.html
@@ -438,7 +438,7 @@ function setup() {
   }

I don’t need this.x and this.y position variables anymore. The Box constructor takes in the starting x- and y-coordinates, passes them along to Bodies.rectangle() 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 this.w variable for when it comes time to draw the box.

-

Step 3: Draw the Box Body

+

Step 3: Draw the Body

Almost there. Before I introduced Matter.js into the sketch, drawing Box was easy. The object’s position was stored in the variables this.x and this.y:

  // Draw the object by using square().
   show() {
diff --git a/content/07_ca.html b/content/07_ca.html
index cf7f706..8da8b78 100644
--- a/content/07_ca.html
+++ b/content/07_ca.html
@@ -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];
   }
diff --git a/content/08_fractals.html b/content/08_fractals.html
index dbb05be..8ca6a66 100644
--- a/content/08_fractals.html
+++ b/content/08_fractals.html
@@ -458,7 +458,7 @@ function setup() {
 
 

Trees

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.

-

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.

+

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.

The Deterministic Version

Figure 8.17 outlines a deterministic set of production rules for drawing a fractal tree.

@@ -826,7 +826,9 @@ B → BBB -

This type of drawing framework is often referred to as turtle graphics (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 translate(), rotate(), and line(). Here’s how I would convert this L-system’s alphabet into p5.js code:

+
+

This type of drawing framework is often referred to as turtle graphics (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 translate(), rotate(), and line(). Here’s how I would convert this L-system’s alphabet into p5.js code:

+
diff --git a/content/09_ga.html b/content/09_ga.html index 03ca5cb..0f80555 100644 --- a/content/09_ga.html +++ b/content/09_ga.html @@ -1018,6 +1018,7 @@ let populationSize = 150; this.fitness = 0; this.position = createVector(x, y); this.velocity = createVector(); + this.acceleration = createVector(); }