If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

Main content

Newton's laws of motion

In the final example of the last section, we saw how we could calculate a dynamic acceleration based on a vector pointing from a circle on the screen to the mouse position. The resulting motion resembled a magnetic attraction between circle and mouse, as if some force were pulling the circle in towards the mouse.
In this section, we will formalize our understanding of the concept of a force and its relationship to acceleration. Our goal, by the end of this, is to understand how to make multiple objects move around the screen and respond to a variety of environmental forces.
Before we begin examining the practical realities of simulating forces in code, let’s take a conceptual look at what it means to be a force in the real world. Just like the word “vector,” “force” is often used to mean a variety of things. It can indicate a powerful intensity, as in “She pushed the boulder with great force” or “He spoke forcefully.” The definition of force that we care about is much more formal and comes from Isaac Newton’s laws of motion:
A force is a vector that causes an object with mass to accelerate.
The good news here is that we recognize the first part of the definition: a force is a vector. Thank goodness we just spent a whole section learning what a vector is and how to program with PVectors!
Let’s look at Newton's three laws of motion in relation to the concept of a force.

Newton’s First Law

Newton’s first law is commonly stated as:
An object at rest stays at rest and an object in motion stays in motion.
However, this is missing an important element related to forces. We could expand it by stating:
An object at rest stays at rest and an object in motion stays in motion at a constant speed and direction unless acted upon by an unbalanced force.
By the time Newton came along, the prevailing theory of motion—formulated by Aristotle—was nearly two thousand years old. It stated that if an object is moving, some sort of force is required to keep it moving. Unless that moving thing is being pushed or pulled, it will simply slow down or stop. Right?
This, of course, is not true. In the absence of any forces, no force is required to keep an object moving. An object (such as a ball) tossed in the earth’s atmosphere slows down because of air resistance (a force). An object’s velocity will only remain constant in the absence of any forces or if the forces that act on it cancel each other out, i.e. the net force adds up to zero. This is often referred to as equilibrium. The falling ball will reach a terminal velocity (that stays constant) once the force of air resistance equals the force of gravity.
Diagram of two people blowing on pendulum
The pendulum doesn't move because all the forces cancel each other out (add up to a net force of zero)
In our ProcessingJS world, we could restate Newton’s first law as follows:
An object’s PVector velocity will remain constant if it is in a state of equilibrium.
Skipping Newton’s second law (arguably the most important law for our purposes) for a moment, let’s move on to the third law.

Newton’s Third Law

This law is often stated as:
For every action there is an equal and opposite reaction.
This law frequently causes some confusion in the way that it is stated. For one, it sounds like one force causes another. Yes, if you push someone, that someone may actively decide to push you back. But this is not the action and reaction we are talking about with Newton’s third law.
Let’s say you push against a wall. The wall doesn’t actively decide to push back on you. There is no “origin” force. Your push simply includes both forces, referred to as an “action/reaction pair.”
A better way of stating the law might be:
Forces always occur in pairs. The two forces are of equal strength, but in opposite directions.
Now, this still causes confusion because it sounds like these forces would always cancel each other out. This is not the case. Remember, the forces act on different objects. And just because the two forces are equal, it doesn’t mean that the movements are equal (or that the objects will stop moving).
Try pushing on a stationary truck. Although the truck is far more powerful than you, unlike a moving one, a stationary truck will never overpower you and send you flying backwards. The force you exert on it is equal and opposite to the force exerted on your hands. The outcome depends on a variety of other factors. If the truck is a small truck on an icy downhill, you’ll probably be able to get it to move. On the other hand, if it’s a very large truck on a dirt road and you push hard enough (maybe even take a running start), you could injure your hand.
What if you pushed a truck while wearing roller skates?
A man pushing a truck while wearing roller skates
Let's re-state Newton's third law for our ProcessingJS world:
If we calculate a PVector f that is a force of object A on object B, we must also apply the force—PVector.mult(f,-1);—that B exerts on object A.
We’ll see that in the world of ProcessingJS programming, we don’t always have to stay true to the above. Sometimes, such as in the case of gravitational attraction between bodies, we’ll want to model equal and opposite forces. Other times, such as when we’re simply saying, “Hey, there’s some wind in the environment,” we’re not going to bother to model the force that a body exerts back on the air. In fact, we’re not modeling the air at all! Remember, we are simply taking inspiration from the physics of the natural world, not simulating everything with perfect precision.

Newton's Second Law

And here we are at the most important law for the ProcessingJS programmer.
This law is traditionally stated as:
Force equals mass times acceleration.
Or:
F=MA
Why is this the most important law for us? Well, let’s write it a different way.
A=F/M
Acceleration is directly proportional to force and inversely proportional to mass. This means that if you get pushed, the harder you are pushed, the faster you’ll move (accelerate). The bigger you are, the slower you’ll move.
Weight vs. Mass
The mass of an object is a measure of the amount of matter in the object (measured in kilograms).
Weight, though often mistaken for mass, is technically the force of gravity on an object. From Newton’s second law, we can calculate it as mass times the acceleration of gravity (w = m * g). Weight is measured in newtons.
Density is defined as the amount of mass per unit of volume (grams per cubic centimeter, for example).
Note that an object that has a mass of one kilogram on earth would have a mass of one kilogram on the moon. However, it would weigh only one-sixth as much.
Now, in the world of ProcessingJS, what is mass anyway? Aren’t we dealing with pixels? To start in a simpler place, let’s say that in our pretend pixel world, all of our objects have a mass equal to 1. F/1 = F. And so:
A=F
The acceleration of an object is equal to force. This is great news. After all, we saw in the Vectors section that acceleration was the key to controlling the movement of our objects on screen. Position is adjusted by velocity, and velocity by acceleration. Acceleration was where it all began. Now we learn that force is truly where it all begins.
Let's use what we've learnt to build on our Mover object, which currently has position, velocity, and acceleration. Now our goal is to be able to add forces to this object, perhaps saying:
mover.applyForce(wind);
or:
mover.applyForce(gravity);
where wind and gravity are PVectors. According to Newton’s second law, we could implement this function as follows:
Mover.prototype.applyForce = function(force) {
    this.acceleration = force;
};

Force Accumulation

This looks pretty good. After all, acceleration = force is a literal translation of Newton’s second law (without mass). Nevertheless, there’s a pretty big problem here. Let’s return to what we are trying to accomplish: creating a moving object on the screen that responds to wind and gravity.
mover.applyForce(wind);
mover.applyForce(gravity);
mover.update();
mover.display();
Ok, let’s be the computer for a moment. First, we call applyForce() with wind. And so the Mover object’s acceleration is now assigned the PVector wind. Second, we call applyForce() with gravity. Now the Mover object’s acceleration is set to the gravity PVector. Third, we call update(). What happens in update()? Acceleration is added to velocity.
velocity.add(acceleration);
We’re not going to see any error in our program, but zoinks! We’ve got a major problem. What is the value of acceleration when it is added to velocity? It is equal to the gravity force. Wind has been left out! If we call applyForce() more than once, it overrides each previous call. How are we going to handle more than one force?
The truth of the matter here is that we started with a simplified statement of Newton’s second law. Here’s a more accurate way to put it:
Net Force equals mass times acceleration.
Or, acceleration is equal to the sum of all forces divided by mass. This makes perfect sense. After all, as we saw in Newton’s first law, if all the forces add up to zero, an object experiences an equilibrium state (i.e. no acceleration). Our implementation of this is through a process known as force accumulation. It’s actually very simple; all we need to do is add all of the forces together. At any given moment, there might be 1, 2, 6, 12, or 303 forces. As long as our object knows how to accumulate them, it doesn’t matter how many forces act on it.
Let's modify the applyForce() method so that we add each new force to acceleration, accumulating them:
Mover.prototype.applyForce = function(force) {
    this.acceleration.add(force);
};
Now, we’re not finished just yet. Force accumulation has one more piece. Since we’re adding all the forces together at any given moment, we have to make sure that we clear acceleration (i.e. set it to zero) before each time update() is called. Let’s think about wind for a moment. Sometimes the wind is very strong, sometimes it’s weak, and sometimes there’s no wind at all. At any given moment, there might be a huge gust of wind, say, when the user holds down the mouse:
if (mouseIsPressed) {
  var wind = new PVector(0.5, 0);
  mover.applyForce(wind);
}
When the user releases the mouse, the wind will stop, and according to Newton’s first law, the object will continue to move at a constant velocity. However, if we had forgotten to reset acceleration to zero, the gust of wind would still be in effect. Even worse, it would add onto itself from the previous frame, since we are accumulating forces!
Acceleration, in our simulation, has no memory; it is simply calculated based on the environmental forces present at a moment in time. This is different than, say, position, which must remember where the object was in the previous frame in order to move properly to the next.
The easiest way to implement clearing the acceleration for each frame is to multiply the PVector by 0 at the end of update().
Mover.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
};

Dealing with Mass

OK. We’ve got one tiny little addition to make before we are done with integrating forces into our Mover object and are ready to look at examples. After all, Newton’s second law is really F=MA, not A=F. Incorporating mass is as easy as adding a property to our object, but we need to spend a little more time here because a slight complication will emerge.
Units of Measurement
Now that we are introducing mass, it’s important to make a quick note about units of measurement. In the real world, things are measured in specific units. We say that two objects are 3 meters apart, the baseball is moving at a rate of 90 miles per hour, or this bowling ball has a mass of 6 kilograms. As we’ll see later in this course, sometimes we will want to take real-world units into consideration. However, in this section, we’re going to ignore them for the most part.
Our units of measurement here are in pixels (“These two circles are 100 pixels apart”) and frames of animation (“This circle is moving at a rate of 2 pixels per frame”). In the case of mass, there isn’t any unit of measurement for us to use. We’re just going to make up numbers. In this example, we’re arbitrarily picking the number 10. There is no unit of measurement, though you might enjoy inventing a unit of your own, like “1 moog” or “1 yurkle.”
For demonstration purposes, we’ll tie object mass to object size -- so if the object's mass is 10, we might draw a circle with radius 10. This makes it easy to visualize the mass of an object and understand the effect of mass in our programs. In the real world, however, size does not definitely indicate mass. A small metal ball could have a much higher mass than a large balloon due to its higher density.
Mass is a scalar (float), not a vector, as it’s just one number describing the amount of matter in an object. We could be fancy about things and compute the area of a shape as its mass, but it’s simpler to begin by saying, “Hey, the mass of this object is…um, I dunno…how about 10?”
var Mover = function() {
    this.mass = 10;
    this.position = new PVector(random(width), random(height));
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
};
This isn’t so great since things only become interesting once we have objects with varying mass, but it’ll get us started. Where does mass come in? We use it while applying Newton’s second law to our object.
Mover.prototype.applyForce = function(force) {
  force.div(this.mass);
  this.acceleration.add(force);
};
Yet again, even though our code looks quite reasonable, we have a fairly major problem here. Consider the following scenario with two Mover objects, both being blown away by a wind force.
var m1 = new Mover();
var m2 = new Mover();

var wind = new PVector(1, 0);

m1.applyForce(wind);
m2.applyForce(wind);
Again, let’s be the computer. m1.applyForce() receives the wind force (1,0), divides it by mass (10), and adds it to acceleration.
codewind
var wind = new PVector(1, 0);(1, 0)
m1.applyForce(wind)(0.1, 0)
OK. Moving on to object m2. It also receives the wind force—(1,0). Wait. Hold on a second. What is the value of the wind force? Taking a closer look, the wind force is actually now (0.1,0)!
Do you remember this little tidbit about working with objects? In JavaScript, an variable that holds an object (like a PVector) is actually holding a pointer to that object in memory. When you pass the object to a function, you aren't passing a copy- you're passing the original pointer. So if a function makes a change to that object (like it does here by dividing by mass), then that object is permanently changed!
That's why things go awry here. We don’t want m2 to receive a force divided by the mass of object m1. We want it to receive that force in its original state—(1,0). And so we must protect ourselves and make a copy of the PVector f before dividing it by mass.
Fortunately, the PVector object has a convenient method for making a copy—get(). get() returns a new PVector object with the same data. And so we can revise applyForce() as follows:
Mover.prototype.applyForce = function(force) {
    var f = force.get();
    f.div(this.mass);
    this.acceleration.add(f);
};
Alternatively, we could re-write the method using the static version of div(), using what we learnt about static functions from the previous section:
Mover.prototype.applyForce = function(force) {
  var f = PVector.div(force, this.mass);
  this.acceleration.add(f);
};
The important thing is to find a way to not affect that original force vector, so that it can be applied to multiple Mover objects.

Creating Forces

We know what a force is (a vector), and we know how to apply a force to an object (divide it by mass and add it to the object’s acceleration vector). What are we missing? Well, we have yet to figure out how we get a force in the first place. Where do forces come from?
Throughout this section, we'll look at two methods for creating forces in our ProcessingJS world:
  • Make up a force! After all, you are the programmer, the creator of your world. There’s no reason why you can’t just make up a force and apply it.
  • Model a force! Yes, forces exist in the real world. And physics textbooks often contain formulas for these forces. We can take these formulas, translate them into source code, and model real-world forces in ProcessingJS.
The easiest way to make up a force is to just pick a number. Let’s start with the idea of simulating wind. How about a wind force that points to the right and is fairly weak? Assuming a Mover object m, our code would look like:
var wind = new PVector(0.01, 0);
m.applyForce(wind);
The result isn’t terribly interesting, but it is a good place to start. We create a PVector object, initialize it, and pass it into an object (which in turn will apply it to its own acceleration). If we wanted to have two forces, perhaps wind and gravity (a bit stronger, pointing down), we might write the following:
var wind = new PVector(0.01, 0);
var gravity = new PVector(0, 0.1);
m.applyForce(wind);
m.applyForce(gravity);
Now we have two forces, pointing in different directions with different magnitudes, both applied to object m. We’re beginning to get somewhere. We’ve now built a world for our objects in ProcessingJS, an environment to which they can actually respond.
Here's what our program looks like, when we put that all together:
Woo! We've covered a lot, but now we can do so much. Keep going - learn to use the force!

This "Natural Simulations" course is a derivative of "The Nature of Code" by Daniel Shiffman, used under a Creative Commons Attribution-NonCommercial 3.0 Unported License.

Want to join the conversation?

  • winston default style avatar for user 𝗣𝗼𝗶𝗻𝘁
    I haven't gone into physics yet. Should I wait until I do? Is it OK to keep going? Should I find something on KA about physics?
    (10 votes)
    Default Khan Academy avatar avatar for user
  • piceratops ultimate style avatar for user The Space Goat
    wait- the force of gravity doesn't care about the mass of something, right? a truck in a vacuum will fall just as fast as a feather. so, gravity seems like a special type of force. and wind- it exerts more force of there is more area facing into the wind. a less dense object will be much more affected by the wind than a more dense one. I understand the wind problem; we don't even have a property for "volume" or "density" or anything, but increasing the mass really should not make gravity less effective.
    (6 votes)
    Default Khan Academy avatar avatar for user
    • piceratops seed style avatar for user samsul.h3.14
      That's not quite accurate. The FORCE of gravity IS affected by mass. A truck feels a greater gravitational attraction than a human, but the ACCELERATION caused by gravity is what's unaffected by mass. So a truck and a human will accelerate at the same rate (if there's no air resistance, of course).
      (6 votes)
  • male robot johnny style avatar for user techmasterau
    I'm stuck on step 2 of the next challenge, here's my code:

    var Balloon = function() {
    this.mass = 1;
    this.height = 100;
    this.width = 70;
    this.position = new PVector(width/2, height-this.height/2-10);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
    };

    Balloon.prototype.applyForce = function(force) {
    var f = PVector.div(force, this.mass);
    this.acceleration.add(f);
    };

    Balloon.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    };

    Balloon.prototype.display = function() {
    stroke(0);
    strokeWeight(2);
    fill(0, 255, 60);
    line(this.position.x, this.position.y, this.position.x, this.position.y + this.height*2);
    ellipse(this.position.x, this.position.y, this.width, this.height);
    };

    Balloon.prototype.checkEdges = function() {
    if (this.height.y/2 < 0) {
    this.velocity.y *= -1;
    }
    };


    var m = new Balloon();

    draw = function() {
    background(224, 224, 224);

    m.update();
    m.display();
    m.checkEdges();
    };

    var pv = new PVector (0, -1);
    m.applyForce(pv);


    What is wrong with it?
    (4 votes)
    Default Khan Academy avatar avatar for user
    • spunky sam orange style avatar for user Elder Fauth
      There are some problems:
      You don't have this line:var gravity = new PVector(1,0); in the Balloon function.
      Also, in the check edges function, you are checking the wrong thing; You should not be checking if this.height.y/2 < 0. You should be checking if the y position is less than the height divided by two.
      Finally, you don't need the var pv = new PVector (0, -1), and because you don't need it, the m.applyForce(pv); line should just be m.applyForce(pv);

      Hope that helps!
      (9 votes)
  • hopper cool style avatar for user Chocolate Milk Productions
    For some reason, it shows an error that says the balloon goes into the ceiling a bit. I have adjusted the code in a lot of different ways, but they all do not work. Here is my code:
    var Balloon = function() {
    this.mass = 1;
    this.height = 100;
    this.width = 70;
    this.position = new PVector(width/2, height-this.height/2-10);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
    };

    Balloon.prototype.applyForce = function(force) {
    var f = PVector.div(force, this.mass);
    this.acceleration.add(f);
    };

    Balloon.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    };

    Balloon.prototype.display = function() {
    stroke(0);
    strokeWeight(2);
    fill(255, 0, 0);
    line(this.position.x, this.position.y, this.position.x, this.position.y + this.height*2);
    ellipse(this.position.x, this.position.y, this.width, this.height);
    };

    Balloon.prototype.checkEdges = function() {
    if (this.position.y < 0 + this.height / 2) {
    this.velocity.y *= -0.75;
    }
    };


    var m = new Balloon();

    draw = function() {
    background(224, 224, 224);
    var boyancy = new PVector(0, -0.1);
    m.applyForce(boyancy);

    m.update();
    m.display();
    m.checkEdges();
    };


    I just don't get it.
    (4 votes)
    Default Khan Academy avatar avatar for user
  • leaf yellow style avatar for user ༺ℛ𝒶𝒸𝒽ℯ𝓁༻ [inactive]
    I've finished the next Challenge: "Floating balloon" It let me pass, but the balloon still drifted away after some time. Is that supposed to happen? Here's my code.

    var helium = new PVector(0,-1);

    var Balloon = function() {
    this.mass = 1;
    this.height = 100;
    this.width = 70;
    this.position = new PVector(width/2, height-this.height/2-10);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
    };

    Balloon.prototype.applyForce = function(force) {
    var f = PVector.div(force, this.mass);
    this.acceleration.add(f);
    };

    Balloon.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    };

    Balloon.prototype.display = function() {
    stroke(0);
    strokeWeight(2);
    fill(255, 0, 0);
    line(this.position.x, this.position.y, this.position.x, this.position.y + this.height*2);
    ellipse(this.position.x, this.position.y, this.width, this.height);
    };

    Balloon.prototype.checkEdges = function() {

    if(this.position.y < this.height/2) {

    this.velocity.y *= -1;

    }

    };


    var m = new Balloon();

    draw = function() {
    background(224, 224, 224);
    m.applyForce(helium);
    m.update();
    m.display();
    m.checkEdges();
    };

    (5 votes)
    Default Khan Academy avatar avatar for user
  • duskpin ultimate style avatar for user COOLpro
    I can't figure out what to do in step two this is my code


    var Balloon = function() {
    this.mass = 1;
    this.height = 100;
    this.width = 70;
    this.position = new PVector(width/2, height-this.height/2-10);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
    };

    Balloon.prototype.applyForce = function(force) {
    var f = PVector.div(force, this.mass);
    this.acceleration.add(f);
    };

    Balloon.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    };

    Balloon.prototype.display = function() {
    stroke(0);
    strokeWeight(2);
    fill(255, 0, 0);
    line(this.position.x, this.position.y, this.position.x, this.position.y + this.height*2);
    ellipse(this.position.x, this.position.y, this.width, this.height);
    };

    Balloon.prototype.checkEdges = function() {
    };


    var m = new Balloon();

    draw = function() {
    background(224, 224, 224);

    m.update();
    m.display();
    m.checkEdges();
    };
    var d = new PVector(0, -7);
    m.applyForce(d);
    Balloon.prototype.checkEdges = function() {
    if (1 < -99) {
    this.velocity.y *= -3;
    }
    };
    (4 votes)
    Default Khan Academy avatar avatar for user
  • leaf blue style avatar for user CompoundMaster
    I'm stuck on step two, and it says in orange text:
    It looks like you're hard coding the height of the balloon. Can you make a check that works for any balloon height?

    Here is my code for step two:
    Balloon.prototype.checkEdges = function() {
    if (this.position.y < 45) {
    this.velocity.y *= -1;
    }
    };

    Does anyone know what's wrong with my code?
    (4 votes)
    Default Khan Academy avatar avatar for user
  • hopper jumping style avatar for user redpandamath
    In Challenge: Floating balloon, I can't get past the second step. Here's my code:
    var Balloon = function() {
    this.mass = 1;
    this.height = 100;
    this.width = 70;
    this.position = new PVector(width/2, height-this.height/2-10);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
    };

    Balloon.prototype.applyForce = function(force) {
    var f = PVector.div(force, this.mass);
    this.acceleration.add(f);
    };

    Balloon.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    };

    Balloon.prototype.display = function() {
    stroke(0);
    strokeWeight(2);
    fill(255, 0, 0);
    line(this.position.x, this.position.y, this.position.x, this.position.y + this.height*2);
    ellipse(this.position.x, this.position.y, this.width, this.height);
    };

    Balloon.prototype.checkEdges = function() {
    if (this.position.y < ) {
    this.velocity.y *= -1;
    }
    };


    var m = new Balloon();
    draw = function() {
    background(224, 224, 224);

    m.update();
    m.display();
    m.checkEdges();
    };

    var d = new PVector(0, -7);
    m.applyForce(d);

    I need something in the blank space of the Ballon.prototype.checkEdges part. Thanks in advance!
    (3 votes)
    Default Khan Academy avatar avatar for user
  • marcimus pink style avatar for user cristina.hernando
    "The easiest way to implement clearing the acceleration for each frame is to multiply the PVector by 0 at the end of update()" (said in the lesson)
    Why not this.acceleration= 0. Isn't it easier?
    (1 vote)
    Default Khan Academy avatar avatar for user
    • leaf green style avatar for user sgjmrt dfghdgh
      Accelleration is a PVector with x and y components, you need to set each of them to 0:
      this.acceleration.x = 0;
      this.acceleration.y = 0;

      Or you could use this.acceleration = new PVector(0, 0);.

      Else you will get in trouble when trying to add a force vector to the acceleration.
      (3 votes)
  • winston default style avatar for user Victor Gutierrez
    I am a bit stunned because in the last example of this lesson the ball doesn't rise as high as the initial position and gradually loses height, the same goes in the x direction with the wind. If we are simulating elastic collisions with no loss of energy, shouldn't the ball rise to the same exact position?? and also in the x-direction shouldn't reach the same initial x position??
    (2 votes)
    Default Khan Academy avatar avatar for user