Engineering Math - Matrix

 

 

 

Translation in 3D

 

This is an example of translating a 3D object (a Cube) using a translation vector. A vector (translation vector) is added to each vertex of the cube. The result of this example is as shown below.

Translation is the simplest change of position. Every vertex moves by the same vector, so the cube keeps its size, its shape and its orientation. I'll first read the result off the plots, then walk through the code that produced them. Finally, we'll write the same translation as a 4 x 4 matrix, which is the form used when translation is combined with rotation.

What does the translated cube look like ?

A translation is easiest to check in the flat views. There, a shift shows up as a square that has moved along one axis, while its size stays the same. The 3D views give the overall picture, and the flat views give the numbers.

The figure below has two rows of four plots. The red cube in the left half is the original, and the blue cube in the right half is the result. Each half has a 3D view and three flat views, one along each axis. The cube is 1 unit wide and centered at the origin, and the translation vector is [1 0 0].

Red original cube and blue cube translated by 1 along x, each in a 3D view and three flat views

Figure 1. The cube before and after the translation. The whole cube moves 1 unit along x, and nothing else changes.

  • x-z plane : the blue square spans x = 0.5 to 1.5, while the red square spans x = -0.5 to 0.5. The cube has moved 1 unit along x.
  • x-y plane : the same shift along x appears, and the y range stays -0.5 to 0.5.
  • y-z plane : the blue square sits exactly where the red one is. This view looks along the x axis, so it cannot show a shift along x.
  • Size and shape : every square is still 1 x 1, and the 3D view shows the same cube in a new place.

How does the Matlab code move the cube ?

Most of the listing only draws the cube, and just five lines move it. So let's first find those lines, and then check two places where the listing and the figure disagree.

Following is the MatLab code for this example. For now, don't pay too much about the code itself, just focus on number marked in red and try to undertand the mathematical meaning intuitively. You can just copy the code here into your Matlab and change the numbers in red part until you develop the intuitive understanding.

Note : When copy and paste this code, '...' may cause some error. In that case, erase '...' and retry '...' in your matlab editor.

clear all;

% vertices of the cube
vert = [-0.5 -0.5 -0.5;  ...
        -0.5 0.5 -0.5;  ...
         0.5 0.5 -0.5;  ...
         0.5 -0.5 -0.5; ...
        -0.5 -0.5 0.5; ...
         -0.5 0.5 0.5;  ...
          0.5 0.5 0.5; ...
          0.5 -0.5 0.5];

fac = [1 2 3 4; ...
    2 6 7 3; ...
    4 3 7 8; ...
    1 5 8 4; ...
    1 2 6 5; ...
    5 6 7 8];

% original object
subplot(2,4,1);
patch('Faces',fac,'Vertices',vert,'FaceColor','r');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(30,30);
title('original');

% view along y-axis (x-z plane)
subplot(2,4,2);
patch('Faces',fac,'Vertices',vert,'FaceColor','r');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(0,0);
title('x-z plane');

% view along x-axis (y-z plane)
subplot(2,4,5);
patch('Faces',fac,'Vertices',vert,'FaceColor','r');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(90,0);
title('y-z plane');

% view along z-axis (x-y plane)
subplot(2,4,6);
patch('Faces',fac,'Vertices',vert,'FaceColor','r');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(0,90);
title('x-z plane');

% transformed object
% This code add a vector to each vertices of the cube and store the result into TxVertices
TxVector = [1 0 0];
TxVertices = zeros(8,3);
for i = 1:8
    TxVertices(i,:) = vert(i,:) + TxVector;
end

% transformed object
subplot(2,4,3);
patch('Faces',fac,'Vertices',TxVertices,'FaceColor','b');
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(30,30);
title('transformed');

% view along y-axis (x-z plane)
subplot(2,4,4);
patch('Faces',fac,'Vertices',TxVertices,'FaceColor','b');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(0,0);
title('x-z plane');

% view along x-axis (y-z plane)
subplot(2,4,7);
patch('Faces',fac,'Vertices',TxVertices,'FaceColor','b');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(90,0);
title('y-z plane');

% view along z-axis (x-y plane)
subplot(2,4,8);
patch('Faces',fac,'Vertices',TxVertices,'FaceColor','b');
axis([-2 2 -2 2 -2 2]);
grid();
material shiny;
alpha('color');
alphamap('rampdown');
view(0,90);
title('x-z plane');

The red lines are the only part that changes the cube. TxVector = [1 0 0] is the translation vector t. Each row of vert is one vertex, and the loop adds t to each of the eight rows. So the loop computes p' = p + t for every vertex, and stores the result in TxVertices. The array fac lists the four vertices of each of the six faces, and patch draws those faces. The remaining lines draw the same cube from four directions. The command view(30,30) gives the 3D view, and view(0,0), view(90,0) and view(0,90) look along the y, x and z axes.

Two details in the listing differ from the figure. Subplots 6 and 8 call view(0,90), which looks down the z axis, but their titles say 'x-z plane'. The figure shows 'x-y plane' for these two plots, and that is the correct label. Also, subplot 3 has no axis() call in the listing, while the figure shows the same -2 to 2 range as the other plots. Without axis(), Matlab fits the range to the data. So the figure was made with a slightly corrected version of this code.

  • Change TxVector to move the cube elsewhere : [0 1 0] moves it along y, and [1 1 0] moves it diagonally in the x-y plane.
  • Translation is an addition, not a multiplication : the code never multiplies the vertices by a matrix. The next section shows how to turn it into one.
  • The loop can be one line : in Matlab R2016b and later, TxVertices = vert + TxVector gives the same result, because Matlab expands the 1 x 3 vector to all eight rows.
  • The three dots continue a line : '...' is the Matlab line continuation, which lets vert and fac span several lines of the listing.

How is the same translation written as a matrix ?

The code adds a vector, while the rotation example multiplies by a matrix. To chain the two in one step, the translation must also become a matrix product. A plain 3 x 3 matrix cannot do this, because any matrix sends the origin to the origin.

The fix is the homogeneous form from the Affine Mapping page. Each vertex gets a fourth component equal to 1. The translation then becomes a 4 x 4 matrix M, with the identity in the top left block and t in the last column. For this example, t = [1, 0, 0]T. The block below applies M to a general point and to vertex 7 of the cube.

[ x' ]   [ 1  0  0  1 ] [ x ]   [ x + 1 ]
[ y' ] = [ 0  1  0  0 ] [ y ] = [ y     ]
[ z' ]   [ 0  0  1  0 ] [ z ]   [ z     ]
[ 1  ]   [ 0  0  0  1 ] [ 1 ]   [ 1     ]

Vertex 7:   (0.5, 0.5, 0.5, 1)   gives   (1.5, 0.5, 0.5, 1)

In Matlab, the same result comes from one product. Append a column of ones to vert and compute M * [vert ones(8,1)]'. The result is 4 x 8. Its first three rows, transposed, are equal to TxVertices.

  • The inverse moves the cube back : the inverse of M has -1 where M has 1, which is a translation by -t.
  • Two translations add : translating by t1 and then by t2 is one translation by t1 + t2, in either order.
  • Translation keeps shape and size : the top left 3 x 3 block of M is the identity, so lengths, angles and volume do not change.
  • Translation does not commute with rotation : rotating and then translating gives a different result from the reverse order. See Rotation in 3D and Rotation and Translation.