Introduction

triangle

When we playing we see moving objects around the scenery, so today let's have a look how one of the most important pieces of that movement works: translation. There are many ways to perform the same maths, but the GPU must follow the defined pipeline and that's way we use matrices.

 

 

Translation matrix

First of all we have to think in a single point, a single point can be defined in the following way: p(x, y) where x means its position in abscissas and y it position in coordinates, so let's plot the following point p(2,1),

 

Really simple, right. What happens if we want to move the point in one in both axis, we have to add p(1, 1) to the previous point and the plot result is this:

All of this seems to be right, so we move the points by adding values to our current points p'(x, y) = p(x, y) +p(<x movement>, <y movement>). The translation matrix for a point 3D is the following:

 T_{\mathbf{v}} \mathbf{p} =
\begin{bmatrix}
1 & 0 & 0 & v_x \\
0 & 1 & 0 & v_y\\
0 & 0 & 1 & v_z\\
0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
p_x \\ p_y \\ p_z \\ 1
\end{bmatrix}
=
\begin{bmatrix}
p_x + v_x \\ p_y + v_y \\ p_z + v_z \\ 1
\end{bmatrix}
= \mathbf{p} + \mathbf{v}

 

In this way in our code we just need to add a Matrix4f, that we call World, where each point will be processed:

    Matrix4f World;
    World.m[0][0] = 1.0f; World.m[0][1] = 0.0f; World.m[0][2] = 0.0f; World.m[0][3] = sinf(scale);       
    World.m[1][0] = 0.0f; World.m[1][1] = 1.0f; World.m[1][2] = 0.0f; World.m[1][3] = cosf(scale);
    World.m[2][0] = 0.0f; World.m[2][1] = 0.0f; World.m[2][2] = 1.0f; World.m[2][3] = 0.0f;
    World.m[3][0] = 0.0f; World.m[3][1] = 0.0f; World.m[3][2] = 0.0f; World.m[3][3] = 1.0f;

 Take a moment to understand the matrix, according to the previous definition we are gonna change the value of Vx and Vy by processing its sin and cos respectively. Vz is always zero. Remember that cos(0) = 1 and sin (0) = 0 so what we se when we run this is that the triangle is following a circumference on its translation movement.

 

Rotation matrix

Now what we have is two vectors, one pointing to v = {0, 2} and the second to v' = {2, 0}. We've rotated the first vector by 90 degrees clockwise in order to get the second one, but how to do that? Well, we know tan(α) = sin (α) / cos (α), it's a trigonometry identity, so also the following is true:

 

where α is the angle between the abscissa and the vector v, so we can say that tan(α) = y / x. If we know 'α which is the new angle, somewhing true, we are able to calculate x and y by calculating sin('α) and cos('α), Finally, the rotation matrix is as follows:

{\displaystyle R_{z}(90^{\circ }){\begin{bmatrix}1\\0\\0\\\end{bmatrix}}={\begin{bmatrix}\cos 90^{\circ }&-\sin 90^{\circ }&0\\\sin 90^{\circ }&\quad \cos 90^{\circ }&0\\0&0&1\\\end{bmatrix}}{\begin{bmatrix}1\\0\\0\\\end{bmatrix}}={\begin{bmatrix}0&-1&0\\1&0&0\\0&0&1\\\end{bmatrix}}{\begin{bmatrix}1\\0\\0\\\end{bmatrix}}={\begin{bmatrix}0\\1\\0\\\end{bmatrix}}}

when applying the rotation on the XY plane. Our translation + rotation matrix is the following:

    World.m[0][0] = cosf(scale); World.m[0][1] = -sinf(scale); World.m[0][2] = 0.0f; World.m[0][3] = sinf(scale);
    World.m[1][0] = sinf(scale); World.m[1][1] = cosf(scale);  World.m[1][2] = 0.0f; World.m[1][3] = cosf(scale);
    World.m[2][0] = 0.0f;        World.m[2][1] = 0.0f;         World.m[2][2] = 1.0f; World.m[2][3] = 0.0f;
    World.m[3][0] = 0.0f;        World.m[3][1] = 0.0f;         World.m[3][2] = 0.0f; World.m[3][3] = 1.0f;

 

All code is available here.