Felipe Almeida | OAPT Conference | May 5, 2023

Computer Code: A Worthwhile Representation?Computer Code: A Worthwhile Representation?

The advantages of representing physical phenomena in various ways (e.g. motion diagrams, text descriptions, interaction diagrams, energy bar charts, etc) are well established. Should representations using code be included too? Do the benefits justify the efforts? This session will demonstrate how creating code to represent simple and complex physical phenomena (e.g. linear motion, Thorโ€™s Hammer) may be advantageous to the physics learner. No previous coding experience assumed.



Computer Code as Another Representation
๐Ÿ”

A sample scenario:

A big box of blueberries is pushed east by a rocket as it travels west along the dirt. The box comes to rest while passing the origin.

Some useful representations:

What (trimmed) computer code and accompanying simulation could look like as another representation:

let mass = 10, boxSize = 10;
let posX = 240, vel = -25;
let netForce = 6.8;
let acc = netForce/mass;
โ‹ฎ
  posX += vel;
  vel += acc;

  if (vel >= 0)
    noLoop();

Intro to Coding with p5.js
๐Ÿ”

p5.js is a free and open source javascript library supported by the procesing foundation that is designed to make creative coding more accessible to artists, educators, beginners (and anyone else). Their convenient online editor can be found here . When using p5.js, a computer program is referred to as a 'sketch' whose visual components appear on a 'canvas'.

What follows is a short tutorial for creating and understanding a sketch that 'moves an object horizontally'.

  1. Two Parts to Every Sketch: Setup() and Draw()
  2. Setup() and Draw() in Action:
    • In the editor below, type the following in setup():
      createCanvas(300, 200);
      background(220);
    • Now type the following in draw(): circle(mouseX, mouseY, 30);
    • Press 'play' to run your sketch and move your mouse over the canvas.
    • Modify setup() to the following: createCanvas(300, 200);
    • Modify draw() to the following:
      background(220);
      circle(mouseX, mouseY, 30);
    • Press 'play' to run your sketch and move your mouse over the canvas.
    Sample Solution(s)
  3. Constant Motion: Changing position every frame creates the illusion of motion.
    • In the editor below, type the following before setup(): let posX = -50;
    • Type the following in setup(): createCanvas(600, 200);
    • Now type the following in draw():
      background(220);
      translate(width/2, height/2);
      square(posX, 0, 10);
      posX += 1;
    • Press 'play' to run your sketch.
    • Change the 1; in posX += 1; to several other values (and press 'play'), and observe what happens (*try negative values too!)
    Sample Solution
  4. Constant Acceleration: Changing velocity every frame creates the illusion of acceleration.
    • In the editor below, type the following before setup():
      let posX = -200;
      let vel = 0;
    • Type the following in setup(): createCanvas(600, 200);
    • Now type the following in draw():
      background(220);
      translate(width/2, height/2);
      square(posX, 0, 10);
      posX += vel; 1
      vel += 0.01;
    • Press 'play' to run your sketch.
    • Change the 0.01; in vel += 1; to several other values, and observe what happens (*try negative values too!)
    Sample Solution
  5. Creating an End Condition: When to stop caring
    • In the editor below, type the following in draw(), after vel += -0.09;:
      if (posX >= 120)
        noLoop();
    • Press 'play' to run your sketch.
    • Try some other end conditions too (e.g. when the object reaches a certain velocity).
    Sample Solution

Big Box of Blueberries Sketch: Walkthrough + Advantages
๐Ÿ”

A big box of blueberries is pushed east by a rocket as it travels west along the dirt. The box comes to rest while passing the origin.

Full Sketch Walkthrough

  1. Define variables for properties of the box (i.e. mass, size).
  2. Define motion variables for the box and their initial values (i.e. position, velocity).
  3. Define the net force acting on the box and the box's resultant acceleration (2nd law of motion).
  4. Choose where the origin will appear on the canvas, and create the canvas.
  5. (Colour the background, draw the title, move to the origin, draw the ground, draw the origin.)
  6. Draw the box.
  7. Change the box's position according to its velocity.
  8. Change the box's velocity according to its acceleration.
  9. Define 'end' conditions and stop the sketch when the conditions are met.

Advantages

Simulation Code

Higher Complexity Example - Spring Force
๐Ÿ”

Highlight: Net force (and acceleration) changes every frame just like position and velocity (but proportional to spring displacement x).

function draw() {
  โ‹ฎ
  //motion
  posX += vel;

  //if touching spring, apply spring force
  if(posX < springStartX){
    x = springStartX - posX;
    springForce = k*x;  
    acc = springForce/mass;
    vel += acc;
  }
}

Higher Complexity Example - 1D Inelastic Collision
๐Ÿ”

Highlight: An if statement to determine if two objects collide, then an implementation of the law of conservation of momentum.

function draw() {
  โ‹ฎ
  //checking for collision, executing collision
  if (abs(m1.posX - m2.posX) < (m1.size/2 + m2.size/2)) {
    vf = (m1.mass*m1.vel + m2.mass*m2.vel) / (m1.mass + m2.mass);
    m1.vel = vf;
    m2.vel = vf;
  }
}

Higher Complexity Example - Thor's Hammer
๐Ÿ”

Highlight: A changing net force (proportional to the pendulum's angle from vertical, θ) and a collision check and implementation of the law of conservation of momentum.

function draw() {
  โ‹ฎ
  hammer.force = -hammer.mass*g*sin(hammer.theta - PI/2)/hammer.l;
  hammer.acc = hammer.force/hammer.mass;
  hammer.vel += hammer.acc;
  โ‹ฎ
  //checking for collision, executing collision
  if (abs(cart.posX - hammer.posX) < (cart.size/2 + hammer.r) && !collided) {
    vf = (cart.mass*cart.vel + hammer.mass*hammer.vel*hammer.l) / (cart.mass + hammer.mass);
    cart.vel = -vf;
    hammer.vel = vf/hammer.l;
    collided = true;
  }
  
  hammer.theta += hammer.vel; 
}

Quantitative Representations
๐Ÿ”

Quantitative (rather than qualitative) representations are also possible using deltaTime: the amount of time passed since the previous frame (in milliseconds).

Highlights:


let t = 0;

let m = 0.25  //mass, in kilograms
let w = 0.1;  //box width, in metres
let d1 = 1.5;  //initial position, in metres
let v1 = -4.5;  //initial velocity, in m/s
let Fnet = 0.9;  //net force, in Newtons
let a = Fnet/m;  //acceleration, in m/sยฒ
  โ‹ฎ

function draw() {
  โ‹ฎ  
  t += deltaTime/1000;  
  d2 = d1 + v1*t + 0.5*a*t**2;  
  v2 = v1 + a*t;
  โ‹ฎ
  
function drawBox() {
  โ‹ฎ
  square(d2*pixelsPerMetre, -w/2*pixelsPerMetre, w*pixelsPerMetre);
}

 

Sample Student Work: Soccer Ball Rolling Along VPCI Running Track


p5.js Reference: Common Functions
๐Ÿ”

Reference Example Example Description
createCanvas(x,y) createCanvas(400, 250) Creates a canvas thatโ€™s 400 pixels wide and 250 pixels tall.
background(color) background('green') Colours the entire canvas green. (n.b. Colors can be defined a number of different ways.)
translate(x, y) translate(100, 200) Moves the origin to 100 pixels from the left of the canvas and 200 pixels from the top of the canvas.
square(x, y, diameter) rectMode(CENTER)
square(10,20,30)

Draws a square with a 30 pixel diameter 10 pixels to the right of the origin and 20 pixels below the origin (rectMode(CENTER) draws the square from its center, rather then the default top-left corner). more shapes
let let animalType = "fox"; Creates a variable called animalType (and assigns a value of "fox" to it).
+= (add assign)
x += 2;
Adds 2 to the existing value of x (i.e. equivalent to x = x + 1;).
if statement
if (t > 10) {
  background('green');
}
If the variable t is greater than 10, the canvas will be painted green.

1 Technically, what is happening here is posX += vel*nFrames, where vel units are pixels/frame and nFrames = 1. So that the tutorial can be done on day 1 (and assuming neither a physics nor programming background), these details are omitted, as the purpose here is to develop a feeling for velocity and get an object moving on-screen as quickly as possible. This line can be revisited later to establish its adherence to the motion equations and how the units work out. (Thank you to whoever brought attention to this during the presentation!) back ↑