mirror of
https://github.com/nature-of-code/noc-book-2
synced 2024-11-16 07:47:48 +01:00
Notion - Update docs
This commit is contained in:
parent
8177aa9988
commit
453263812e
3 changed files with 16 additions and 21 deletions
|
@ -952,7 +952,6 @@ static add(v1, v2) {
|
|||
<p>When calling a static method, instead of referencing an object instance, you reference the name of the class. Here’s the right way to implement the vector addition example:</p>
|
||||
<pre class="codesplit" data-code-language="javascript">let v = createVector(0, 0);
|
||||
let u = createVector(4, 5);
|
||||
|
||||
<s>let w = v.add(u);</s>
|
||||
<strong>let w = p5.Vector.add(v, u);</strong></pre>
|
||||
<p>The <code>p5.Vector</code> class has static versions of <code>add()</code>, <code>sub()</code>, <code>mult()</code>, and <code>div()</code>. These static methods allow you to perform generic mathematical operations on vectors without changing the value of one of the input vectors in the process.</p>
|
||||
|
|
|
@ -812,22 +812,22 @@ mover.applyForce(force);</pre>
|
|||
mover.show();
|
||||
}</pre>
|
||||
<p>I’m almost there. Since I decided to put the <code>attract()</code> method inside the <code>Attractor</code> class, I still need to actually write that method. It should receive a <code>Mover</code> object and return a <code>p5.Vector</code>:</p>
|
||||
<pre class="codesplit" data-code-language="javascript">attract(m) {
|
||||
// All the math
|
||||
return ______________;
|
||||
}</pre>
|
||||
<pre class="codesplit" data-code-language="javascript"> attract(m) {
|
||||
// All the math
|
||||
return ______________;
|
||||
}</pre>
|
||||
<p>What goes inside the method? All of that nice math for gravitational attraction!</p>
|
||||
<pre class="codesplit" data-code-language="javascript">attract(mover) {
|
||||
//{!1} What’s the force’s direction?
|
||||
let force = p5.Vector.sub(this.position, mover.position);
|
||||
let distance = force.mag();
|
||||
// Calculate the strength of the attraction force.
|
||||
let strength = (this.mass * mover.mass) / (distance * distance);
|
||||
force.setMag(strength);
|
||||
<pre class="codesplit" data-code-language="javascript"> attract(mover) {
|
||||
//{!1} What’s the force’s direction?
|
||||
let force = p5.Vector.sub(this.position, mover.position);
|
||||
let distance = force.mag();
|
||||
// Calculate the strength of the attraction force.
|
||||
let strength = (this.mass * mover.mass) / (distance * distance);
|
||||
force.setMag(strength);
|
||||
|
||||
// Return the force so it can be applied!
|
||||
return force;
|
||||
}</pre>
|
||||
// Return the force so it can be applied!
|
||||
return force;
|
||||
}</pre>
|
||||
<p>And I’m done. Sort of. Almost. I need to work out one small kink. Look at the code for the <code>attract()</code> method again. See that slash symbol for division? Whenever you have one of those, you should ask yourself this question: What would happen if the distance happened to be a really, really small number, or (even worse!) 0? You can’t divide a number by 0, and if you were to divide a number by something tiny like 0.0001, that’s the equivalent of multiplying that number by 10,000! That may be a viable outcome of this formula for gravitational attraction in the real world, but p5.js isn’t the real world. In the p5.js world, the mover could end up being very, very close to the attractor, and the resulting force could be so strong that the mover flies way off the canvas.</p>
|
||||
<p>Conversely, what if the mover were to be, say, 500 pixels from the attractor (not unreasonable in p5.js)? You’re squaring the distance, so this will result in dividing the force by 250,000. That force might end up being so weak that it’s almost as if it’s not applied at all.</p>
|
||||
<p>To avoid both extremes, it’s practical to constrain the range of <code>distance</code> before feeding it into the formula. Maybe, no matter where the <code>Mover</code> <em>actually</em> is, you should never consider it to be less than 5 pixels or more than 25 pixels away from the attractor, for the purposes of calculating the force of gravitational attraction:</p>
|
||||
|
|
|
@ -515,22 +515,18 @@ function setup() {
|
|||
<p>Imagine it’s a Saturday morning. You’ve just gone out for a lovely jog, had a delicious bowl of cereal, and are sitting quietly at your computer with a cup of warm chamomile tea. It’s your old friend so-and-so’s birthday, and you’ve decided you’d like to make a greeting card with p5.js. How about simulating some confetti? Purple confetti, pink confetti, star-shaped confetti, square confetti, fast confetti, fluttery confetti—all kinds of confetti, all with different appearances and different behaviors, exploding onto the screen all at once.</p>
|
||||
<p>What you have is clearly a particle system: a collection of individual pieces (particles) of confetti. You might be able to cleverly redesign the <code>Particle</code> class to have variables that store color, shape, behavior, and more. To create a variety of particles, you might initialize those variables with random values. But what if some of your particles are drastically different? It could become very messy to have all sorts of code for different ways of being a particle in the same class. Another option might be to do the following:</p>
|
||||
<pre class="codesplit" data-code-language="javascript">class HappyConfetti {
|
||||
|
||||
}
|
||||
|
||||
class FunConfetti {
|
||||
|
||||
}
|
||||
|
||||
class WackyConfetti {
|
||||
|
||||
}</pre>
|
||||
<p>This is a nice solution: create three classes to describe the different kinds of confetti that are part of your particle system. The <code>Emitter</code> constructor could then have some code to pick randomly from the three classes when filling the array (note that this probabilistic method is the same one I employed in the random walk examples in Chapter 0):</p>
|
||||
<div class="snip-below">
|
||||
<pre class="codesplit" data-code-language="javascript">class Emitter {
|
||||
constructor(num) {
|
||||
this.particles = [];
|
||||
|
||||
for (let i = 0; i < num; i++) {
|
||||
let r = random(1);
|
||||
// Randomly pick a kind of particle.
|
||||
|
@ -803,7 +799,7 @@ for (let animal of kingdom) {
|
|||
}</pre>
|
||||
<p>Let’s make this a bit more sophisticated. Say I want to have each <code>Confetti</code> particle rotate as it flies through the air. One option is to model angular velocity and acceleration, as described in <a href="/oscillation#">Chapter 3</a>. For ease, however, I’ll implement something less formal.</p>
|
||||
<p>I know a particle has an x-position somewhere between 0 and the width of the canvas. What if I said that when the particle’s x-position is 0, its rotation should be 0; when its x-position is equal to the width, its rotation should be equal to <span data-type="equation">4\pi</span>? Does this ring a bell? As discussed in Chapter 0, whenever a value has one range that you want to map to another range, you can use the <code>map()</code> function:</p>
|
||||
<pre class="codesplit" data-code-language="javascript">let angle = map(this.position.x, 0, width, 0, TWO_PI * 2);</pre>
|
||||
<pre class="codesplit" data-code-language="javascript"> let angle = map(this.position.x, 0, width, 0, TWO_PI * 2);</pre>
|
||||
<p>Here’s how this code fits into the <code>show()</code> method:</p>
|
||||
<pre class="codesplit" data-code-language="javascript"> show() {
|
||||
let angle = map(this.position.x, 0, width, 0, TWO_PI * 2);
|
||||
|
@ -883,7 +879,7 @@ for (let animal of kingdom) {
|
|||
let f = force.copy();
|
||||
f.div(this.mass);
|
||||
this.acceleration.add(f);
|
||||
}</pre>
|
||||
}</pre>
|
||||
</div>
|
||||
<p>Now that the <code>Particle</code> class is complete, I have an important question to ask: Where should I call the <code>applyForce()</code> method? Where in the code is it appropriate to apply a force to a particle? In my view, there’s no right or wrong answer; it really depends on the exact functionality and goals of a particular p5.js sketch. My quick-and-dirty solution in the previous examples was to create and apply a <code>gravity</code> force in the <code>run()</code> method of each particle:</p>
|
||||
<div class="snip-below snip-above">
|
||||
|
|
Loading…
Reference in a new issue