Don't Forget Your Math

Before jumping into 3D graphics programming, let's tack a step back and talk about trigonometry and vectors. Hey, don't fall asleep—I'm serious. You'll use the trigonometry definitions and vector math basics a lot when dealing with 3D graphics.

Trigonometry and Right Triangles

You've probably seen the trigonometric definitions in Screenshot. The definitions show how the angles and side lengths of a right triangle relate to each other. Some people have these definitions memorized; for everyone else, Screenshot is provided here for a quick reference.

Screenshot The definitions of the trigonometric functions.

Java graphics 07fig01.gif


Lots of 3D graphics problems can be solved using right triangles. A right triangle is a triangle that has one 90° angle. To "solve" a right triangle, or calculate the length of all the sides and angles, you need to know at least two pieces of information about it: either two sides or one side and one angle. You're probably familiar with the equation a2+b2=c2. In this equation, called the Pythagorean Theorem, a, b, and c are sides of a right triangle. The hypotenuse, or side opposite the right angle, is c. If you know the length of two sides of a triangle and need to know the third, this equation is for you. However, if you know only one side and one angle, the trigonometric definitions in Screenshot come in handy. The definitions of sine, cosine, and tangent show the relationship between the sides of a right triangle and its angles, and enable you to solve a triangle in various situations.

Vector Math

When working with 3D graphics, we denote a point in 3D space as the triplet (x, y, z). The tricky part, and the part important to understand, is that this triplet can be thought of as either a point in space or a vector. A vector is a magnitude and a direction, like a velocity, and is the basis of vector math. An example of a direction is east, and an example of a magnitude is 55 mph. So, if the x-axis points east, then the vector (55, 0, 0) could be interpreted as east at 55 mph. Likewise, if the z-axis points south, then the vector (0, 0, 55) could be interpreted as south at 55 mph. In this tutorial, you work with only 3D vectors, but keep in mind that vectors aren't limited to three dimensions; they can have two dimensions or even more than three. In the text, we denote vectors as an uppercase letter (as opposed to a real number, in lower case). Also, we denote a vector's components with a subscript:

V=(Vx, Vy, Vz)


Remember, a vector is a magnitude and a direction, and it doesn't have an origin. It doesn't matter what the origin is. In other words, traveling east at 55 mph in Los Angeles is the same as traveling east at 55 mph in Paris (except in Paris, you'll probably be using kilometers, but you get the idea). It's the same vector. Now let's move on to some vector math. First, basic addition: Vectors can be added together, as shown in Screenshot. In this figure, the vectors U and V are added together (U+V), and U is subtracted from V (V–U). The vectors –U and –V are also shown: These vectors have the same magnitude but opposite direction of their positive counterparts.

Screenshot Vectors can be added together.

Java graphics 07fig02.gif


Mathematically, adding two 3D vectors is achieved by adding their components together:

U+V=(Ux+Vx, Uy+Vy, Uz+Vz)


For example, if a bird is traveling east at 55 mph and the wind is pushing the bird west at 10 mph, the result of the bird and wind vectors added together would be east at 45 mph. Note that adding two vectors results in a new vector with a different magnitude, a different direction, or both. Of course, the same works for subtraction. Next, you can multiply a vector by a scale. This changes its magnitude without changing its direction, and is achieved by multiplying every component by the scale:

s V=(s Vx, s Vy, s Vz)


So, multiplying east at 55 mph by 2 would mean east at 110 mph. Don't try that at home, kids. A vector's magnitude, or length, is notated with bars around it. The length can be calculated using the three-dimensional version of the Pythagorean Theorem:

|V|=(Vx2+Vy2+Vz2)1/2


If a vector has a length of 1, it's called a unit vector, or a normalized vector. You can normalize a vector by dividing it by its length. A normalized vector is denoted with a party hat over it:

Û=U/|U|


Vectors may also wear party hats when they've had too much punch. That's it for a quick introduction to vector math. We'll get into more vector math later in this chapter, but with the information we have so far, we'll go ahead and create a useful vector class. The Vector3D class, in Listing 7.1, uses floats to describe a 3D vector. We use floats for most 3D calculations in this tutorial, mainly because they're less costly than doubles in most situations and give us enough precision for our needs.

Listing 7.1 Vector3D.java
package com.brackeen.javagamebook.math3D;
/**
 The Vector3D class implements a 3D vector with the
 floating-point values x, y, and z. Vectors can be thought of
 either as a (x,y,z) point or as a vector from (0,0,0) to
 (x,y,z).
*/
public class Vector3D implements Transformable {
 public float x;
 public float y;
 public float z;
 /**
 Creates a new Vector3D at (0,0,0).
 */
 public Vector3D() {
 this(0,0,0);
 }
 /**
 Creates a new Vector3D with the same values as the
 specified Vector3D.
 */
 public Vector3D(Vector3D v) {
 this(v.x, v.y, v.z);
 }
 /**
 Creates a new Vector3D with the specified (x, y, z) values.
 */
 public Vector3D(float x, float y, float z) {
 setTo(x, y, z);
 }
 /**
 Checks if this Vector3D is equal to the specified Object.
 They are equal only if the specified Object is a Vector3D
 and the two Vector3D's x, y, and z coordinates are equal.
 */
 public boolean equals(Object obj) {
 Vector3D v = (Vector3D)obj;
 return (v.x == x && v.y == y && v.z == z);
 }
 /**
 Checks if this Vector3D is equal to the specified
 x, y, and z coordinates.
 */
 public boolean equals(float x, float y, float z) {
 return (this.x == x && this.y == y && this.z == z);
 }
 /**
 Sets the vector to the same values as the specified
 Vector3D.
 */
 public void setTo(Vector3D v) {
 setTo(v.x, v.y, v.z);
 }
 /**
 Sets this vector to the specified (x, y, z) values.
 */
 public void setTo(float x, float y, float z) {
 this.x = x;
 this.y = y;
 this.z = z;
 }
 /**
 Adds the specified (x, y, z) values to this vector.
 */
 public void add(float x, float y, float z) {
 this.x+=x;
 this.y+=y;
 this.z+=z;
 }
 /**
 Subtracts the specified (x, y, z) values to this vector.
 */
 public void subtract(float x, float y, float z) {
 add(-x, -y, -z);
 }
 /**
 Adds the specified vector to this vector.
 */
 public void add(Vector3D v) {
 add(v.x, v.y, v.z);
 }
 /**
 Subtracts the specified vector from this vector.
 */
 public void subtract(Vector3D v) {
 add(-v.x, -v.y, -v.z);
 }
 /**
 Multiplies this vector by the specified value. The new
 length of this vector will be length()*s.
 */
 public void multiply(float s) {
 x*=s;
 y*=s;
 z*=s;
 }
 /**
 Divides this vector by the specified value. The new
 length of this vector will be length()/s.
 */
 public void divide(float s) {
 x/=s;
 y/=s;
 z/=s;
 }
 /**
 Returns the length of this vector as a float.
 */
 public float length() {
 return (float)Math.sqrt(x*x + y*y + z*z);
 }
 /**
 Converts this Vector3D to a unit vector, or, in other
 words, a vector of length 1. Same as calling
 v.divide(v.length()).
 */
 public void normalize() {
 divide(length());
 }
 /**
 Converts this Vector3D to a String representation.
 */
 public String toString() {
 return "(" + x + ", v + y + ", " + z + ")";
 }
}


There's nothing too difficult here. Vector3D has methods for adding, subtracting, multiplying, dividing, getting the length of, and normalizing vectors. We use the Vector3D class for both vectors and points in space because some math calculations require treating a point as a vector, or vice versa. For example, you might want to get the vector between two points in space. In this case, if both points were a Vector3D, subtracting one from the other would result in the vector between them. As said before, there's more to talk about with vector math, and there are a few more methods to add on to the Vector3D class. We get to this later in the chapter. For now, you have enough to move on to some 3D basics.

Screenshot


   
Comments