# Physics

## Point and spring simulation

left click to create a point
right click to select a point
select multiple points to connect them
hold down "d" and move mouse to drag

# Introduction

A few years ago I wrote a little website called chubmarine.com. It was a physics simulation type thing, much like the one that's on this page. It's no longer active, but I thought it would be interesting to write about anyway.

While it was cool to get attention online, I think the event that had the most impact on me relating to the site was a conversation I had with my mom right after I launched it. Apparently, what I thought was a clever portmanteau of my last name and the word submarine was actually a euphemism for something or other that is perhaps not the most appropriate name for a physics simulation. My mom found this out when she googled "chubmarine", and the first result was a link to urbandictionary.com. You can probably guess how that discussion went.

# The Nerdy Stuff

Simulating points and springs may seem super complicated and math/physics intensive, however it's actually quite simple to get up and running in very few lines of code. I won't go into a detailed explanation of each and every single feature, but I'll try to highlight the most important bits.

## Vectors

You might be familiar with vectors from math class, but just as a refresher here is a short video which explains the concept suitably well.

In essence, a vector is an object that represents both direction and magnitude. In our simulation, vectors are instances of a class that has two properties: `x` and `y`.

Vectors are a very convenient way to represent the positions and velocities of our points. The `Vector` class in this simulation contains a few helper functions, for example a `length` function to get the length of the vector, or a `normalize` function which creates a vector in the same direction as the original but with a length of 1.

## Game Loop

In video game programming there exists the concept of the game loop, which is the infinitely repeating sequence of recieving input, changing the game state, and drawing the game on the screen. As a consequence of this particular simulation being written in JavaScript, we can't actually have a real infinite loop, since that would freeze the page (I found this out the hard way), so instead we have to emulate an infinite loop using callbacks and the `requestAnimationFrame` function.

The simulation is started by calling the following `start` function, which runs a single step of the game, and then schedules itself to be run again.

``````Simulation.prototype.start = function () {
this.lastFrameTime = this.lastFrameTime || new Date();
var currentTime = new Date();

// difference between the time that the last frame
// was run and the current time in milliseconds
var delta = currentTime - this.lastFrameTime;

// number that we multiply displacements by to
// compensate for going faster/slower than 60fps
var adjust = (1000 / 60) / delta;

this.lastFrameTime = currentTime;

var that = this;

requestAnimationFrame(function () {
that.start();
});
};``````

Notice how we can compensate for the app running slower or faster than we want by calculating the difference between the times at which the current and last frames were run.

The `tick` function is as follows:

``````Simulation.prototype.tick = function (adjust) {
this.clear();

// first we update the game state
for (var i = 0; i < this.springs.length; i++) {
}

for (var i = 0; i < this.points.length; i++) {
}

// then we draw it to the screen
for (var i = 0; i < this.springs.length; i++) {
this.springs[i].draw(this.context);
}

for (var i = 0; i < this.points.length; i++) {
this.points[i].draw(this.context);
}
};``````

The arrays `springs` and `points` are defined elsewhere in the program. `context` is an instance of the CanvasRenderingContext2D class, which allows us to draw graphics on an HTML canvas. The `clear` function clears the canvas so that it is empty before the game draws another frame.

## Points

The point class is defined as follows:

``````function Point(x, y) {
this.pos = new Vector(x, y);
this.vel = new Vector(0, 0);
this.highlighted = false;
this.dragged = false;
}

Point.size = 10;
Point.friction = 0.01;
Point.bounceResistance = 0.5;
Point.airResistance = 1.025;
Point.mass = 0.2;``````

Probably the most important part of the `Point` class is the `update` function, which, as you can probably infer from the name, updates the state of the point.

``````Point.prototype.update = function (context, adjust) {
if (!this.dragged) {
this.vel = this.vel.divide(Point.airResistance);
}

this.collideWithWalls(context);
};``````

You may be wondering why we check for whether or not the point is dragged. In order for the user to be able to drag a point, it has to be at the position of the mouse exactly. Therefore, while it's being dragged, it does not follow the laws of physics.

## Collisions

Implementing collisions was a tricky problem. One might be tempted to simply reverse the velocity of a point when it "hits" a wall, however that may cause the point to get stuck, as its velocity is switched back and forth forever. After a few iterations, the following algorithm seemed to be the most effective at modeling collisions. In order to collide the points with the walls, or edges of the canvas, the following steps are taken for each point:

1. Check if the point is outside the canvas
2. If it is, then:
1. Move it back in the canvas via the closest wall
2. Set the relevant component of its velocity to point towards the inside of the canvas
3. Dampen the relevant component of its velocity to simulate loss of energy
4. Dampen the other component of its velocity to simulate friction

Here's the implementation:

``````Point.prototype.collideWithWalls = function (context) {
if (this.pos.x < Point.size / 2) { // if too far left.
this.pos.x = Point.size / 2;
this.vel.x = Math.abs(this.vel.x) * (1 - Point.bounceResistance);
this.vel.y *= 1 - Point.friction;
}

if (this.pos.y < Point.size / 2) { // if too far up.
this.pos.y = Point.size / 2;
this.vel.y = Math.abs(this.vel.y) * (1 - Point.bounceResistance);
this.vel.x *= 1 - Point.friction;
}

if (this.pos.x > context.canvas.width - Point.size / 2) { // if too far to the right.
this.pos.x = context.canvas.width - Point.size / 2;
this.vel.x = Math.abs(this.vel.x) * -1 * (1 - Point.bounceResistance);
this.vel.y *= 1 - Point.friction;
}

if (this.pos.y > context.canvas.height - Point.size / 2) { // if too far to the bottom.
this.pos.y = context.canvas.height - Point.size / 2;
this.vel.y = Math.abs(this.vel.y) * -1 * (1 - Point.bounceResistance);
this.vel.x *= 1 - Point.friction;
}
}``````

As you can see it's not the most elegant implementation with a lot of repetition, but it gets the job done.

## Springs

In actual real physics the motion of a spring is modeled using Hooke's Law. Essentially what it boils down to is that the force that the spring exerts on an object is proportional to its extension from rest. If a spring is squished or stretched more, it should exert proportionally more force.

The `Spring` class, which attempts to model the action of a real spring, is defined as follows:

``````function Spring(firstPoint, secondPoint) {
this.first = firstPoint;
this.second = secondPoint;
this.restLength = 100;
this.springyness = 16;
}``````

The `update` function of the `Spring` class handles the implementation details of Hooke's Law.

``````Spring.prototype.update = function (context, adjust) {
var difference = this.second.pos.subtract(this.first.pos);
var distance = this.length();

var extension = distance - this.restLength;