Merge pull request #849 from nature-of-code/notion-update-docs

[Notion] Update docs
This commit is contained in:
Daniel Shiffman 2024-02-26 10:53:52 -05:00 committed by GitHub
commit f2712067f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 16 additions and 14 deletions

View file

@ -90,12 +90,6 @@
<p>Earlier I stated that you could flip two coins. In p5.js, however, when you want to randomly choose from a list of options, you can simply generate a random number with the <code>random()</code> function. It picks a random floating-point (decimal) value within any range you want. Here, I use 4 to indicate a range of 0 to 4:</p>
<pre class="codesplit" data-code-language="javascript">let choice = floor(random(4));</pre>
<p>I declare a variable <code>choice</code> and assign it a random integer (whole number) by using <code>floor()</code> to remove the decimal places from the random floating-point number. Technically speaking, the number generated by <code>random(4)</code> lies within the range of 0 (inclusive) to 4 (exclusive), meaning it can never actually be 4.0. The highest possible number it could generate is just below 4—3.999999999 (with as many 9s as JavaScript will allow), which <code>floor()</code> then truncates down to 3, removing the decimal part. Therefore, Ive effectively assigned <code>choice</code> a value of 0, 1, 2, or 3.</p>
<div data-type="note">
<h3 id="coding-conventions">Coding Conventions</h3>
<p>In JavaScript, variables can be declared using either <code>let</code> or <code>const</code>. A typical approach is to declare all variables with <code>const</code> and change to <code>let</code> when needed. In this first example, <code>const</code> would be appropriate for declaring <code>choice</code> as its never reassigned a new value over the course of its life inside each call to <code>step()</code>. While this differentiation is important, Im choosing to follow the p5.js example convention and declare all variables with <code>let</code>.</p>
<p>I recognize that JavaScript has both <code>const</code> and <code>let</code> for important reasons. However, the distinction can be a distraction and confusing for beginners. I encourage you to explore the topic further and make your own decisions about how to best declare variables in your own sketches. For more, you can read <a href="https://github.com/processing/p5.js/issues/3877">the discussion surrounding issue #3877 in the p5.js GitHub repository</a>.</p>
<p>Im also choosing to use JavaScripts strict equality (<code>===</code>) operator (and its inequality counterpart, <code>!==</code>). This Boolean operator tests both value and type equality. For example, <code>3 === '3'</code> will evaluate to <code>false</code> because the types are different (number versus string), even though they look similar. On the other hand, using the loose equality (<code>==</code>) operator in <code>3 == '3'</code> would result in <code>true</code> because the two different types are converted to be comparable. Although the loose comparison often works fine, it can sometimes lead to unexpected results, so <code>===</code> is probably the safer choice.</p>
</div>
<p>Next, the walker takes the appropriate step (left, right, up, or down), depending on which random number was picked. Heres the full <code>step()</code> method closing out the <code>Walker</code> class:</p>
<div class="snip-above">
<pre class="codesplit" data-code-language="javascript"> step() {
@ -114,6 +108,12 @@
}
}</pre>
</div>
<div data-type="note">
<h3 id="coding-conventions">Coding Conventions</h3>
<p>In JavaScript, variables can be declared using either <code>let</code> or <code>const</code>. A typical approach is to declare all variables with <code>const</code> and change to <code>let</code> when needed. In this first example, <code>const</code> would be appropriate for declaring <code>choice</code> as its never reassigned a new value over the course of its life inside each call to <code>step()</code>. While this differentiation is important, Im choosing to follow the p5.js example convention and declare all variables with <code>let</code>.</p>
<p>I recognize that JavaScript has both <code>const</code> and <code>let</code> for important reasons. However, the distinction can be a distraction and confusing for beginners. I encourage you to explore the topic further and make your own decisions about how to best declare variables in your own sketches. For more, you can read <a href="https://github.com/processing/p5.js/issues/3877">the discussion surrounding issue #3877 in the p5.js GitHub repository</a>.</p>
<p>Im also choosing to use JavaScripts strict equality (<code>===</code>) operator (and its inequality counterpart, <code>!==</code>). This Boolean operator tests both value and type equality. For example, <code>3 === '3'</code> will evaluate to <code>false</code> because the types are different (number versus string), even though they look similar. On the other hand, using the loose equality (<code>==</code>) operator in <code>3 == '3'</code> would result in <code>true</code> because the two different types are converted to be comparable. Although the loose comparison often works fine, it can sometimes lead to unexpected results, so <code>===</code> is probably the safer choice.</p>
</div>
<p>Now that Ive written the class, its time to make an actual <code>Walker</code> object in the sketch itself. Assuming youre looking to model a single random walk, start with a single global variable:</p>
<pre class="codesplit" data-code-language="javascript">// A <code>Walker</code> object
let walker;</pre>

View file

@ -1014,7 +1014,7 @@ function draw() {
<p>Example 2.8 could be improved by refactoring the code to include constructor arguments that assign the body velocities. For now, however, this approach serves as a quick way to experiment with patterns based on various initial positions and velocities.</p>
<div data-type="exercise">
<h3 id="exercise-214">Exercise 2.14</h3>
<p>The paper “Classification of Symmetry Groups for Planar <em>n</em><a href="https://doi.org/10.1017/fms.2013.5">-Body Choreographies” by James Montaldi and Katrina Steckles</a> explores <em>choreographic</em> solutions to the <em>n</em>-body problem (defined as periodic motions of bodies following one another at regular intervals). Educator and artist Dan Gries created <a href="https://dangries.com/rectangleworld/demos/nBody">an interactive demonstration of these choreographies</a>. Try adding a third (or more!) body to Example 2.8 and experiment with setting initial positions and velocities. What choreographies can you achieve?</p>
<p>The paper <a href="https://doi.org/10.1017/fms.2013.5">“Classification of Symmetry Groups for Planar <em>n</em>-Body Choreographies” by James Montaldi and Katrina Steckles</a> explores <em>choreographic</em> solutions to the <em>n</em>-body problem (defined as periodic motions of bodies following one another at regular intervals). Educator and artist Dan Gries created <a href="https://dangries.com/rectangleworld/demos/nBody">an interactive demonstration of these choreographies</a>. Try adding a third (or more!) body to Example 2.8 and experiment with setting initial positions and velocities. What choreographies can you achieve?</p>
</div>
<p>Im now ready to move on to an example with <em>n</em> bodies by incorporating an array:</p>
<pre class="codesplit" data-code-language="javascript">// Start with an empty array.

View file

@ -49,7 +49,7 @@
/* What else do I need to add? */</pre>
</div>
<p>Like the <code>Mover</code> and <code>Particle</code> classes before it, the <code>Vehicle</code> classs motion is controlled through its position, velocity, and acceleration vectors. This will make the steering behaviors of a single autonomous agent straightforward to implement. Yet by building a system of multiple vehicles that steer themselves according to simple, locally based rules, surprising levels of complexity emerge. The most famous example is Reynoldss boids model for flocking or swarming behavior, which Ill demonstrate in Example 5.9.</p>
<p>Like the <code>Mover</code> and <code>Particle</code> classes before it, the <code>Vehicle</code> classs motion is controlled through its position, velocity, and acceleration vectors. This will make the steering behaviors of a single autonomous agent straightforward to implement. Yet by building a system of multiple vehicles that steer themselves according to simple, locally based rules, surprising levels of complexity emerge. The most famous example is Reynoldss boids model for flocking or swarming behavior, which Ill demonstrate in Example 5.11.</p>
<div data-type="note">
<h3 id="why-vehicles">Why Vehicles?</h3>
<p>In his book <em>Vehicles: Experiments in Synthetic Psychology</em> (Bradford Books, 1986), Italian neuroscientist and cyberneticist Valentino Braitenberg describes a series of hypothetical vehicles with simple internal structures, writing, “This is an exercise in fictional science, or science fiction, if you like that better.” Braitenberg argues that his extraordinarily simple mechanical vehicles manifest behaviors such as fear, aggression, love, foresight, and optimism. Reynolds took his inspiration from Braitenberg, and Ill take mine from Reynolds.</p>
@ -1371,7 +1371,7 @@ function draw() {
}</pre>
<p>All that remains is to initialize the flock in <code>setup()</code> and run it in <code>draw()</code>.</p>
<div data-type="example">
<h3 id="example-511-flocking">Example 5.11: Flocking</h3>
<h3 id="example-511-flockingex">Example 5.11: Flockingex</h3>
<figure>
<div data-type="embed" data-p5-editor="https://editor.p5js.org/natureofcode/sketches/IkpBw96Sd" data-example-path="examples/05_steering/example_5_9_flocking"><img src="examples/05_steering/example_5_9_flocking/screenshot.png"></div>
<figcaption></figcaption>
@ -1475,7 +1475,7 @@ for (let i = 0; i &#x3C; grid.length; i++) {
let column = floor(boid.position.x / resolution);
let row = floor(boid.position.y / resolution);
// Constrain to the limits of the array.
column = constrain(column, 0, columns - 1);
column = constrain(column, 0, cols - 1);
row = constrain(row, 0, rows - 1);
// Add the boid.
grid[column][row].push(boid);
@ -1492,7 +1492,7 @@ for (let i = 0; i &#x3C; grid.length; i++) {
<pre class="codesplit" data-code-language="javascript"> run(boids) {
let column = floor(this.position.x / resolution);
let row = floor(this.position.y / resolution);
column = constrain(column, 0, columns - 1);
column = constrain(column, 0, cols - 1);
row = constrain(row, 0, rows - 1);
// Only these boids will be checked. See the code online for how neighboring cells are also included.
let neighbors = grid[column][row];

View file

@ -14,7 +14,9 @@ class Boid {
this.maxspeed = 3; // Maximum speed
this.maxforce = 0.05; // Maximum steering force
}
// No argument to run() anymore, could bring in grid
// but accessing it as global variable instead
run() {
let col = Math.floor(this.position.x / resolution);
let row = Math.floor(this.position.y / resolution);

View file

@ -14,7 +14,7 @@ class Flock {
run() {
for (let boid of this.boids) {
boid.run(this.boids); // Passing the entire list of boids to each boid individually
boid.run();
}
}

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script>
<meta charset="utf-8" />
<title>The Nature of Code Example 6.9 Flocking</title>
<link rel="stylesheet" type="text/css" href="style.css" />