# Calculate 3 x 3 rotation matrices from 3 x n matrix

21 views (last 30 days)

Show older comments

I am using the following code to open a .csv file, index columns of interest (euler rotations around x, y, z axes) as single column arrays, and then sequentially order these as a 3 x n matrix:

%Imports geometric camera parameters from phtosynth output .csv in the

%current directory and orders columns as seperate 1 x n matrices

if exist('PARAMETERS_0.csv', 'file') == 2

disp('file found')

[PX PY PZ RX RY RZ] = csvimport('PARAMETERS_0.csv', 'columns', {' PositionX', ' PositionY', ' PositionY', ' RotationX', ' RotationY', ' RotationZ'});

else

disp('camera parameters input file not found')

end

% Sequentially indexes RX RY RZ into a 3 x n matrix where columns are euler

% angles around x y z axes

for i=1:length(RX)

MRV(:,i)=[RX(i);RY(i);RZ(i)];

end

The resulting 3 x n matrix looks like this:

[0.5053 0.5300 0.3820 -0.1594 -0.1289 -0.1107 -1.1684

1.4532 1.4258 1.1240 1.2185 1.2424 1.2131 0.9390

1.4532 1.4258 1.1240 1.2185 1.2424 1.2131 0.9390]

Where individual columns represent euler rotations around x, y z axis (in descending order), describing the orientation of a camera:

e.g.

POV1 =

0.5053

1.4532

1.4532

My problem is that I need to use the euler rotations represented as column vectors in the matrix (MRV) as inputs to calculate a 3 x 3 rotation matrix for each camera position (POV1,..,POVn). The functions to achieve this in the command console would be as follows (example using column 1):

Rx1 = [1 0 0; 0 cosd(MPV(1,1)) -sind(MPV(1,1)); 0 sind(MPV(1,1)) cosd(MPV(1,1))];

Ry1 = [cosd(MPV(2,1)) 0 sind(MPV(2,1)); 0 1 0; -sind(MPV(2,1)) 0 cosd(MPV(2,1))];

Rz1 = [cosd(MPV(3,1)) -sind(MPV(3,1)) 0; sind(MPV(3,1)) cosd(MPV(3,1)) 0; 0 0 1];

RM1 = Rz1*Ry1*Rx1

This function would need to be applied sequentially to each column to give an output rotation matrix of the form:

r11 r12 r13

r21 r22 r23

r31 r32 r33

I know that the code needed would be a for loop of some description but am a bit stuck on the nature of the syntax needed. Any help would be greatly appreciated. Note that I need also to concatenate this rotation matrix with a column vector from an equivalent 3 x n matrix to MRV (x y z position) and a single row array (0 0 0 1) to produce a 4 x 4 matrix (homogeneous coordinates) of the form:

r11 r12 r13 x

r21 r22 r23 y

r31 r32 r33 z

0 0 0 1

So any solution would have to be compatible with next stage in the analysis

##### 0 Comments

### Accepted Answer

Julien
on 9 Oct 2012

Edited: Julien
on 9 Oct 2012

Ok I found an other way, more properly, to store you resulting matrices. You will store them inside a structure and create dynamics fieldnames.

the final code will looks like this :

euler=struct();

for k=1:size(MPV,2)

Rxk = [1 0 0; 0 cosd(MPV(1,k)) -sind(MPV(1,k)); 0 sind(MPV(1,k)) cosd(MPV(1,k))];

Ryk = [cosd(MPV(2,k)) 0 sind(MPV(2,k)); 0 1 0; -sind(MPV(2,k)) 0 cosd(MPV(2,k))];

Rzk = [cosd(MPV(3,k)) -sind(MPV(3,k)) 0; sind(MPV(3,k)) cosd(MPV(3,k)) 0; 0 0 1];

RMk = Rzk*Ryk*Rxk;

euler.(['PV' num2str(k)])=RMk;

end

then to acces one specific matrix, you have to enter euler.PVi. For example, if you want to access PV1, type euler.PV1

##### 2 Comments

Julien
on 9 Oct 2012

you're welcome ;) in fact concatenation is really simple. for example with PV 1: example:

PV1=[PV1 [x y z]';[0 0 0 1]];

using brackets, when you let a space, that indicates you will add columns, and puting a semilcon indicates that you put lines.

so in my code, I first add the x y z column (I use transpose to show you several way to do this. You could also put

[x;y;z]

then I added the line

[0 0 0 1]

### More Answers (1)

Julien
on 9 Oct 2012

Edited: Julien
on 9 Oct 2012

Hi Thomas,

The code is not hard to write. When you want to make sequential calculations, you have first to write it for one specified point (as you did with your first column), and then convert it for any column (by setting indexes).

So if i re-write your code for a column k :

Rxk = [1 0 0; 0 cosd(MPV(1,k)) -sind(MPV(1,k)); 0 sind(MPV(1,k)) cosd(MPV(1,k))];

Ryk = [cosd(MPV(2,k)) 0 sind(MPV(2,k)); 0 1 0; -sind(MPV(2,k)) 0 cosd(MPV(2,k))];

Rzk = [cosd(MPV(3,k)) -sind(MPV(3,k)) 0; sind(MPV(3,k)) cosd(MPV(3,k)) 0; 0 0 1];

RMk = Rzk*Ryk*Rxk

Then, you only need to vary k from 1 to the number of column you have to calculate, that means :

for k=1:size(MPV,2)

Rxk = [1 0 0; 0 cosd(MPV(1,k)) -sind(MPV(1,k)); 0 sind(MPV(1,k)) cosd(MPV(1,k))];

Ryk = [cosd(MPV(2,k)) 0 sind(MPV(2,k)); 0 1 0; -sind(MPV(2,k)) 0 cosd(MPV(2,k))];

Rzk = [cosd(MPV(3,k)) -sind(MPV(3,k)) 0; sind(MPV(3,k)) cosd(MPV(3,k)) 0; 0 0 1];

RMk = Rzk*Ryk*Rxk

end

But if you let it like this, your RMk matrix will be replaced at each iteration. So the question is, how do you want to store each matrix .

EDIT :

You can store each matrix in separated variables using assigning function, so replace

RMk = Rzk*Ryk*Rxk

by

assignin('base',['RM' num2str(k)],Rzk*Ryk*Rxk)

##### 4 Comments

Julien
on 9 Oct 2012

### See Also

### Products

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!