Vector

From GDWiki

(Redirected from Math:Vector)
Jump to: navigation, search

Vectors are a pretty essential part of graphics, physics, game logic and even a lot of AI for games. They are not very complicated but to use them effectively you'll need to know a few tricks.

The wiki has code for a C++ generic vector class.

Contents

[edit] Interpretation

A point is a position in space. A vector has direction and magnitude. The two are distinct concepts but have the same representation, so they are often confused. It is common to use vectors to represent both, since a point can be thought of as a vector starting from the origin.

[edit] Representation

Points and vectors can be represented in many ways, but the most common representation is cartesian: one number for each dimension. In game programming most points and vectors will have 2 or 3 dimensions, but occasionally they have 4. In this article points and vectors are written as \langle x, y \rangle or \langle x, y, z \rangle.

For most applications, the vectors will contain floating point numbers (C's float type & VB's Single type), and if you need extra precision you can use the 64-bit variety (double). In some situations integer vectors are useful though (for example, in tile-based maps).

[edit] Basic operations

Points and vectors can be involved in addition and subtraction. If you take a vector and add or subtract a vector, you get a vector. If you take a point and add or subtract a vector, you get a point. You can subtract two points and get a vector. You cannot add two points.

\vec V + \vec V = \vec V
\vec V - \vec V = \vec V
P + \vec V = P
P - \vec V = P
\vec V + P  = P
V - P meaningless
P + P meaningless
P - P = \vec V
-\vec V = \vec V
- P meaningless

Once you understand the difference between points and vectors, you will realize why the linear interpolation formula involves subtracting points instead of  u \times P_1 + \left(1-u\right) \times P_2.

Adding and subtracting vectors and points is trivial. Add or subtract the corresponding elements.

\langle 4, 0 \rangle + \langle 1, 10 \rangle = \langle 5, 10 \rangle
\langle 1, 2, 3 \rangle - \langle 2, 2, 2 \rangle = \langle -1, 0, 1 \rangle

The meaning of adding vector A and vector B together is that the new vector represents what you get to when you first follow vector A then follow vector B. Negating a vector just changes its direction to be the opposite of the original direction, and leaves the length the same.

Vectors can also be scaled by a factor, which is mind-blowingly straightforward as well:

\langle 1, 2, 3 \rangle \times 2 = \langle 2, 4, 6 \rangle
\frac{\langle 8, 4 \rangle}{4} = \langle 2, 1 \rangle

This leaves the vector pointing in the same direction, but makes it bigger (or smaller). Viewed this way, negating a vector is the same as multiplying it by -1. That brings us to the length of a vector, the mathematical notation of that is putting pipes (|'s) around the name.

\vec A = \langle 0, 4, 0 \rangle, \vec B = \langle 3, 4 \rangle, \vec C = \langle 2, 2, -2 \rangle
\left|\vec A\right| = 4
\left|\vec B\right| = \sqrt{3^2 + 4^2} = \sqrt{25} = 5
\left|\vec C\right| = \sqrt{2^2 + 2^2 + (-2)^2} = \sqrt{12}

If you remember Pythagoras this is all quite simple.

[edit] Two-dimensional stuff

A useful operation on vectors is the dot product. The dot product involves multiplying the corresponding numbers:

\vec A \cdot \vec B = A_x B_x + A_y B_y

Note that this gives a number, not a vector. This number, conveniently enough, is the cosine of the angle between the two vectors, multiplied by the length of the two vectors.

\vec A \cdot \vec B = cos(\theta_{AB})\left|\vec A\right| \left|\vec B\right|

Note that the limiting cases for this are that if

 \vec A \cdot \vec B = 0

then the vectors are perpendicular since cos(90) = 0 - or one is a zero vector - and if

 \vec A \cdot \vec B = \left|\vec A\right| \left|\vec B\right| ,

then they are parallel - cos(0) = 1. Otherwise, the angle can be calculated by:

\theta_{AB} = cos^{-1}\left(\frac{\vec A \cdot \vec B}{\left|\vec A\right| \left|\vec B\right|} \right)

If the two vectors are normalized (which means they have a length of exactly 1), the latter part of the formula can be left off. The normalized version of a vector can be realized by first getting the length of the vector and then dividing each component by the length. Just make sure the length isn't zero or you will get division by zero. After division, the vector is scaled to fit on the unit circle.

The angle referred to here is the smallest angle between the two vectors. If you want to turn one vector towards another vector, you'll have to know which way to turn. The dot product does not give this information, it only tells you how far to turn. Finding out the direction of the angle can be done the following way:


\det(\vec A, \vec B) = A_x B_y - B_x A_y

If det (the determinant) is positive the angle between A and B is positive (counter-clockwise). If the determinant is negative the angle goes clockwise. Finally, if the determinant is 0, the vectors point in the same direction. This can be used to create the following angle-calculating function (in C++):

float Angle(const Vector& a, const Vector& b)
{
  float cosine = (a.x * b.x + a.y * b.y) / (vectorlength(a) * vectorlength(b));
  // rounding errors might make dotproduct out of range for cosine
  if (cosine > 1) cosine = 1;
  else if (cosine < -1) cosine = -1;
 
  if ((a.x * b.y - a.y * b.x) < 0)
    return -acos(cosine);
  else
    return acos(cosine);
}

Which returns the angle between two vectors in radians, with counter-clockwise angles being positive. (There are other, possibly faster ways to compute such a signed angle).

Another nice property of the dot product is that you can project one vector on another one. The following picture will try to clarify.

\mathrm{proj}(\vec A, \vec B) = \vec A \frac{\vec A \cdot \vec B}{\left|\vec A\right|^{2}}

    B
   /
  / 
 /
/___C_____A

C is B projected on A. That means C is what is left of B if only the component that is pointing in the direction of A is taken.

[edit] Three dimensions

The dot product is also defined in three dimensions, it is done in a similar way: \vec A \cdot \vec B = {\vec A}_x{\vec B}_x + {\vec A}_y{\vec B}_y + {\vec A}_z{\vec B}_z

And again it gives the cosine of the angle between A and B multiplied by the lengths of A and B.

Another very useful operation is the cross product. It gives a vector that has an angle of 90° with both A and B:

\vec A \times \vec B =\langle
{\vec A}_y{\vec B}_z - {\vec A}_z{\vec B}_y,
{\vec A}_z{\vec B}_x - {\vec A}_x{\vec B}_z,
{\vec A}_x{\vec B}_y - {\vec A}_y{\vec B}_x \rangle

A useful application of this is to get the normal of a plane. That is the vector that is pointing straight out of a plane. If two vectors lie in a plane (any two vectors that do not point in the same or opposite direction form a plane), their cross-product is the normal of that plane.

The direction of the cross product vector can still go two ways based on the previous description, out of the front of the plane or out of the back of the plane. An easy way to remember what way it will go is the following: If you are looking straight down the plane A and B form, and the angle between A and B goes clockwise, the cross product vector will be pointing straight at you.

[edit] More about planes

A plane in three-dimensional space can be represented in two ways.

The first way consists of a point on the plane, P0, and the normal, \vec N (a vector that is perpendicular to the plane). Any point, P, is on the plane if the vector from P0 to P is perpendicular to \vec N. In other words, (P-P_0) \cdot \vec N = 0.

Planes can also be described as the equation Ax + By + Cz + D = 0.

A B, C, and D in the second form can be derived from the first form:

P_0 = \langle x_0, y_0, z_0 \rangle
\vec N = \langle A, B, C \rangle
D = -(\vec N \cdot P_0) = -(Ax_0 + By_0 + Cz_0)

It is very easy to find out where a point is relative to the plane. You just fill in P in the first form or x, y and z in the second form of the equation. If the result of (P-P_0) \cdot \vec N using the first form or Ax + By + Cz + D using the second form is 0, the point is on the plane. If the result is positive, the point is in front of the plane (i.e. on the side in the direction of the normal), and if it is negative, it is behind the plane.

[edit] External Resources

Personal tools