The Nature of Code

Exercises from the book The Nature of Code by Daniel Shiffman. The animations are constructed using the p5.js library (reference documents for p5). At the moment, all the HTML, CSS, and JavaScript is hand-rolled. The page is deployed to S3 via the AWS command line tool invoked from a Makefile, and served by CloudFront. S3 and CloudFront are configured with Terraform.

Chapter 1: Vectors

Chapter 1 demonstrates P5.js Vectors as well as presenting a few elements of vector arithmetic. The chapter provides an excellent introduction to vector arithmetic, and is worth reading in its entirety at least once. For anyone not familiar with vectors, the chapter is worth reading in considerable detail.

Exercise 1.1: Vectorize existing code

Take one of the walker examples from Chapter 0 and convert it to use vectors.

Steps for the random walk were biased towards the right at 26%, down at 26%, up and left at 24% each. Just this slight bias results in a clear trend, can be seen by letting the animation run for a few minutes.

The step size is 1 pixel, and the walker is not confined to the region defined by the canvas (cream colored panel above).

An additional walker was added mirroring the position of the initial walked. The resulting image has a Rorschach-like quality, albeit skewed towards a 5 o'clock direction. The Rorschach aspect breaks when the walkers wrap around the canvas.

Exercise 1.2: Vectorize something else!

Find something else you’ve previously made in p5.js using separate x and y variables, and use vectors instead.

This shows three instances of Ex. 0.6, "qualified random variables," all on the same canvas and "walking" concurrently. Adding more walkers would be easy.

Exercise 1.3: Bouncer

Extend Example 1.2 into 3D. Can you get a sphere to bounce around a box?

First let's figure it out in 2D. The following show a ball bouncing around in a rectangular box. Straightforward.

Doing this in 3D is a little more involved as it was done in WebGL to leverage browser rendering capabilities. WebGL provides primitive shapes such as box and sphere which would otherwise have to be created by coordinates.

This was all relatively straightforward.

Exercise 1.4: Write the limit() function for the p5.Vector class

Write the limit() function for the p5.Vector class:
    
      limit(max) {
        if (this.mag() > max) {
          this.normalize();
          this.mult(max);
        }
      }
    
  

I didn't really understand what this question wanted, but I did put a limiting value in for the radius in Problem 1.8 below.

Exercise 1.5: Vehicle Acceleration

Create a simulation of an object (think about a vehicle) that accelerates when you press the up arrow and brakes when you press the down arrow.

Leveraging WebGL again, a slab (dark green) and a box (dark red) is a reasonable facsimile of some sort of vehicle traveling across terrain.

The vehicle accelerates when the up arrow is pressed and decelerates when the down arrow is pressed. The vehicle wraps around the canvas.

Exercise 1.6: Perlin Acceleration

Referring back to Exercise 0.7, implement an acceleration calculated with Perlin noise.

Exercise 1.7: Static functions

Translate the following pseudocode to code, using static or nonstatic functions where appropriate:

Another problem where the author's intent was not clear to me. The assumption may be that I'm using the author's code and archittecture, which is not the case. My implementation is for the most part independent.

Exercise 1.8: Gravitational attraction

Example 1.10 is remarkably close to the concept of gravitational attraction, with the object being attracted to the mouse position. In the example, however, the attraction magnitude is constant, whereas with a real-life gravitational force, the magnitude is inversely proportional to distance: the closer the object is to the attraction point, the faster it accelerates. I'll cover gravitational attraction in more detail in the next chapter, but for now, try implementing your own version of Example 1.10 with a variable magnitude of acceleration, stronger when it's either closer or farther away.

Why not just use gravity? Mathematically, gravity is expressed as:

$$ F = G \frac{m_1 m_2}{r^2} $$

where:

Here is an implementation which uses the formula, but with non-physical values (for demonstration purposes only).

The disk starts at rest and will move by gravitaional attraction towards the position of the pointer. See if you can capture the disk into a stable orbit around the pointer.


And that is a wrap for Chapter 1 of Nature of Code. You may also be interested in Chapter 0: Randomness


dool.in