# Posts tagged ‘Vector’

So the cross product along with the dot product is the bread and butter of vector math – but I’d never known really whats happening internally. Essentially the cross product of two vectors (two directions), creates a new vector thats orthogonal to them. This means its a vector thats 90 degrees perpendicular to product of the other two.

So if we have two vectors [1,0,0] and [0,1,0], the cross product will be [0,0,1] – Likewise if we swap these vectors the cross product will be [0, 0, -1]. Even though we doing multiplication internally, we’re also doing subraction and vector order matters here. We can use sarrus’ rule, to get the cross product which is like finding the determinant – which i’ll discuss in matrix math:

If we have two vectors, [1, 0, 0] and [0, 1, 0] we can put them into a 3 by 3 matrix, with an imaginary row at the top:

I J K
1 0 0
0 1 0

We’ll get the determinant of each part of the imaginary row. Starting with the I, we’ll disregard any row and column it crosses and keep the rest. So for I it’ll become:

0 0
1 0

Next we’ll multiply the first value of the first row, by the last value of the last row – in this case 0, 0 and subtract it from first value of the last multiplied by the last value of the first row:

I = 1 * ((0 * 0) – (1 * 0)) = 0

This is the first part of a new vector – Lets see how this looks for the whole thing: cross ([1, 0, 0], [0,1,0]) =

I = 1 * ((0 * 0) – (1 * 0)) = 0
J = 1 * ((1 * 0) – (0 * 0)) = 0
K = 1 * ((1 * 1) – ( 0 * 0) = 1

We can see that the last part makes a difference, we’re doing (1 *1) – (0 * 0), so 1 – 0. If we’d have swapped the initial vectors around we’d have (0 * 0) – (1 * 1) = -1. Next up we’ll break into matrices..

A lot of maths I use tends to be abstracted away either in libraries I use, or inside the application. I’m going to go back to basics starting with vector maths, and moving onto matrices – these, in my opinion are the back bone to doing what we do. I’ll cover from the ground up and then go into some more complex areas: determinants, inverse multiplication, decomposition etc. I’ll be learning a bunch of this stuff along the way. Lets get started:

Vectors

So a vector is basically a direction from the origin. [1, 2, 3] basically means we have a point thats moved 1 in the X direction, 2 in the Y and 3 the Z direction.

Vectors can be added together simply by adding the parts of each together. [1, 2, 3] + [4, 5, 6] = [(1+4), (2+5), (3+6)]. Subtraction follows a similar process.

Vectors can be multiplied against a scalar (float) value by multiplying each part by it: [1, 2, 3] * 5 = [(1*5), (2*5), (3*5)].

We can get the length of a vector by firstly, powering each part by 2, then summing (adding up) these parts, and finally getting the square root of the total. This looks like this len([1, 2, 3]) = sqrt((1^2) + (2^2) + (3^2)).

Using this length we can get the normal of the vector. Normalizing a vector keeps its direction, but its length becomes 1.0. This is important in finding angles, unit vectors and matrix scale. To do this we first get the vectors length, and then divide each part of the vector by it:

normal([1, 2, 3]) =

length = sqrt((1^2) + (2^2) + (3^2))

normal = [1/length, 2/length, 3/length]

The dot product of two 3d vectors (x, y, z), basically returns the magnitude of one vector projected onto another. If we have two vectors [1, 0, 0] and [1, 1, 0]; when we project the latter onto the former, the value along the formers length is the dot product. To get the dot product of two vectors we simply multiply the parts together:

[1, 2, 3] . [4, 5, 6] = (1*4) + (2 * 5) + (3 * 6)

We can use the dot product to get the angle between two vectors too. If we first normalize each vector, we can get the angle by getting the inverse cos (or acos) of this dot. This will return a radian, so we can convert it into degrees by multiplying it by (180 / pi):

cos(norm([1,2, 3] . norm([4, 5, 6]) )^-1 * (180/pi)

Next cross products..

BVH (Biovision) motion data is evil and I for one hate it! I wish when they had come up with the hierarchy, rotation order and transform methods they have firstly in world space, treated rotations as vectors and treated parenting as loosely as possible.

All you want for an animation format is a position of the joint, its direction and its spin – all in vectors with the position being in world space. This way any additional info like parenting can be bolted on without affecting firstly the initial pose or the animation. (as there keyed and set in world space)

The power of this is that, you could just have a set of positions and animation data without any vector info for direction or spin eg.

pos dir spn
[10,10,10] [0,0,0] [0,0,0]

And use it for raw mocap data such as TRC, or Vicom. But also by giving each joint an additional vector value for direction and spin you can use it as an intermediate format to a character rig. Parenting can still exist.

The power of this is that additionally, joints arent tied to the parents local space, and therefore you could store stretching infomation.