diff --git a/content/00_5_introduction.html b/content/00_5_introduction.html index 4641c47..eb76440 100644 --- a/content/00_5_introduction.html +++ b/content/00_5_introduction.html @@ -42,6 +42,7 @@
You draw a shape at position x
. With each frame of animation, you increment the value of x
, redraw the shape, and voilà—the illusion of motion! Maybe you took it a step or two further and included a y
position, as well as variables for speed along the x- and y-axes:
x = x + xspeed; y = y + yspeed;+
Part 1 of this story will take this idea even further. After exploring how to use different flavors of randomness to drive an object’s motion (Chapter 0), I’m going to take these xspeed
and yspeed
variables and demonstrate how together they form a vector (Chapter 1). You won’t get any new functionality out of this, but it will build a solid foundation for programming motion in the rest of the book.
Once you know a little something about vectors, you’re going to quickly realize that a force (Chapter 2) is a vector. Kick a soccer ball and you’re applying a force. What does a force cause an object to do? According to Sir Isaac Newton, force equals mass times acceleration, so that force causes an object to accelerate. Modeling forces will allow you to create systems with dynamic motion, in which objects move according to a variety of rules.
Now, that soccer ball to which you applied a force might have also been spinning. If an object moves according to its linear acceleration, it can spin according to its angular acceleration (Chapter 3). Understanding the basics of angles and trigonometry will allow you to model rotating objects as well as grasp the principles behind oscillating motion, like a pendulum swinging or a spring bouncing.
Once you’ve tackled the basics of motion and forces for an individual inanimate object, I’ll show you how to make thousands upon thousands of those objects and manage them as a single unit called a particle system (Chapter 4). Particle systems are also a good excuse to look at some additional features of object-oriented programming—namely, inheritance and polymorphism.
diff --git a/content/04_particles.html b/content/04_particles.html index 78d7042..66ae2c6 100644 --- a/content/04_particles.html +++ b/content/04_particles.html @@ -676,9 +676,9 @@ class Cat extends Animal { } eat() { - // Calleat()
from Animal
. A child can execute a function from the parent while adding its own code.
+ // Call eat()
from Animal
. A child can execute a function from the parent.
super.eat();
- // Add some additional code for a dog’s specific eating characteristics.
+ // Additional code for a dog’s specific eating characteristics.
print("Woof!!!");
}
@@ -1139,10 +1139,10 @@ class Repeller {
}
repel(particle) {
- // {!1}
+ // {!2}
let force = p5.Vector.sub(this.position, particle.position);
- // {.continue.bottom-align} This is the same repel algorithm from Chapter 2: forces based on gravitational attraction.
let distance = force.mag();
+ // {.continue.bottom-align} This is the same repel algorithm from Chapter 2: forces based on gravitational attraction.
distance = constrain(distance, 5, 50);
let strength = -1 * this.power / (distance * distance);
force.setMag(strength);
@@ -1187,11 +1187,13 @@ class Repeller {
First, declare a variable to store the image:
let img;-
Then, load the image in preload()
:
function preload() { ++Then, load the image in
+preload()
:function preload() { // Load the PNG. img = loadImage("texture.png"); }+Next, when it comes time to draw the particle, use the
img
variable instead of drawing a circle or rectangle:show() { imageMode(CENTER); diff --git a/content/05_steering.html b/content/05_steering.html index 6745004..616d0aa 100644 --- a/content/05_steering.html +++ b/content/05_steering.html @@ -286,7 +286,6 @@ desired.setMag(this.maxspeed);-arrive(target) { let desired = p5.Vector.sub(target, this.position); - //{!1} The distance is the magnitude of // the vector pointing from // the position to the target. @@ -531,9 +530,7 @@ let row = floor(this.position.y / this.resolution); -class Vehicle { - follow(flow) { +-follow(flow) { // What is the vector at that spot in the flow field? let desired = flow.lookup(this.position); desired.setMag(this.maxspeed); @@ -542,7 +539,6 @@ let row = floor(this.position.y / this.resolution);steer.limit(this.maxforce); this.applyForce(steer); }Notice that
lookup()
is a method of theFlowField
class, rather than ofVehicle
. While you certainly could placelookup()
within theVehicle
class instead, from my perspective, placing it inFlowField
aligns best with the OOP principle of encapsulation. The lookup task, which retrieves a vector based on a position from the flow field, is inherently tied to the data of theFlowField
object.You may also notice some familiar elements from Chapter 4, such as the use of an array of vehicles. Although the vehicles here operate independently, this is a great first step toward thinking about the group behaviors that I’ll introduce later in this chapter.
@@ -948,7 +944,7 @@ for (let i = 0; i < path.points.length - 1; i++) {Simple units operate in parallel. For every cycle through the draw()
loop, each unit will calculate its own steering forces. This will create the appearance of all the units working in parallel.Systems as a whole exhibit emergent phenomena. Complex behaviors, patterns, and intelligence can emerge from the interactions among simple units. This phenomenon occurs in nature, such as in ant colonies, migration patterns, earthquakes, and snowflakes. The question is whether the same results can be achieved in a p5.js sketch. -Beyond these core principles, three additional qualities of complex systems will help frame the discussion, as well as provide guidelines for features to include in a software simulation. It’s important to acknowledge that this is a fuzzy set of characteristics, and not all complex systems have all of them:
+Beyond these core principles, three additional qualities of complex systems will help frame the discussion, as well as provide guidelines for features to include in a software simulation. It’s important to acknowledge that this is a fuzzy set of characteristics, and not all complex systems have all
of them:
- Nonlinearity: This aspect of complex systems is often casually referred to as the butterfly effect, coined by mathematician and meteorologist Edward Norton Lorenz, a pioneer in the study of chaos theory. In 1961, Lorenz was running a computer weather simulation for the second time and, perhaps to save a little time, typed in a starting value of 0.506 instead of 0.506127. The end result was completely different from the first result of the simulation. @@ -989,8 +985,9 @@ function setup() {
That looks good but is not quite right. What’s missing? In the case of
seek()
, I said, “SeekmouseX
andmouseY
.” In the case ofseparate()
, I’m saying, “Separate from everyone else.” Who is everyone else? It’s the list of all the other vehicles:vehicle.separate(vehicles);This is the big leap beyond what you saw before with particle systems. Instead of each element (particle or vehicle) operating on its own, I’m now saying, “Hey you, that vehicle there! When it comes time for you to operate, you need to operate with an awareness of everyone else. So I’m going to go ahead and pass you the list of everyone else.”
-Putting together what I’ve done so far, here are the
-setup()
anddraw()
functions for a sketch that exhibits group behavior:let vehicles; ++Putting together what I’ve done so far, here are the
+setup()
anddraw()
functions for a sketch that exhibits group behavior:let vehicles; function setup() { createCanvas(640, 240); @@ -1012,6 +1009,7 @@ function draw() { vehicle.show(); } }+