noobtuts

Java Vector2 Class

java-vector2-class-preview
When making a two dimensional game, everything that has to be positioned in the game world needs a Vector2 class. A Vector2 in its most basic form only consists of an x and y value as floating point numbers (float in Java). It can be used to store a position, to store a movement direction, a rotation and much more.

About Points and Directions

According to its definition a Vector is a direction. The vector (2,2) is a pointer that points from the origin (0,0) to the point (2,2). The vector (-3, 0) is a pointer that points from the origin (0,0) to the point (-3, 0) accordingly. Since vectors always store a x and y value, they are also often used as just points. Take a look at the following graphics:
java-vector2-class-directions java-vector2-class-points

The red direction and the red point are the exact same vector, the same applies for the blue and the green ones. For the beginner its easier to think of it as a point, but we need to keep in mind that theoretically its a pointer.

Example: If we want to store an objects position, then we would use a Vector2. If we would store an objects movement direction, then we would use a Vector2 as well. We need x and y in both cases, that's why we use a Vector2 in both cases.

Implementation of the basic Class

Let's create the basic Vector2 class consisting of the x and y value, a constructor and a compare function:

public class Vector2 
{              
    // Members
    public float x;
    public float y;
       
    // Constructors
    public Vector2() {
        this.x = 0.0f;
        this.y = 0.0f;
    }
       
    public Vector2(float x, float y) {
        this.x = x;
        this.y = y;
    }
       
    // Compare two vectors
    public boolean equals(Vector2 other) {
        return (this.x == other.x && this.y == other.y);
    }
}

We created two constructors. The first one can be used like this:

// Create a Vector2 with x = 0 and y = 0
Vector2 v = new Vector2();

The second constructor let's us create a new Vector2 while already setting the x and y values:

// Create a Vector2 with x = 1 and y = -2
Vector2 v = new Vector2(1.0f, -2.0f);

Let's create a vector and then modify its y value afterwards:

Vector2 v = new Vector2(42.0f, 0.0f);
v.y = 3.0f;

If we want to find out if two vectors are equal, we can do it like this:

Vector2 v = new Vector2(1.0f, -2.0f);
    Vector2 w = new Vector2(1.0f, 99.0f);
    if (v.equals(w)) {
        // do something
    }

It's important to compare them with v.equals(w) instead of using v == w. The == operator compares the object, the equals function compares the x and y values (which is what we want).

Implementation of DistanceTo

Very often we will have to calculate the distance between two points in the game world. Let's take a look at a graphic:
java-vector2-class-distance
The red and the green arrows are our two vectors. The distance between those is the blue line, or to be exact: the length of the blue line.

The distance calculation algorithm is following the same concept every time for Vector2, Vector3 and the rest. If you are interested in how it works, please take a look at the Euclidean distance Wikipedia Article.

Let's implement it. The following function will be put into our Vector2 class:

public static double distance(Vector2 a, Vector2 b) {
    float v0 = b.x - a.x;
    float v1 = b.y - a.y;
    return Math.sqrt(v0*v0 + v1*v1);
}

The used formula is: squareRoot( (b.x-a.x) * (b.x-a.x) + (b.y-a.y) * (b.y-a.y) ). To save calculations we calculate the x and y differences only once and store them in v0 and v1.

Let's test the function:

Vector2 a = new Vector2(0.0f, -1.0f);
Vector2 b = new Vector2(0.0f, 2.0f);
double dist = Vector2.distance(a, b);

The distance in this example is exactly 3. Feel free to draw it on a paper to see it in a better way.

Implementation of Normalize

We will need to normalize a Vector2 sooner or later for certain computations. What normalize does is keeping the vectors direction while setting its length to exactly 1. To understand this we will look at two graphics:
java-vector2-class-normalize1 java-vector2-class-normalize2

The red arrow is a Vector2 that is pointing towards a certain direction. The length is more than one, for example let's say it's five. The blue arrow is pointing towards the same direction, but it has been normalized. The length is exactly one.

Let's implement it. All we have to do is find out the vector's current length and then multiply x and y by 1 / length:

public void normalize() {
    // sets length to 1
    //
    double length = Math.sqrt(x*x + y*y);

    if (length != 0.0) {
        float s = 1.0f / (float)length;
        x = x*s;
        y = y*s;
    }
}

Here is a usage example:

Vector2 v = new Vector2(42.0f, 0.0f);
v.normalize();

This example modifies v to (1.0f, 0.0f), exactly as it was planned. Feel free to draw it on a paper, then you will see the effect a bit better.

Summary

The result is a very simple to use Vector2 class that comes with the most commonly used functions. Now it's time for you to add a few more functions like add, scale or subtract accordingly.