 ## Tutorial 4 - 3D Vectors

### Overview

3D Vectors are extremely useful in 3d games and I think simple vector math is fun! I want to make this a crash course for anyone who doesn't really get them. And I will also go over some functions provided by the d3dx9 library to help you make the most of them.

### What is a Vector? Figure 8.

Simply put, a 3d vector is an x,y and z value. In DirectX we use the D3DXVECTOR3 structure to hold an x,y and z value, for example:

```D3DXVECTOR3 MyVector;
MyVector.x = 0;
MyVector.y = 0;
MyVector.z = 0;
```

This sets x to 0, y to 0 and z to 0.

A vector is also a line, because if you draw a line from the position 0,0,0 to x,y,z, you have a line.

### Direction

Because we can represent a line by an x,y,z value, we can say that a vector has a direction. The direction of a vector is from the start of the vector 0,0,0 to the end of the vector x,y,z. Like an arrow pointing in some direction.

### Magnitude

You can think of a vector as a line pointing in some direction, or an arrow. The length of the arrow is called it's magnitude. We can use the following formula to get the magnitude of a vector:

length = sqrt(x^2 + y^2 + z^2);

Or:

length = sqrt(x*x + y*y + z*z);

You can also use the D3DX function D3DXVec3Length() to get the length of a vector:
```D3DXVECTOR3 V(1,5,7);
float length = D3DXVec3Length(&V);
``` Figure 9.

If you have a 3d point, P, and you move it by a vector, v1, it will have moved by the length of the vector in the direction the vector is pointing.

To move a point, (x,y,z) by a vector you simply add the x, y and z of the vector to the point for example:

New P = P + v1:

New P x = Px + v1x;
New P y = Py + v1y;
New P z = Pz + v1z;

In code you could have:
```D3DXVECTOR3 P(5,7,1);
D3DXVECTOR3 v1(2,-1,0);
D3DXVECTOR3 NewP = P + v1;
```

### Subtracting

If you subtract a vector from a point P, P will have moved in the opposite direction of the vector by the length of the vector.

If you subtract a 3d point, P1 from P2 (P2 - P1), you get a vector that points from P1 to P2 (See Figure 10.). Figure 10.

### Multiplying

If you multiply the x,y and z components of a vector by some amount, this has the same effect as increasing or decreasing it's magnitude. For example v1 x 2 will double the length of the vector, v1, or v1 x 0.5 will halve the length of the vector, v1. It's direction will remain unchanged unless you multiply by a negative value, it's direction will be reversed.

### Unit Vectors (Normalized Vectors)

Unit vectors are vectors that have length 1. By using a unit vector you can represent any direction as a vector of length one, and transform a point P so P moves in that direction and here's the clever bit, you can decide how far P moves in that direction by multiplying the vector by the distance you want P to move.

Unit vectors are also called Direction Vectors for this reason.

You can turn any vector into a direction vector by dividing it's x,y and z components by it's length. For example:

DirectionVector.x = V.x / magnitude;
DirectionVector.y = V.y / magnitude;
DirectionVector.z = V.z / magnitude;

A vector of length 1 is said to be a normalized vector.

### Equation of a Circle

Here is a very useful equation I learned when I started out as a programmer. It can let you control the direction you want something to travel in. For example, say you have a car in a game and you want to change the direction it is travelling in - You can use this equation to produce a direction vector that you can use to make a car travel in whatever direction you want:
```x = cos(angle);
y = sin(angle);
```

if angle is 0, x will be 1 and y will be 0. Remember to convert degrees to radians for cos and sin functions. D3DXToRadian(degree). When angle is 90, x will be 0 and y will be 1. Therefore, angle 0 - 360, will produce a circle that starts at the x axis, where y is 0 and x is 1 and moves in a clockwise direction as angle increases from zero to 360, provided positive Y points down-the-way.

Then, when you supply an angle to this equation you get a direction vector, (x,y). You could do the same thing for the x and z axis if working in 3d, for example, to rotate around the Y axis, set y to 0, and use the following equation:
```x = cos(angle);
z = sin(angle);
y = 0;
```
Plug-in the angle and you get a direction vector.

You can then make an object move along that direction vector by the distance you want it to travel.

### Angle Between Vectors

There are other useful properties of vectors such as something called the dot product of two vectors, A and B is equal to length of A x length of B x cos(theta):
```A . B = lengthA*lengthB*cos(theta)
```

The dot product is simply a number calculated as follows:
```float DotProduct = (x1*x2 + y1*y2 + z1*z2)
```

We can rearrange the equation above to get the angle between two vectors:
```cos(theta) = (A . B)/(lengthA*lengthB);

theta = acos((A . B)/(lengthA*lengthB));
```

Where theta is the angle between the two vectors. In fact the 360 degree angle between two vectors can be found by this function:
```float Get360AngleBetweenVectors(float x1, float y1, float x2, float y2)
{
float dot = x1*x2 + y1*y2;
float det = x1*y2 - y1*x2;
float angle = atan2(det, dot);
return D3DXToDegree(angle);
}
```

### Cross Product

The Cross Product is a vector given by two other vectors, or in 2 Dimensions, one other vector. It is a vector perpendicular to the other two vectors or another vector. For example, a perpendicular vector is a vector at right angle(90degrees) to another vector: Figure 11.

In two dimensions, the cross product is equal to (-y, x)

### D3DX Functions

Finally, to conclude this tutorial, here are some useful functions from the d3dx library(d3dx9.h):
```D3DXVECTOR3 V1;
D3DXVECTOR3 V2;
float dotProduct = D3DXVec3Dot(&V1, &V2);

D3DXVECTOR3 CrossProduct;
D3DXVec3Cross(&CrossProduct, &V1, &V2);

float length = D3DXVec3Length(&V1);

D3DXVECTOR3 DirVector;
D3DXVec3Normalize(&DirVector, &V2);
```