Tuesday, October 28, 2008

XNA Sidebar - Intro To Vector Math

I am not a math wiz, but I know enough to get around. I wrote my Sidebar article on Trigonometry to explain a few concepts that people might want to know to better program in XNA. Well according to my site metrics, it quicky became one of my most viewed pages. So apparently it was info people wanted to know! Well in that same spirit, I give you my intro to vectors post.

Vectors in 2 dimensions are relatively easy concepts, especially when you can visualize them. They have 2 parts, a direction and a magnitude. We can write them as a simple coordinate like [7,8]. Now, although this looks more like a point (and you are right) if we consider this as relative to another point, say (0,0) we now have a vector. As you can see the vector in the image has a direction and a length. In this case the length could be found by the Pythagorean theorem. where A is the x length and B is the Y length. So the length of this vector is the square root of 7 squared + 8 squared, which is 10.63.

One of the simplest operations we can do to a vector is addition. Say we take our vector [7,8] and add [1,3]. If we look at example B, we see the 2 vectors. But when we add them, we simply add their 2 components. Thus resulting in a new vector [8,11]. Which makes more sense if we look at example C where we have stacked the first 2 vectors. That is went from the endpoint of the first vector and moved 1 in the x direction and 3 in the Y. The same goes for subtraction, just minus instead of plus

Multiplication is another useful tool for Vectors. when we multiply a vector times a scaler (a single number) it "scales" the vector to a new length. So if we say [3,4] * 2 we end up with the vector [6,8] which is 2 times as long as the first vector. See Example D. Want some proof? The length of the vector [3,4]

LENGTH [3,4]
= SQRT[3^2 + 4^2]
= SQRT[9+16]
= SQRT[25]
= 5

[3,4] * 2 = [6,8]

LENGTH [6,8]
= SQRT[6^2 + 8^2]
= SQRT[36 + 64]
= SQRT[100]
= 10

and 10 is 2 times 5.

So we have double the length of the vector, but kept the same direction. Much like if we think of a vector as a force being applied to an object in a given direction it will go a certain distance. If we double that force, it will go twice as far. This works the same for division. dividing a vector by 2 will cut it's length in half.

One of the things that we may want to do is find out what the vector that goes in the same direction as this vector, but has a length of 1 is. This is called a unit vector and is gained when we normalize a vector. Luckily for us the XNA Vector2 class has a Normalize method which converts a Vector2 into a unit vector. This is really handy when we have a vector that we want to follow, but it is longer than our current velocity can carry us. Say we want to move from (0,0) to (5,5) we would add the vector (5,5) to position, but say our maximum speed for that movement is only 2. The vector [5,5] would take us aprx 7.07 in that direction. We need to find the vector that is 2 units long in the same direction. We can do that by Normalizing the vector [5,5] and then multiplying it by 2. So we scale it up or down to a length of 1 and then multiply it by the length we actually want it to be. So in c# that would look like this


float maxSpeed = 2;
Vector2 canGo;
Vector2 wantToGo = new Vector2(5,5);
wantToGo.Normalize();
canGo = wantToGo * maxSpeed;


When we multiply this out we get a point that is at [1.14,1.14] This is the vector [5,5] Normalized and multiplied by 2. You are going to see these vector method a lot in our new steering code, because a lot of the time we want to steer further than we are able to move so we have to scale back our vector to a size that we can actually move.

1 comment:

Stephan Coetzee said...

Thanks a lot for this. I'm reading books on XNA, but there is a huge lack of theory. And I didn't have maths in English, so I struggle to grasp simple stuff. Now I might actually understand the stuff I learn!