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

Modeling gravity and friction

Now, let's try to make our forces a little bit more true to the real world, by improving the gravity of the last example and introducing a friction force.

Gravity on Earth

You may have noticed something woefully inaccurate about this last example. The smaller the circle, the faster it falls. There is a logic to this; after all, we just stated (according to Newton’s second law) that the smaller the mass, the higher the acceleration.
But this is not what happens in the real world. If you were to climb to the top of the Leaning Tower of Pisa and drop two balls of different masses, which one will hit the ground first? According to legend, Galileo performed this exact test in 1589, discovering that they fell with the same acceleration, hitting the ground at the same time.
Why is this? As we will see later in this course, the force of gravity is calculated relative to an object’s mass. The bigger the object, the stronger the force. So if the force is scaled according to mass, the mass is canceled out when force is divided by mass. We can implement this in our program by multiplying our made-up acceleration (due to gravity) by mass:
for (var i = 0; i < movers.length; i++) {
    gravity.set(0, 0.1 * movers[i].mass);
    movers[i].applyForce(gravity);
    …
}
Because the strength of the wind force is independent of mass in our simulation, the mass does not cancel out and the smaller objects still accelerate to the right more quickly.
Making up forces will actually get us quite far. The world of ProcessingJS is a pretend world of pixels and you are its master. So whatever you deem appropriate to be a force, well by golly, that’s the force it should be. Nevertheless, there may come a time where you find yourself wondering: “But how does it really all work?”
Open up any high school physics textbook and you will find some diagrams and formulas describing many different forces—gravity, electromagnetism, friction, tension, elasticity, and more. Or, hey, browse the physics lessons on Khan Academy. In this section, we’re going to look at two of those forces—friction and gravity. The point we’re making here is not that friction and gravity are fundamental forces that you always need to have in all your ProcessingJS programs. Rather, we want to evaluate these two forces as case studies for the following process:
  • Understanding the concept behind a force
  • Deconstructing the force’s formula into two parts:
    • How do we compute the force’s direction?
    • How do we compute the force’s magnitude?
  • Translating that formula into ProcessingJS code that calculates a PVector to be sent through our Mover's applyForce() function.
If we can follow the above steps with two forces, then hopefully if you ever find yourself Googling “atomic nuclei weak nuclear force” at 3 a.m., you will have the skills to take what you find and adapt it for ProcessingJS programs.

Dealing with formulae

OK, in a moment we’re going to write out the formula for friction. This isn’t the first time we’ve seen a formula in this course; we just finished up our discussion of Newton’s second law, F=M×A​ (or force = mass * acceleration). We didn’t spend a lot of time worrying about this formula because it’s a nice and simple one. Nevertheless, it’s a scary world out there. Just take a look at the equation for a “normal” distribution, which we covered (without looking at the formula) in the Introduction.
f(x,μ,σ)=1σ2πe((xμ)22σ2)
What we’re seeing here is that formulas like to use a lot of symbols (quite often letters from the Greek alphabet). Let’s take a look at the formula for friction.
Friction=µNv^
If it’s been a while since you’ve looked at a formula from math or physics, there are three key points that are important to cover before we move on.
  • Evaluate the right side, assign to the left side. This is just like in code! What we’re doing here is evaluating the right side of the equation and assigning it to the left. In the case above, we want to calculate the force of friction—the left side tells us what we want to calculate and the right side tells us how to do it.
  • Are we talking about a vector or a scalar? It’s important for us to realize that in some cases, we’ll be looking at a vector; in others, a scalar. For example, in this case the force of friction is a vector. We can see that by the arrow above the word “friction.” It has a magnitude and direction. The right side of the equation also has a vector, as indicated by the symbol v^, which in this case stands for the velocity unit vector.
  • When symbols are placed next to each other, we mean for them to be multiplied. The formula above actually has four elements: -1, µ, N, and v^. We want to multiply them together and read the formula as: Friction=µNv^

Friction

Let’s begin with friction and follow our steps.
Friction is a dissipative force. A dissipative force is one in which the total energy of a system decreases when an object is in motion. Let’s say you are driving a car. When you press your foot down on the brake pedal, the car’s brakes use friction to slow down the motion of the tires. Kinetic energy (motion) is converted into thermal energy (heat). Whenever two surfaces come into contact, they experience friction. A complete model of friction would include separate cases for static friction (a body at rest against a surface) and kinetic friction (a body in motion against a surface), but for our purposes, we are only going to look at the kinetic case.
Here’s the formula for friction, along with an illustration: 
An illustration of someone sledding, alongside the formula for friction, Friction =−1µN*v
Now it’s now up to us to separate this formula into two components that determine the direction of friction as well as the magnitude. Based on the diagram above, we can see that friction points in the opposite direction of velocity. In fact, that’s the part of the formula that says 1v^, or -1 times the velocity unit vector. In ProcessingJS, this would mean taking the velocity vector, normalizing it, and multiplying by -1.
var friction = velocity.get();
friction.normalize();
// Let’s figure out the direction of the friction force 
// (a unit vector in the opposite direction of velocity)
friction.mult(-1);
Notice two additional steps here. First, it’s important to make a copy of the velocity vector, as we don’t want to reverse the object’s direction by accident. Second, we normalize the vector. This is because the magnitude of friction is not associated with how fast it is moving, and we want to start with a friction vector of magnitude 1 so that it can easily be scaled.
According to the formula, the magnitude is μN. μ, the Greek letter mu (pronounced “mew”), is used here to describe the coefficient of friction. The coefficient of friction establishes the strength of a friction force for a particular surface. The higher it is, the stronger the friction; the lower, the weaker. A block of ice, for example, will have a much lower coefficient of friction than, say, sandpaper. Since we’re in a pretend ProcessingJS world, we can arbitrarily set the coefficient based on how much friction we want to simulate.
var c = 0.01;
Now for the second part: N. That N refers to the normal force, the contact force that's exerted by objects touching each other. More specifically, it's the perpendicular component of that contact force.
Think of a vehicle driving along a road. The vehicle pushes down against the road, and Newton’s third law tells us that the road in turn pushes back against the vehicle. That’s the normal force. For a simple case of an object moving horizontally, the normal force is equal to mass multiplied by the gravitational force, Fn=mg. That means a lightweight sports car would exert a smaller normal force, and thus experience less friction than a massive tractor trailer truck.
In the sledding diagram above, the object is moving along a surface at an angle, so computing the normal force is a bit more complicated because it doesn’t point in the same direction as gravity. For that, we’d need to know something about angles and trigonometry.
For now, our goal will be a "good enough" simulation for our ProcessingJS programs, not a perfect simulation. For example, we can make friction work with the assumption that the normal force will always have a magnitude of 1. Our N is then simply:
var normal = 1;
When we get into trigonometry in the next section, we’ll revisit these details and make our friction example a bit more sophisticated.
Now that we have both the magnitude and direction for friction, we can put it all together…
var c = 0.01;
var normal = 1;
var frictionMag = c * normal;
var friction = movers[i].velocity.get();
friction.mult(-1);
friction.normalize();
friction.mult(frictionMag);
…and add it to our “forces” example, where many objects experience wind, gravity, and now friction:
If you watch that program run for a while, you’ll notice that the circles move less and less, and tend to hang around one area. Since friction continuously pushes against the object in the opposite direction of its movement, the object continuously slows down. This can be either a useful technique or a problem, depending on the goals of your visualization.

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?

  • hopper happy style avatar for user William
    How would I model friction if the velocity is less than one?
    (10 votes)
    Default Khan Academy avatar avatar for user
  • blobby green style avatar for user Wings94
    I don't understand this:
    "As we will see later in this course, the force of gravity is calculated relative to an object’s mass. The bigger the object, the stronger the force. So if the force is scaled according to mass, it is canceled out when acceleration is divided by mass."
    (5 votes)
    Default Khan Academy avatar avatar for user
    • old spice man green style avatar for user Bob Lyon
      It is saying that the force due to gravity is a standard gravitation constant g times the mass of the object m, or
         F = gm
      In beginners' Physics we all learn(ed) the relationship amoung force F, mass m and acceleration a as being
         F = ma
      substituting for F we get a new equation
         gm = ma
      so both sides of the new equation can be divided by the mass (the mass "can be cancelled out") rendering
         g = a
      Clear as mud, right?
      https://en.wikipedia.org/wiki/Standard_gravity
      (24 votes)
  • piceratops ultimate style avatar for user The Space Goat
    wait, so friction doesn't increase with velocity? A) I thought that was the "v" in the formula, and B) it seems to make sense for the decceleration (is that a word?) to be higher when it's going faster. and C) I've been doing more friction for more speed in coding my whole life XP but the code in here NORMALIZES it and cares only about μ and the "normal." Please, tell me, What is the v in the formula??
    (7 votes)
    Default Khan Academy avatar avatar for user
    • leaf red style avatar for user James McNally
      v here is indeed the normalised vector symbol of the velocity, so it has a magnitude of one but a direction in which the object is travelling. So for the sledge diagram its downhill. However, friction is AGAINST the direction of motion, so there is a -1 at the beginning of our equation.

      And just so you know you aren't entirely insane, drag does increase with speed when travelling through a fluid, like air or water. So as I skydive out of an airplane as I increase in velocity until the force of my weight downwards is equal to the drag of the air and I cannot go any faster. This is known as terminal velocity! https://en.wikipedia.org/wiki/Terminal_velocity

      However for the purposes of this we have ignored any kind of drag from travelling through the air (the wind force added is NOT drag) and so the velocity won't make an effect on the friction of the surface on the floor. Apologies for the essay!
      (12 votes)
  • leaf blue style avatar for user JibrilAbdi
    What does
    .get();
    and
    .normalize();
    do. The documentation was no help to me.
    (6 votes)
    Default Khan Academy avatar avatar for user
  • leaf blue style avatar for user CompoundMaster
    I'm on step 3 on Speed Bumps, but I have no idea what to put in this.
    if (bump.isUnder(boards[i])) {

    }
    (4 votes)
    Default Khan Academy avatar avatar for user
  • piceratops tree style avatar for user Randy Childs
    I believe the article's definition of friction should be amended slightly.

    "Friction is a dissipative force. A dissipative force is one in which the total energy of a system decreases when an object is in motion." (emphasis added)

    It should be total mechanical energy instead of total energy. I think it's important to reinforce the law of conservation of energy here: the total energy of any closed system is always constant. The mechanical energy lost to friction is converted to other forms of energy, such as heat and sound, as the article suggests in the helpful example of applying the brakes of a car. That "lost" energy still exists in the environment surrounding the moving object(s). It merely exists in forms that are not practically available for conversion back into kinetic energy, which is why friction tends to cause objects to decelerate to rest over time.

    This is a very minor point of contention, and it doesn't at all affect my great appreciation for the educational content on this site.
    (6 votes)
    Default Khan Academy avatar avatar for user
  • leafers seed style avatar for user danilomacari
    does this code make my machine slower? i tend to leave the page open for a while, and apparently the machine gets slower with time, to the point of crashing my browser (Chrome)
    (3 votes)
    Default Khan Academy avatar avatar for user
  • hopper cool style avatar for user Ouwrei
    I need help in the next challenge
    (3 votes)
    Default Khan Academy avatar avatar for user
    • leaf green style avatar for user Anas
      Sorry for waiting 3 years.
      var Skateboard = function(x, m) {
      this.mass = m;
      this.position = new PVector(x, 0);
      this.velocity = new PVector(0, 0);
      this.acceleration = new PVector(0, 0);
      this.width = this.mass*16;
      this.height = this.mass*16*2;
      };

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

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

      Skateboard.prototype.display = function() {
      stroke(0);

      fill(184, 184, 37);
      strokeWeight(1);
      ellipse(this.position.x, this.position.y+this.height/5, this.width/10, this.height/10);
      ellipse(this.position.x+this.width, this.position.y+this.height/5, this.width/10, this.height/10);
      ellipse(this.position.x, this.position.y+this.height*0.80, this.width/10, this.height/10);
      ellipse(this.position.x+this.width, this.position.y+this.height*0.80, this.width/10, this.height/10);

      fill(71, 71, 71);
      rect(this.position.x, this.position.y, this.width-2, this.height, 30);
      };

      var SpeedBump = function(y, height) {
      this.x = 50;
      this.y = y;
      this.width = 300;
      this.height = height;
      };

      SpeedBump.prototype.display = function() {
      fill(40, 40, 40, 100);
      noStroke();
      rect(this.x, this.y, this.width, this.height);
      };

      SpeedBump.prototype.isUnder = function(skateboard) {
      return skateboard.position.x >= this.x &&
      skateboard.position.x <= this.x + this.width &&
      skateboard.position.y >= this.y &&
      skateboard.position.y <= this.y + this.height;
      };


      var boards = [];
      boards.push(new Skateboard(100, 1.5));
      boards.push(new Skateboard(150, 2.0));
      boards.push(new Skateboard(200, 2.5));
      var bump = new SpeedBump(30,60);

      draw = function() {

      // bump.display();
      background(6, 97, 21);
      fill(140, 140, 140);
      rect(50, 0, 300, height);
      fill(255, 255, 255);
      rect(190, 0, 10, height);
      bump.display();

      for (var i = 0; i < boards.length; i++) {
      var accel = new PVector(0, 0.1*boards[i].mass);


      var c = 0.01;
      if(bump.isUnder(boards[i]))
      {
      c = 0.7;
      }
      var normal = 1;
      var frictionMag = c * normal;
      var friction = boards[i].velocity.get();
      friction.mult(-1);
      friction.normalize();
      friction.mult(frictionMag);
      boards[i].applyForce(friction);

      boards[i].applyForce(accel);
      boards[i].update();
      boards[i].display();
      }
      };
      (4 votes)
  • aqualine ultimate style avatar for user MegaStarWarsFan789
    Isn't μ pronounced "moo" instead of "mew"? I'm currently learning Koine Greek, and, years ago, when I learned the Greek Alphabet, the books I used pronounced it like "moo". Is modern Greek different? I guess it's not important, I'm just curious. :)
    (3 votes)
    Default Khan Academy avatar avatar for user
    • aqualine ultimate style avatar for user AD Baker
      I have heard it both ways. I don't have as much experience with Greek, but I can tell you that Latin is pronounced differently in Europe than it is in the US and Ecclesiastical Latin is different from Academic Latin. Greek also has the additional twist of being a modern language as well as an ancient language.

      I wouldn't spend a lot of time trying to reconcile modern Greek with Math. If you want to pronounce it "moo," go for it.
      (2 votes)
  • starky ultimate style avatar for user Davy _ King
    SOMEONE HELP ME WITH THE NEXT CHALLENGE!! plz

    var Skateboard = function(x, m) {
    this.mass = m;
    this.position = new PVector(x, 0);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
    this.width = this.mass*16;
    this.height = this.mass*16*2;
    };

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

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

    Skateboard.prototype.display = function() {
    stroke(0);

    fill(184, 184, 37);
    strokeWeight(1);
    ellipse(this.position.x, this.position.y+this.height/5, this.width/10, this.height/10);
    ellipse(this.position.x+this.width, this.position.y+this.height/5, this.width/10, this.height/10);
    ellipse(this.position.x, this.position.y+this.height*0.80, this.width/10, this.height/10);
    ellipse(this.position.x+this.width, this.position.y+this.height*0.80, this.width/10, this.height/10);

    fill(71, 71, 71);
    rect(this.position.x, this.position.y, this.width-2, this.height, 30);
    };

    var SpeedBump = function(y, height) {
    this.x = 50;
    this.y = y;
    this.width = 300;
    this.height = height;
    };

    SpeedBump.prototype.display = function() {
    fill(0, 0, 0, 100);
    noStroke();
    rect(this.x, this.y, this.width, this.height);
    };

    SpeedBump.prototype.isUnder = function(skateboard) {
    return skateboard.position.x >= this.x &&
    skateboard.position.x <= this.x + this.width &&
    skateboard.position.y >= this.y &&
    skateboard.position.y <= this.y + this.height;
    };

    var bump = new SpeedBump(140,50);
    var boards = [];
    boards.push(new Skateboard(100, 1.5));
    boards.push(new Skateboard(175, 2.0));
    boards.push(new Skateboard(300, 2.5));



    draw = function() {



    background(6, 97, 21);
    fill(140, 140, 140);
    rect(50, 0, 300, height);
    fill(255, 255, 255);
    rect(190, 0, 10, height);
    bump.display();

    for (var i = 0; i < boards.length; i++) {
    var c = 0.01; // Coefficient of friction
    if (bump.isUnder(boards [i])) {
    c = 0.5;
    }

    }


    };
    (2 votes)
    Default Khan Academy avatar avatar for user
    • aqualine ultimate style avatar for user Rudra
      You should have not deleted the code that was inside the for loop.

      It should be like this:

      for (var i = 0; i < boards.length; i++) {
      var accel = new PVector(0, 0.1*boards[i].mass);

      var c = 0.01; // Coefficient of friction
      var normal = 1;

      if (bump.isUnder(boards[i])) {
      c = 1;
      }

      var frictionMag = c * normal;
      var friction = boards[i].velocity.get();
      friction.mult(-1);
      friction.normalize();
      friction.mult(frictionMag);
      boards[i].applyForce(friction);

      boards[i].applyForce(accel);
      boards[i].update();
      boards[i].display();
      }
      (1 vote)