Examples

download zipped archive of all examples
The above zip uses the Vector3D library, while the links below include the Vector3D.java tab. The full source code for the Vector3D class is here: Vector3D.java. The library is recommended, however, if you want to mess with the Vector3D code you may want to use a tab.

Related

  • Newtonian Physics, An Online Textbook (This is long, you may find Chapter 4 to be particularly relevant to this week’s discussion.)
  • The Physics Classroom — Newton’s Laws
  • Mathematics and Physics for Programmers, Chapters 12 and 14, Danny Kodicek (suggested)
  • Newton’s Laws

    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 is defined as the amount of mass per unit of volume (grams per cubic centimeter, for example.
  • Note 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.

    First Law:
    An object at rest stays at rest unless an external force acts on the object. An object in motion stays in motion (at a constant velocity), again, unless an external force is applied.

    Second Law:
    Force = Mass * Acceleration (this is the formula for an object with a constant mass.) For our purposes, we will know the mass and the force, but want to calculate an object’s acceleration (which is proportional to the force and inversely proportional to the mass, i.e. Acceleration = Force / Mass)

    Third Law:
    All forces occur in pairs, and these two forces are equal in magnitude and opposite in direction.

    Forces acting on an object

    For our purposes, the most important law will be #2. Take the following example:

    Consider a body with the following properties:

  • Location — Point
  • Velocity — Vector
  • Acceleration — Vector
  • Mass — Scalar
  • class Thing {
      //instance variables for the class
      Vector3D loc;
      Vector3D vel;
      Vector3D acc;
      float mass;
    
      //constructor
      Thing(Vector3D a, Vector3D v, Vector3D l, float m_) {
        acc = a.copy();
        vel = v.copy();
        loc = l.copy();
        mass = m_;
      }
    

    Motion will work the same way it did in last week’s examples. For each cycle of the program, for any given object, we will do the following (with one addition from last week):

  • Increment velocity by acceleration
  • Move location by velocity
  • Reset acceleration back to zero vector < --- *NEW*
  • Render object at location
  • void update() {
      vel.add(acc);
      loc.add(vel);
      acc.setXY(0.0f,0.0f); // new!
    }
    

    We reset the acceleration to 0 here because with each cycle of the program, before updating an object’s location, we will calculate all the forces acting upon that object. For each force we will use Newton’s Second Law to calculate acceleration, acculmulating all forces together for a total acceleration of the object. Consider the following:

  • An object at LOCATION = (10,20) with a MASS = 5, and initial VELOCITY = (-3,2)
  • A WIND force to the right = (5,0)
  • A GRAVITY force downward = (0,10)
  • Here is our algorithm (remember F = M*A, so A = F / M):

    FOR ANY GIVEN TIME T:

    ACCELERATION CAUSED BY WIND = WIND / MASS = (5,0) / 5 = (1,0)
    ACCELERATION CAUSED BY GRAV = GRAV / MASS = (0,10) / 5 = (0,2)
    TOTAL ACCELERATION = (1,0) + (0,2) = (1,2)
    VELOCITY = VELOCITY + ACCELERATION = (-3,2) + (1,2) = (-2,4)
    LOCATION = LOCATION + VELOCITY = (10,20) + (-2,4) = (8,24)

    In terms of coding our object, for any given force applied to it, we need a function to receive that force as a parameter and calculate the object’s acceleration according to that force:

    void add_force(Vector3D force) {
      force.div(mass);  // Newton's second law
      acc.add(force);    // Accumulate acceleration
    }
    

    It should be noted that the inclusion of mass as a property for our body is to demonstrate Newton’s Laws with some small amount of accuracy. However, for the purposes of creating an interesting visual simulation, it is not entirely necessary (especially in the case of an example only having one object) and we could simplify our code (as we might in later examples) by excluding mass and making Acceleration = Force.

    The above example assumes we have already figured out how to calculate forces (like wind, friction, gravity, etc.) Here are some examples of forces we will examine:

    “Dissipative” Force

    A dissipative force is one where the total energy of a system decreases when an object is in motion. For example, an object traveling through a liquid (viscosity) or sliding along a surface (friction). A true model of friction would include separate cases for static friction (for a body at rest against a surface) and kinetic friction (for a body in motion against a surface), but we will consider just one case. Friction is calculated independently of an object’s speed in the opposite direction of the object’s motion, i.e.:

    Friction Force = -c * (velocity unit vector)

    where c is the “coefficient of friction”

    Drag through a liquid, however, though similar to friction, is directly related to the speed of an object. The faster an object moves, the more drag force is applied to it, i.e.:

    Viscous Force = -c * (velocity vector)

    Assume an object “t” of type Thing from our example above. If it were traveling through a liquid with a coefficient of friction of -0.02, our code to calculate and apply the force would be:

    float c = -0.02f;                           //drag coefficient
    Vector3D thingVel = t.getVel();             //velocity of our thing
    Vector3D force = Vector3D.mult(thingVel,c); //following the formula above
    t.add_force(force);                         //adding the force to our object, which will ultimately affect its acceleration
    

    Gravitational Force

    Gravity on Earth

    The gravitational pull of the earth can be treated as a special case because the distance d is approximately a constant (i.e. the radius of the earth) and for any given location, we can approximate the earth’s surface as flat (the direction of gravity is therefore the normal to the earth’s plane.)

    (G * M) / (D * D) is therefore approximately a constant –> 9.8 meters / seconds squared, the acceleration due to gravity on earth.

    Two bodies will attract each other with a force of equal magnitude (but in opposite direction — i.e. Newton’s Third Law). To calculate the force, we need:

  • G –> Gravitational Constant
  • M1, M2 –> The masses of each object, respectively
  • D –> The distance between the center points of each object
  • L1, L2 –> The location points of each object, respectively
  • Gravitational Force Magnitude = (G * M1 * M2) / (D * D)

    To calculate the direction of the force, we can simply examine the unit vector difference between the two points, i.e.

    Gravitational Force Direction (for Object #1) = (L2 - L1) / ||L2 - L1||

    In order to create code for gravitational force, we can add another function to our Thing class, which takes another Thing object as its parameter and calculates its own gravitational pull towards that object, i.e.

    Vector3D calcGravForce(Thing t) {
      Vector3D dir = Vector3D.sub(t.getLoc(),loc);      //calculate direction of force
      float d = dir.magnitude();                        //distance between objects
      dir.normalize();                                  //normalize vector (distance doesn't matter here, we just want this vector for direction)
      float force = (G * mass * t.getMass()) / (d * d); //calculate gravitional force magnitude
      dir.mult(force);                                  //get force vector --> magnitude * direction
      return dir;
    }
    

    Now, in our main program, assume we have an array of Things:

    final int MAX = 5;
    Thing[] t = new Thing[MAX];
    

    Our next step is to do the following inside the main loop:

  • For every Thing t1, loop through and calculate the gravitational force vector for every Thing t2 (except skip calculating the force when t1 = t2)
  • void draw() {
      for (int i = 0; i < t.length; i++) {          //for every Thing t[i]
        for (int j = 0; j < t.length; j++) {        //for every Thing t[j]
          if (i != j) {                             //make sure we are not calculating gravtional pull on oneself
            Vector2D f = t[i].calcGravForce(t[j]);  //use the function we wrote above
            t[i].add_force(f);                      //add the force to the object to affect its acceleration
          }
        }
        t[i].go();                                  //implement the rest of the object's functionality
      }
    }
    

    The Real World vs. Our Digital World

    It is important to note here that “ideal world scenarios” often have serious problems when working with a visual computer simulation. Take the following example where we have two objects:

    Thing T1: LOC = (10.2,10.0), MASS = 5
    Thing T2: LOC = (10.3,9.9), MASS = 5
    G = 1.0

    DIST = SQRT((10.2-10.3)*(10.2-10.3)+(10.0-9.9)*(10.0-9.9)) = SQRT(0.01 + 0.01) = ~0.14
    GRAVFORCEMAG = (1.0 * 5 * 5) / (0.14 * 0.14) = 1250.0

    This force of 1250 “units” is going to be much too large when thinking about moving an object a certain number of pixels along the screen. To create nice smooth-looking visualizations, therefore, we often need to develop clever ways of limiting factors within the system (having a maximum velocity, a minimum distance, etc.). In the examples below, you’ll see some strategies implemented for “faking it”. This issue is one that you will need to consider as you develop your own projects.

    Examine this version of the gravitational force calculation function:

    Vector3D calcGravForce(Thing t) {
      Vector3D dir = Vector3D.sub(t.getLoc(),loc);      //calculate direction of force
      float d = dir.magnitude();                        //distance between objects
      d = constrain(d,20.0f,100.0f);                    //Limiting the distance to eliminate "extreme" results for very close or very far objects
      dir.normalize();                                  //normalize vector (distance doesn't matter here, we just want this vector for direction)
      float force = (G * mass * t.getMass()) / (d * d); //calculate gravitional force magnitude
      dir.mult(force);                                  //get force vector --> magnitude * direction
      return dir;
    }
    

    Other Related Topics

  • Springs and Hooke’s Law
  • Spring Force Processing Example
  • Pendulum Motion (we will examine pendulums more closely next week)
  • Pendulum Java Applet

  • 3 Responses to “Forces”  

    1. 1 sajid

      Think there is a small type error in this code:

      Thing(Vector3D a, Vector3D, v, Vector3D l, float m_) {

      should this not be:

      Thing(Vector3D a, Vector3D v, Vector3D l, float m_) {

      thanks and I am learning a lot from here.

    2. 2 Daniel

      Oops, thanks for catching the error!

    3. 3 picturetunes

      hi, there is a minor calculation error in the description:

      ACCELERATION CAUSED BY GRAV = GRAV / MASS = (0,10) / 5 = (0,2)
      should be
      ACCELERATION CAUSED BY GRAV = GRAV / MASS = (0,10) / 5 = (0,02)

      thanks for making those great learning resources available for everyone!

    Leave a Reply