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.

Reading

  • Some links about vectors: Working with vectors, Describing Motion, Vectors: Velocities, Accelerations, and Forces
  • Mathematics and Physics for Programmers, Chapter 5 — Vectors, Danny Kodicek (suggested)
  • Hackers and Painters, Paul Graham
  • Two’s Company

    To animate an object in a virtual space, we need a way of storing information about the object’s location, movement, etc. In a two dimensional space (such as our computer screen), a location is expressed as an x and y coordinate. This pairing of two pieces of information is the essential building block for the systems we will create. We will have both “Points” and “Vectors”. A point represents a location and a vector represents the displacement between two points.

    Consider a rectangle moving across the screen. At any given instant it has the following:

  • Position — the object’s location, expressed in two dimensions as a point.
  • Velocity — the rate at which the object’s position changes per time unit, expressed as a two dimensional vector
  • Acceleration — the rate at which the object’s velocity changes per time unit, expressed as a two dimensional vector
  • Technically, Position is a point and Velocity/Acceleration are vectors. For our purposes, however, we will consider all three as vectors to simplify our coding (with the xy components of our location vector storing location coordinates instead of values for rate of change). Examine the following pseudo-ish code. Assume three vectors, velocity, acceleration, and location. This simple algorithm will form the basis for our first week examples.

    velocity = velocity + acceleration
    location = location + velocity
    draw thing @ location
    

    Since vectors represent pairs of values, we cannot simply use traditional addition/multiplication/etc. Instead, we’ll need to do some “vector” math.

    Assume vector v = (vx,vy), vector w,u, etc.

    u = v + w -->  ux = vx + wx, uy = vy + wy
    u = v - w –>  ux = vx - wx, uy = vy - wy
    

    Also, note that the algebraic rules for vectors are similar to real numbers:

    v + w = w + v (commutative)
    u + (v + w) = (u + v) + w (associative)
    

    For vectors, we also have scalar multiplication by a single real number (n & m below), i.e.

    v = w * n --> vx = wx * n, vy = wy * n
    v = w / n –> vx = wx / n, vy = wy / n
    (n*m)*v = n*(m*v)
    (n+m)*v = n*v + m*v
    n*(v+u) = n*v + n*u
    

    Vectors also have a dot product (or inner product), which is a means for comparing the direction of two vectors. We may examine dot product in a later class as it is not necessary for the current examples.

    A common operation we will need to perform is to compute the length (or magnitude) of a vector (for any vector v, length is often expressed as ||v||). This is done using the pythagorean theorem and can be expressed as follows:

    ||v|| = sqrt ( vx*vx + vy*vy )
    

    Once we have the magnitude of a vector, this allows us to normalize it, i.e. compute its unit vector (a vector with the same direction, but with a length of one.) Knowing the unit vector is very useful since it describes a vector’s direction w/o regard to length. For any given vector u, its unit vector (expressed as û) is calculated as follows:

    û = u / || u ||
    

    A Two (or is it 3?) Dimensional Vector Class

    Object Oriented Programming refers to art of breaking down a program into a set of self-contained parts. Before we can begin to code any simple physics / motion simulation, we need to create a template class to store the data and perform the calculations associated with a vector. Our first instinct might be to turn to the java class Vector. This class, though named Vector, refers to an expandable array of objects, and won’t do us any good.

    There is the package javax.vecmath — if you look at this package, you’ll find Point2D and Vector2D — importing this package into our processing projects and using these classes would give us what we need. However, for the purpose of better understanding how vectors work, we will develop our own code for this class (but you may choose not to use this class and import other java classes instead.)

    For a review of object oriented programming visit:
    http://itp.nyu.edu/icm/shiffman/week3/index.html.

    Our Vector class starts with declaring the instance variables for each Vector object (an x and y coordinate) as well as a constructor to fill the instance variables.

    public class Vector3D {
      public float x;
      public float y;
      public float z;
    
      Vector3D(float x_, float y_, float z_) {
        x = x_; y = y_; z = z_;
      }
    
      Vector3D(float x_, float y_) {
        x = x_; y = y_; z = 0f;
      }
    
      /**functionality to go here -- see below**/
    }
    
    Instance methods are methods that are tied to an actual instance of an object and can only be called via an object’s reference.
    Vector3D v1 = new Vector3D(0,1);
    Vector3D v2 = new Vector3D(1,0);
    v1.add(v2);

    Static methods make no use of the instance variables of any object of the class. They act like “global” methods for a class and are called directly via the class name, without first creating an object from the class.
    Vector3D v1 = new Vector3D(0,1);
    Vector3D v2 = new Vector3D(1,0);
    Vector3D v3 = Vector3D.add(v1,v2);

    Note the use of an overloaded constructor above. We have two constructors (methods with the same name: “Vector3D”). We would think that the compiler would be confused — how can you have two functions with the same name! It’s important to remember, however, that a method’s signature is not just its name, but its arguments (and return type while we’re at it) as well. Therefore, two functions with the same name with different arguments is allowed. Here it’s particularly useful since we can use the same Vector3D class for both 2D and 3D vectors. When we want a 2D vector, we just create one with only an ‘x’ and ‘y’ value. Behind the scenes, the Vector3D class manages the information for ‘z’, setting the value to zero (which will render it irrelevent for all calculations.)

    Once we’ve set up the constructor, we can start to implement functions that take care of the Vector math for us. Note the use of both static and non-static (instance) methods. We’ll use instance methods when we want to perform an operation on a specific instance of a Vector3D object, and static methods when we want to create a new Vector3D object from an operation.

      public float magnitude() {
        return (float) Math.sqrt(x*x + y*y + z*z);
      }
    
      public void add(Vector3D v) {
        x += v.x;
        y += v.y;
        z += v.z;
      }
    
      public static Vector3D add(Vector3D v1, Vector3D v2) {
        Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z);
        return v;
      }
    

    The full java source for our Vector3D class is here: Vector3D.java.

    Integrating with Processing (Internal vs. External classes)

    Processing sketches are really Java programs. If we were to remove the safety net of the Processing environment, we’d end up with code that looks like this:

    import processing.core.*;
    import java.applet.*;
    import java.awt.*;
    import java.awt.image.*;
    import java.awt.event.*;
    import java.io.*;
    import java.net.*;
    import java.text.*;
    import java.util.*;
    import java.util.zip.*; 
    
    public class JavaExample extends PApplet {
    
      public void setup() {
        size(200, 200);
      }
    
      public void draw() {
        background(100);
        rectMode(CENTER);
        fill(255);
        rect(mouseX,mouseY,16,16);
      }
    }
    

    dotjavaWhen we write classes in the Processing IDE, these classes are really “internal” classes, i.e. they exist inside the larger class (”JavaExample” above). This is how we are able to refer to built-in variables (such as width, height, mouseX, etc.) anywhere in the sketch, as well as call built-in Processing drawing functions anywhere in the sketch. There comes a time, however, when we might want to write an “external” class — i.e. a stand-alone Java class that knows nothing about a Processing applet whatsoever. Vector3D.java is our first example of an external Java class. A Vector is a generic enough concept that is does not need to be part of the Processing applet class itself. Also, it’s convenient to include some static methods in the Vector3D class, and static methods are not allowed in internal classes. To create an external class, simply name the tab with the .java (as pictured). In truth, we should most likely make a Processing Library so that we’re not adding this class to every single one of our sketches, but could just import it via a nice import statement. . . but for now, it’s a nice little exercise to learn to create our own external Java classes.

    Encapsulation

    Java supports different levels of access for variables (see: Controlling Access to Members of a Class). In the Vector3D class, for example, we have the option of making x and y private — from the java tutorial: “A private member is accessible only to the class in which it is defined. Use this access to declare members that should only be used by the class. This includes variables that contain information that if accessed by an outsider could put the object in an inconsistent state, or methods that, if invoked by an outsider, could jeopardize the state of the object or the program in which it’s running. Private members are like secrets you never tell anybody.”

    This is a questionable call here and we might choose to make x & y private. Indeed, one of the foundations of object oriented programming is “Encapsulation”. Making our instance variables private is good practice. By using encapsulation, the data associated with an object is hidden and the caller of that object deals only with its behaviors, not directly with the internal implementation. We can think of it more simply as “Never access your object’s data directly; use only its methods.”

    Consider a car as an object. Encapsulation would hide all the details associated with the car’s internal wiring, etc. so that we could just say things like “car.drive()” and “car.turn()”, etc. This gives us three advantages:

  • We don’t need to know the details of how an object works to operate it
  • If we change the way an object works (i.e. rewire a car, change its engine, etc.), we still use the same functionality with the car (car.drive() doesn’t change).
  • The caller of the car object cannot break the car if the details of the implementation cannot be accessed
  • Nevertheless, to keep things somewhat simple, it’s very convenient to keep the x, y, and z components of the Vector class public. We’ll consider this an exception, and try to make sure we practice good encapsulation techniques with our other classes. For example, with in the above Mouse interaction example, we only access the location, velocity, and acceleration methods of the class via methods. The Vector3D object is also always copied before it is taken out of the class, so that the reference to the actual Vector3D object itself cannot be manipulated.

    class Thing {
      // Using private now to encapsulate data
      private Vector3D loc;
      private Vector3D vel;
      private Vector3D acc;
      private float maxvel;
    
      // The Constructor (called when the object is first created)
      Thing(Vector3D a, Vector3D v, Vector3D l) {
        acc = a;
        vel = v;
        loc = l;
        maxvel = 8;
      }
    
      // Add functions to our thing object to access the location,
      // velocity and acceleration from outside the class
      Vector3D getVel() {
        return vel.copy();
      }
    
      Vector3D getAcc() {
        return acc.copy();
      }
    
      Vector3D getLoc() {
        return loc.copy();
      }
    
      void setLoc(Vector3D v) {
        loc = v.copy();
      }
    
      void setVel(Vector3D v) {
        vel = v.copy();
      }
    
      void setAcc(Vector3D v) {
        acc = v.copy();
      }
    

    The Vector3D library

    If you don’t need to make any changes to the Vector3D class and intend on using it often, it’s a bit more convenient to use it as a Processing library. You can do so by downloading the Vector3D processing library.


    3 Responses to “Vectors”  

    1. 1 Shaun

      Thanks for the great introduction into vector motion. I went through your examples and created an applet with an array of projectiles with fading dotted-line trails and gravity. I placed the acceleration arrow at the start of the velocity one since acceleration steers velocity. I’m in the process of writing a recursive collision function to keep the projectiles from being pushed out of the window. All in all, I learned a lot from your examples and I’m starting to branch off into many different topics of interest because of this. Thank you very much!

    2. 2 lenny

      very useful intro, thanks a lot.

    1. 1 Create Digital Motion » New Processing Libraries Added: Vector3D, xmlrpclib, 2 GUIs and ID3


    Leave a Reply