Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Matlab - transformation matrix - what is wrong?

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 17 Nov, 2011 16:35:42

Message: 1 of 18

Hi all

I have a vector (let's call it the x-vector) and based on that, I want
to construct a rotation matrix. To get the y-vector, I multiply the
x-vector with a rotation matrix that I know will my x- and y-vectors
perpendicular. Then to get the z-vector, I cross x- and y-vectors.

Why doesn't this work???

Please see this small example:

%--------------------
x2y_y2z_z2x = [0 0 1 ; 1 0 0 ; 0 1 0]; % rotation matrix

xvec = [...
     0.0455
     0.0218
     -0.9987 ];

yvec = x2y_y2z_z2x * xvec;
zvec = cross(xvec,yvec);

Anew = [xvec yvec zvec];
Anew' * Anew

% ans =
%
% 1.0000 -0.0663 0.0000
% -0.0663 1.0000 0.0000
% 0.0000 0.0000 1.0000
% NB! THIS SHOULD GIVE THE IDENTITY MATRIX - WHY DOESN'T IT WORK???

%-----
% Then I thought I should make sure all vectors are unit vectors:

xvec = xvec./norm(xvec);
yvec = yvec./norm(yvec);
zvec = zvec./norm(zvec);

Anew = [xvec yvec zvec];
Anew' * Anew
%--------------------

Still not working!

Why not?

(code should be copy/paste-able for your convenience)

Subject: Matlab - transformation matrix - what is wrong?

From: Matt J

Date: 17 Nov, 2011 16:49:29

Message: 2 of 18

someone <newsboost@gmail.com> wrote in message <ja3d4u$o8j$1@dont-email.me>...
> Hi all
>
> To get the y-vector, I multiply the
> x-vector with a rotation matrix that I know will my x- and y-vectors
> perpendicular.
==============

This assumption appears to be invalid:


>> dot(xvec,yvec)

ans =

   -0.0662

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 17 Nov, 2011 17:12:26

Message: 3 of 18

On 2011-11-17 17:49, Matt J wrote:
> someone <newsboost@gmail.com> wrote in message
> <ja3d4u$o8j$1@dont-email.me>...
>> Hi all
>>
>> To get the y-vector, I multiply the x-vector with a rotation matrix
>> that I know will my x- and y-vectors perpendicular.
> ==============
>
> This assumption appears to be invalid:
>
>
>>> dot(xvec,yvec)
>
> ans =
>
> -0.0662

Ok, thanks - but why?

What's wrong with my assumptions and why can't I multiply the x-vector
like I do, to get the perpendicular y-vector to begin with (then the
z-vector should be piece of cake, if the y-vector is correct)?

How to fix it?

I don't get it...

Subject: Matlab - transformation matrix - what is wrong?

From: Roger Stafford

Date: 17 Nov, 2011 17:58:08

Message: 4 of 18

someone <newsboost@gmail.com> wrote in message <ja3d4u$o8j$1@dont-email.me>...
> I have a vector (let's call it the x-vector) and based on that, I want
> to construct a rotation matrix. To get the y-vector, I multiply the
> x-vector with a rotation matrix that I know will my x- and y-vectors
> perpendicular. Then to get the z-vector, I cross x- and y-vectors.
>
> Why doesn't this work???
- - - - - - - - -
  Matt is right. You have no reason to expect that xvec and yvec will be orthogonal. The rotation matrix you created performs a rotation through 2/3*pi radians (120 degrees) about the axis vector [1;1;1]. Only a very special vector would be rotated to an orthogonal result. For example, xvec = [(1+sqrt(5))/4;(1-sqrt(5))/4;1/2] would be orthogonal to its yvec, but only because it makes a particular angle with respect to the above axis vector.

Roger Stafford

Subject: Matlab - transformation matrix - what is wrong?

From: Matt J

Date: 17 Nov, 2011 19:06:29

Message: 5 of 18

someone <newsboost@gmail.com> wrote in message <ja3f9r$7ph$1@dont-email.me>...
>
>
> What's wrong with my assumptions and why can't I multiply the x-vector
> like I do, to get the perpendicular y-vector to begin with (then the
> z-vector should be piece of cake, if the y-vector is correct)?
>
> How to fix it?
===============

Further to what Roger said, we can't really tell you "how to fix it", because we don't know what properties you want the result to have. Clearly, you're trying to generate a system of right-handed axes {xvec,yvec,zvec} starting with a known xvec, but there are infinitely many such systems that have xvec in common. What specific properties do you want yours to have?

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 18 Nov, 2011 08:29:29

Message: 6 of 18

On 2011-11-17 20:06, Matt J wrote:
> someone <newsboost@gmail.com> wrote in message
> <ja3f9r$7ph$1@dont-email.me>...
>>
>>
>> What's wrong with my assumptions and why can't I multiply the x-vector
>> like I do, to get the perpendicular y-vector to begin with (then the
>> z-vector should be piece of cake, if the y-vector is correct)?
>>
>> How to fix it?
> ===============
>
> Further to what Roger said, we can't really tell you "how to fix it",
> because we don't know what properties you want the result to have.

I'm not sure I understand this. I want the resulting matrix to be a
valid transformation matrix, i.e. xvec, yvec and zvec should be
orthogonal to each other. The only thing I start from is xvec and based
on that - I must construct yvec. I think zvec is the easiest, because
|xvec|*|yvec| = 1, thus length of zvec is also = 1 and it is known that
it is perpendicular to the 2 other vectors, when using the cross product.

I'm not sure which other properties you're asking me, that I would like
to have. Which other properties are there, other than I demand that:

   Anew' * Anew == eye(3)

Sorry, but I clearly don't understand your answer. I would be very
grateful, if you could elaborate a bit on your answer :-)

> Clearly, you're trying to generate a system of right-handed axes
> {xvec,yvec,zvec} starting with a known xvec, but there are infinitely
> many such systems that have xvec in common. What specific properties do
> you want yours to have?

See my above comments about properties.

I just want one valid solution of the infinite many solutions that you
can come up with. Just give me 1 valid solution, please :-)

Thanks!

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 18 Nov, 2011 08:38:39

Message: 7 of 18

On 2011-11-17 18:58, Roger Stafford wrote:
> someone <newsboost@gmail.com> wrote in message
> <ja3d4u$o8j$1@dont-email.me>...
>> I have a vector (let's call it the x-vector) and based on that, I want
>> to construct a rotation matrix. To get the y-vector, I multiply the
>> x-vector with a rotation matrix that I know will my x- and y-vectors
>> perpendicular. Then to get the z-vector, I cross x- and y-vectors.
>>
>> Why doesn't this work???
> - - - - - - - - -
> Matt is right. You have no reason to expect that xvec and yvec will be
> orthogonal. The rotation matrix you created performs a rotation through
> 2/3*pi radians (120 degrees) about the axis vector [1;1;1]. Only a very

Are you really sure about these 120 degrees? I thought my transformation
matrix, i.e:

x2y_y2z_z2x = [0 0 1 ; 1 0 0 ; 0 1 0]; % rotation matrix

... would rotate the vector it is multiplied by, with 90 degrees in
different directions...

On the other hand: I think you maybe could be right claiming my
x2y_y2z_z2x is wrong, because I don't fully understand this problem (and
why it doesn't work), so I would be really happy for a more thorough
explanation of this issue and how did you get/see/calculate these 120
degrees?

> special vector would be rotated to an orthogonal result. For example,
> xvec = [(1+sqrt(5))/4;(1-sqrt(5))/4;1/2] would be orthogonal to its
> yvec, but only because it makes a particular angle with respect to the
> above axis vector.

Uuh, I'm very confused now... If I understand you correctly:

You're basically saying that my initial rotation matrix is wrong, i.e.
that I cannot derive my yvec like I do. So how do you suggest I derive
my yvec, given that I want to keep my xvec ?

I only demand that yvec is a unit vector (like xvec) and that yvec is
orthogonal to xvec - even though I cannot solve this problem, I cannot
believe it should be difficult for a clever guy (like those in this
forum) :-)

Subject: Matlab - transformation matrix - what is wrong?

From: Matt J

Date: 18 Nov, 2011 15:28:29

Message: 8 of 18

someone <newsboost@gmail.com> wrote in message <ja55if$3uf$1@dont-email.me>...
>
> I only demand that yvec is a unit vector (like xvec) and that yvec is
> orthogonal to xvec - even though I cannot solve this problem, I cannot
> believe it should be difficult for a clever guy (like those in this
> forum) :-)
===================

If that's all you require, why not use two cross products, as follows

if ~isequal(xvec,[1 0 0])

 yvec=cross(xvec,[1 0 0]);
 zvec=cross(xvec,yvec);

else %xvec is just the standard x-axis basis vector,
 
 yvec=[0 1 0];
 zvec=[0 0 1];

end

Subject: Matlab - transformation matrix - what is wrong?

From: Matt J

Date: 18 Nov, 2011 16:04:11

Message: 9 of 18

"Matt J" wrote in message <ja5tit$r9n$1@newscl01ah.mathworks.com>...
>
> If that's all you require, why not use two cross products, as follows
>
> if ~isequal(xvec,[1 0 0])
===============

That should be

if norm(xvec,[1,0,0])

And, obviously, you may want to modify the code to account for the cases where xvec is very close to the x-axis, but doesn't coincide with it.

Subject: Matlab - transformation matrix - what is wrong?

From: Roger Stafford

Date: 18 Nov, 2011 17:25:27

Message: 10 of 18

someone <newsboost@gmail.com> wrote in message <ja55if$3uf$1@dont-email.me>...
> Are you really sure about these 120 degrees? I thought my transformation
> matrix, i.e:
> x2y_y2z_z2x = [0 0 1 ; 1 0 0 ; 0 1 0]; % rotation matrix
> ... would rotate the vector it is multiplied by, with 90 degrees in
> different directions...

  Yes, I am sure that the rotation matrix you defined as [0 0 1;1 0 0;0 1 0] will produce a rotation of 120 degrees about the axis [1;1;1]. One easy way to see this is to apply the transformation to [1;1;1] itself. It leaves it unchanged! That is the way an axis of rotation (through the origin) is supposed to act when its rotation matrix is applied to it. It is the eigenvector of the matrix whose eigenvalue is one. Apply the rotation three times and you get the identity matrix which constitutes an overall 360 degree rotation. Therefore each separate rotation must have been a third of that, namely, 120 degrees.

  Apparently you thought that because this matrix induces a permutation among the coordinates of any vector it is applied to, then it must represent a rotation of 90 degrees, but that is faulty reasoning. Imagine looking at the three x, y, and z axes from the perspective of a point along the [1;1;1] line. What you would see is three axis lines coming out from the origin making equal angles with respect to one another, which therefore must be 120 degrees each, and that is just the perspective from which the rotation is properly viewed.

> You're basically saying that my initial rotation matrix is wrong, i.e.
> that I cannot derive my yvec like I do. So how do you suggest I derive
> my yvec, given that I want to keep my xvec ?

  I have carefully reread your first article in this thread. What you seem to want is to 1) start with some (arbitrary?) unit vector 'xvec', 2) construct some rotation matrix that will rotate 'xvec' through 90 degrees to a perpendicular unit vector 'yvec', and then 3) find a third unit vector 'zvec' which is perpendicular to both of them. Do I state that correctly?

  If that is your aim, then your choice of a rotation matrix is indeed wrong. It is not clear whether your ultimate aim is to find 'yvec' and 'zvec' from 'xvec', or to find the corresponding rotation matrix. If you only want the three orthogonal vectors, then forget about the rotation matrix. You can find the vectors directly using, say, matlab's 'null' function.

  If it is the rotation matrix itself you wish to find, then you still must choose a unit 'zvec' which is orthogonal to 'xvec' and which can act as your axis of rotation. There are infinitely many possibilities. Again you can use 'null' to achieve this. To get 'xvec' to be rotated to an orthogonal 'yvec', the rotation must be through pi/2 radians (90 degrees.) If I had to accomplish this from scratch I would translate the vector equation for a 90 degree rotation about 'zvec', namely,

 w = dot(v,zvec)*zvec + cross(zvec,v),

into a matrix equation

 w = R*v

where v is an arbitrary vector [x;y;z] and w is its rotated version (and 'zvec' is a unit vector.) That R would then be the desired rotation matrix. Very likely Matt's File Exchange routine at:

 http://www.mathworks.com/matlabcentral/fileexchange/26186-absolute-orientation-horns-method

could also perform this operation.

Roger Stafford

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 23 Nov, 2011 13:46:18

Message: 11 of 18

On 2011-11-18 16:28, Matt J wrote:
> someone <newsboost@gmail.com> wrote in message
> <ja55if$3uf$1@dont-email.me>...
>>
>> I only demand that yvec is a unit vector (like xvec) and that yvec is
>> orthogonal to xvec - even though I cannot solve this problem, I cannot
>> believe it should be difficult for a clever guy (like those in this
>> forum) :-)
> ===================
>
> If that's all you require, why not use two cross products, as follows

The truth? Because I'm apparantly too stupid, thank you :-)

> if ~isequal(xvec,[1 0 0])
>
> yvec=cross(xvec,[1 0 0]); zvec=cross(xvec,yvec);
>
> else %xvec is just the standard x-axis basis vector,
>
> yvec=[0 1 0];
> zvec=[0 0 1];
>
> end

I'm terribly sorry for the late answer. I had been travelling just
before I asked the question and then I came back, started doing too many
things and for a few days I forgot I had asked here (ofcourse I
remembered it, when I sat down at looked at this problem again). I'm
sorry. Next: Thank you very much!


However, I don't understand this:

On 2011-11-18 17:04, Matt J wrote:
 > "Matt J" wrote in message <ja5tit$r9n$1@newscl01ah.mathworks.com>...
 >>
 >> If that's all you require, why not use two cross products, as follows
 >>
 >> if ~isequal(xvec,[1 0 0])
 > ===============
 >
 > That should be
 >
 > if norm(xvec,[1,0,0])
 >
 > And, obviously, you may want to modify the code to account for the cases
 > where xvec is very close to the x-axis, but doesn't coincide with it.

I don't understand your second point:

K>> norm(xvec,[1,0,0])
??? Error using ==> norm
The only matrix norms available are 1, 2, inf, and 'fro'.

---------------------

Here's what I think you might have had in mind?

         if all(xvec == crossProdVec)
             yvec = [0 1 0];
             zvec = [0 0 1];
         else
             yvec = cross(xvec,crossProdVec);
             zvec = cross(xvec,yvec);
         end


But it works fine - THANKS!

(sorry again for late answer)

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 23 Nov, 2011 13:46:33

Message: 12 of 18

On 2011-11-18 16:28, Matt J wrote:
> someone <newsboost@gmail.com> wrote in message
> <ja55if$3uf$1@dont-email.me>...
>>
>> I only demand that yvec is a unit vector (like xvec) and that yvec is
>> orthogonal to xvec - even though I cannot solve this problem, I cannot
>> believe it should be difficult for a clever guy (like those in this
>> forum) :-)
> ===================
>
> If that's all you require, why not use two cross products, as follows

The truth? Because I'm apparantly too stupid, thank you :-)

> if ~isequal(xvec,[1 0 0])
>
> yvec=cross(xvec,[1 0 0]); zvec=cross(xvec,yvec);
>
> else %xvec is just the standard x-axis basis vector,
>
> yvec=[0 1 0];
> zvec=[0 0 1];
>
> end

I'm terribly sorry for the late answer. I had been travelling just
before I asked the question and then I came back, started doing too many
things and for a few days I forgot I had asked here (ofcourse I
remembered it, when I sat down at looked at this problem again). I'm
sorry. Next: Thank you very much!


However, I don't understand this:

On 2011-11-18 17:04, Matt J wrote:
 > "Matt J" wrote in message <ja5tit$r9n$1@newscl01ah.mathworks.com>...
 >>
 >> If that's all you require, why not use two cross products, as follows
 >>
 >> if ~isequal(xvec,[1 0 0])
 > ===============
 >
 > That should be
 >
 > if norm(xvec,[1,0,0])
 >
 > And, obviously, you may want to modify the code to account for the cases
 > where xvec is very close to the x-axis, but doesn't coincide with it.

I don't understand your second point:

K>> norm(xvec,[1,0,0])
??? Error using ==> norm
The only matrix norms available are 1, 2, inf, and 'fro'.

---------------------

Here's what I think you might have had in mind?

         if all(xvec == crossProdVec)
             yvec = [0 1 0];
             zvec = [0 0 1];
         else
             yvec = cross(xvec,crossProdVec);
             zvec = cross(xvec,yvec);
         end


But it works fine - THANKS!

(sorry again for late answer)

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 23 Nov, 2011 14:20:56

Message: 13 of 18

On 2011-11-18 18:25, Roger Stafford wrote:
> someone <newsboost@gmail.com> wrote in message
> <ja55if$3uf$1@dont-email.me>...
>> Are you really sure about these 120 degrees? I thought my
>> transformation matrix, i.e:
>> x2y_y2z_z2x = [0 0 1 ; 1 0 0 ; 0 1 0]; % rotation matrix
>> ... would rotate the vector it is multiplied by, with 90 degrees in
>> different directions...

Uh, I'm very sorry about the late answer - as I also explained to Matt
J... Not sure whether I get an answer now, anyway:

> Yes, I am sure that the rotation matrix you defined as [0 0 1;1 0 0;0 1
> 0] will produce a rotation of 120 degrees about the axis [1;1;1]. One
> easy way to see this is to apply the transformation to [1;1;1] itself.
> It leaves it unchanged! That is the way an axis of rotation (through the
> origin) is supposed to act when its rotation matrix is applied to it. It

Ok, you're right, I think...

> is the eigenvector of the matrix whose eigenvalue is one. Apply the

The axis of rotation... when its rotation matrix is applied to it, is
the eigenvector of the matrix whose eigenvalue is 1 ? Damn, I wish I was
good at eigenvectors and eigenvalues, I still don't understand it:

K>> [v,d]=eig(eye(3))

v =

      1 0 0
      0 1 0
      0 0 1


d =

      1 0 0
      0 1 0
      0 0 1

K>> [v,d]=eig( x2y_y2z_z2x )

v =

    0.5774 0.5774 -0.5774
   -0.2887 - 0.5000i -0.2887 + 0.5000i -0.5774
   -0.2887 + 0.5000i -0.2887 - 0.5000i -0.5774


d =

   -0.5000 + 0.8660i 0 0
         0 -0.5000 - 0.8660i 0
         0 0 1.0000

???

> rotation three times and you get the identity matrix which constitutes
> an overall 360 degree rotation. Therefore each separate rotation must
> have been a third of that, namely, 120 degrees.

hmm. Can you explain that about eigenvectors and eigenvalues again?

I don't understand it, sorry :-)

> Apparently you thought that because this matrix induces a permutation
> among the coordinates of any vector it is applied to, then it must
> represent a rotation of 90 degrees, but that is faulty reasoning.

I thought that it would make the xvector into a yvector, yvector into a
zvector and zvector into an xvector, by changing the column order in the
original identity matrix... I looked at the columns, I consider column 1
as x, column 2 as y and column 3 as z...

> Imagine looking at the three x, y, and z axes from the perspective of a
> point along the [1;1;1] line. What you would see is three axis lines

Yes.

> coming out from the origin making equal angles with respect to one
> another, which therefore must be 120 degrees each, and that is just the
> perspective from which the rotation is properly viewed.

Hmm.

>> You're basically saying that my initial rotation matrix is wrong, i.e.
>> that I cannot derive my yvec like I do. So how do you suggest I derive
>> my yvec, given that I want to keep my xvec ?
>
> I have carefully reread your first article in this thread. What you seem
> to want is to 1) start with some (arbitrary?) unit vector 'xvec', 2)
> construct some rotation matrix that will rotate 'xvec' through 90
> degrees to a perpendicular unit vector 'yvec', and then 3) find a third
> unit vector 'zvec' which is perpendicular to both of them. Do I state
> that correctly?

Yep, I think it works now using this code:


         crossProdVec = [1;0;0];

         % don't want to cross xvec with itself (it gives [0;0;0])
         if all(xvec == crossProdVec)
             yvec = [0 1 0];
             zvec = [0 0 1];
         else
             yvec = cross(xvec,crossProdVec);
             zvec = cross(xvec,yvec);
         end

         xvec = xvec./norm(xvec);
         yvec = yvec./norm(yvec);
         zvec = zvec./norm(zvec);

         Anew = [xvec yvec zvec];
         Anew' * Anew

Last line should give eye(3)...

> If that is your aim, then your choice of a rotation matrix is indeed
> wrong. It is not clear whether your ultimate aim is to find 'yvec' and
> 'zvec' from 'xvec', or to find the corresponding rotation matrix. If you

I consider xvec = column 1, yvec = column 2 and zvec = column 3 in the
rotation matrix... ?

> only want the three orthogonal vectors, then forget about the rotation
> matrix. You can find the vectors directly using, say, matlab's 'null'
> function.

Unfortunately, my linear algebra skills are not too good. If I say:

  A=[...
         1 2 3
         1 2 3
         1 2 3]


  Z = null(A)

It responds with 2 vectors:
Z =
          0 0.9636
    -0.8321 -0.1482
     0.5547 -0.2224

If I say: null(A,'r') it gives these 2 vectors:

ans =
     -2 -3
      1 0
      0 1

What exactly are these two vectors? Let me guess: "an orthonormal basis
for the null space" - I don't understand what that means. Well... I
think I understand orthonormal - it's like perpendicular in my mind, the
"null space" I don't understand :-)

> If it is the rotation matrix itself you wish to find, then you still
> must choose a unit 'zvec' which is orthogonal to 'xvec' and which can
> act as your axis of rotation. There are infinitely many possibilities.

Yep, agreed about infinitely many solutions. Yep, it's the rotation
matrix I would like to find...

> Again you can use 'null' to achieve this. To get 'xvec' to be rotated to
> an orthogonal 'yvec', the rotation must be through pi/2 radians (90
> degrees.) If I had to accomplish this from scratch I would translate the
> vector equation for a 90 degree rotation about 'zvec', namely,

huh? Why do you start from zvec? In my example, I started from a known
xvec and then I had to find yvec and zvec.

> w = dot(v,zvec)*zvec + cross(zvec,v),

hmmm... w = dot product of arbitrary v-vector with (known) zvec I
assume? In my case shouldn't it be, dot(v,xvec)*xvec because the only
thing I know in the beginning is the xvector?

And then you make dot product v, zvec. Isn't that something like
projecting v into zvec (or is it zvec into v) and then you multiply with
zvec - isn't that to get the length of this vector right? And then you
add something: cross zvec with v. Cross product is like making a plane
out of the two vectors and then finding a vector that is perpendicular
to the plane (neglecting the length of the vector). hmm...

> into a matrix equation
>
> w = R*v
>
> where v is an arbitrary vector [x;y;z] and w is its rotated version (and
> 'zvec' is a unit vector.) That R would then be the desired rotation

Great. Hmmm... I think I would like to understand it a little better,
before trying to code it and seeing it for myself :-)

> matrix. Very likely Matt's File Exchange routine at:
>
> http://www.mathworks.com/matlabcentral/fileexchange/26186-absolute-orientation-horns-method
>
>
> could also perform this operation.

The last part, I didn't understand. If it's not too rude, can I ask you
to show a minimal example of code? Or if you could please comment on my
stupid questions, then I could maybe understand it enough so that I can
code it myself.

Thanks! It's great to learn a bit of essential linear algebra here -
I've always wanted to be better with eigenvalues and eigenvectors and
rotation matrixes...

Subject: Matlab - transformation matrix - what is wrong?

From: Matt J

Date: 23 Nov, 2011 16:22:08

Message: 14 of 18

someone <newsboost@gmail.com> wrote in message <jaivg8$ogp$1@dont-email.me>...
>
> Yep, I think it works now using this code:
>
>
> crossProdVec = [1;0;0];
>
> % don't want to cross xvec with itself (it gives [0;0;0])
> if all(xvec == crossProdVec)
> yvec = [0 1 0];
> zvec = [0 0 1];
> else
> yvec = cross(xvec,crossProdVec);
> zvec = cross(xvec,yvec);
> end
================

No. It will still fail if xvec=[-1;0;0] . Here's what you probably want:


xvec = xvec./norm(xvec);

SmallTolerance=1e-6; %You choose this.

if norm(xvec(2:3))<=SmallTolerance %xvec is highly paralllel to x-axis

         crossProdVec = [0;1;0];

else
           crossProdVec = [1;0;0];

end

             yvec = cross(xvec,crossProdVec);
             zvec = cross(xvec,yvec);
      
         

Subject: Matlab - transformation matrix - what is wrong?

From: someone

Date: 24 Nov, 2011 13:16:58

Message: 15 of 18

On 2011-11-23 17:22, Matt J wrote:
> someone <newsboost@gmail.com> wrote in message
> <jaivg8$ogp$1@dont-email.me>...
>>
>> Yep, I think it works now using this code:
>>
>>
>> crossProdVec = [1;0;0];
>>
>> % don't want to cross xvec with itself (it gives [0;0;0])
>> if all(xvec == crossProdVec)
>> yvec = [0 1 0];
>> zvec = [0 0 1];
>> else
>> yvec = cross(xvec,crossProdVec);
>> zvec = cross(xvec,yvec);
>> end
> ================
>
> No. It will still fail if xvec=[-1;0;0] . Here's what you probably want:
>
>
> xvec = xvec./norm(xvec);
>
> SmallTolerance=1e-6; %You choose this.
>
> if norm(xvec(2:3))<=SmallTolerance %xvec is highly paralllel to x-axis
>
> crossProdVec = [0;1;0];
>
> else
> crossProdVec = [1;0;0];
>
> end
>
> yvec = cross(xvec,crossProdVec);
> zvec = cross(xvec,yvec);

Ah, of course!

Thank you very much...

A shame if Roger Stafford doesn't see my other linear algebra post about
understanding different aspects of the rotational matrix, because I was
so slow at answering... I think he has a really good understanding of
this, which I lack :-)

Subject: Matlab - transformation matrix - what is wrong?

From: Roger Stafford

Date: 28 Nov, 2011 06:39:08

Message: 16 of 18

someone <newsboost@gmail.com> wrote in message <jalg4b$d3v$1@dont-email.me>...
> A shame if Roger Stafford doesn't see my other linear algebra post about
> understanding different aspects of the rotational matrix, because I was
> so slow at answering... I think he has a really good understanding of
> this, which I lack :-)
- - - - - - - - -
  Hello 'Someone'. I'm sorry I have been so slow in responding to your Nov. 23 & 24 posts. It is simply that I have not fully understood what it is you want to accomplish. It seems clear that you are starting with only a single defined vector which you call 'xvec'. From this you wish to derive a pair of other vectors, 'yvec' and 'zvec', forming an orthogonal set with 'xvec' and perhaps a rotation matrix which rotates 'xvec' into 'yvec' through ninety degrees. What has not been clear is whether it is the rotation matrix that is your ultimate goal or simply the other two vectors.

  As I asserted earlier, if you only want the other two vectors, then the matlab function 'null' is what you need. First, realize that there are infinitely many possibilities. Assuming 'xvec' is a row vector, do this:

 xvec = xvec/norm(xvec); % Make sure 'xvec' is a unit vector
 n = null(x); % The columns of n will be 'yvec' and 'zvec'
 yvec = n(:,1).'; % Make them separate row vectors
 zvec = n(:,2).';
 if det([xvec;yvec;zvec]) < 0 % Make xvec,yvec,zvec a right hand set
  zvec = -zvec;
 end
 % Test for orthogonality
 [xvec;yvec;zvec]*[xvec;yvec;zvec].' % This should be eye(3) (within roundoff error)

As you see, there is no need to obtain a rotation matrix if this is your only aim. Note also that 'yvec' and 'zvec' can be any two orthogonal vectors which lie in a plane which is itself orthogonal to 'xvec', and of course there are infinitely many such pairs.

  On the other hand, if you desire the rotation matrix also, you are still faced with infinitely many choices. Presumably you want the rotation matrix to rotate 'xvec' into 'yvec' with a ninety-degree rotation and you want the axis of rotation to lie along the line of 'zvec' where again these three vectors form a (right-hand) orthonormal system. There are infinitely many ways to do this, and, as I mentioned before, the easiest way to accomplish this is to proceed as above using 'null' to create both 'yvec' and 'zvec' at the same time.

  Having accomplished this, you then give the general expression for a rotation matrix about the origin as follows. Let the axis of rotation be a unit vector w = [wx;wy;wz] (short for 'zvec'.), let the angle of rotation be t (short for theta), and let P = [x;y;z) be an arbitrary vector. Then P will be transformed into vector Q according to the equation

 Q = dot(P,w)*w + cos(t)*cross(cross(w,P),w) + sin(t)*cross(w,P)

This follows from ordinary vector analysis by taking appropriate components of P with respect to 1) the vector w, 2) a vector orthogonal to the plane of P and w, and 3) a vector orthogonal to each of these, and then rotating P in a circle in the plane of the second two of these vectors through the angle t (in a right hand sense.)

  If you (tediously) rewrite this as an equivalent matrix multiplication of the column vector P, the results (after much sweat) will be:

 Q = R*P

where

 R = [wx^2+(wy^2+wz^2)*cos(t),wx*wy*(1-cos(t))-wz*sin(t),wz*wx*(1-cos(t))+wy*sin(t);
      wx*wy*(1-cos(t))+wz*sin(t),wy^2+(wz^2+wx^2)*cos(t),wy*wz*(1-cos(t))-wx*sin(t);
      wz*wx*(1-cos(t))-wy*sin(t),wy*wz*(1-cos(t))+wx*sin(t),wz^2+(wx^2+wy^2)*cos(t)]

  In your case of t = pi/2 (90 degrees) you will have:

 R = [wx^2,wx*wy-wz,wz*wx*wy;
      wx*wy+wz,wy^2,wy*wz-wx;
      wz*wx-wy,wy*wz+wx,wz^2];

  In connection with my assertion that your R was incorrect, notice that you can work backwards from a known R to the axis of revolution and the angle. If you take the eigenvector/eigenvalue of R you will get either +w or -w for the eigenvector whose eigenvalue is 1. On my computer with your R = [0 0 1 ; 1 0 0 ; 0 1 0] I got w = [-1/sqrt(3);-1/sqrt(3);-1/sqrt(3)] (which I spoke of as [1;1;1] simply because they are both parallel.) Having found w, you can then determine the angle t by

 t = atan2(wx*(R(3,2)-R(2,3))+wy*(R(1,3)-R(3,1))+wz*(R(2,1)-R(1,2)),(trace(R)-1)/2);

as you can readily check from the above general formula. For the above w this would give t = -2/3*pi, or reversing the sign of w would give +2/3*pi (120 degrees.) (I claim my argument about viewing things from a perspective along the w line is easier to comprehend.)

Roger Stafford

Subject: Matlab - transformation matrix - what is wrong?

From: Roger Stafford

Date: 28 Nov, 2011 06:59:09

Message: 17 of 18

"Roger Stafford" wrote in message <javaac$4sq$1@newscl01ah.mathworks.com>...
> t = atan2(wx*(R(3,2)-R(2,3))+wy*(R(1,3)-R(3,1))+wz*(R(2,1)-R(1,2)),(trace(R)-1)/2);
- - - - - - - -
  I see I made an error in the expression for the angle, t. It should be:

 t = atan2(wx*(R(3,2)-R(2,3))+wy*(R(1,3)-R(3,1))+wz*(R(2,1)-R(1,2)),trace(R)-1);

That is, there should be no division by 2 in the second argument.

Roger Stafford

Subject: Matlab - transformation matrix - what is wrong?

From: Roger Stafford

Date: 28 Nov, 2011 20:06:11

Message: 18 of 18

"Roger Stafford" wrote in message <javaac$4sq$1@newscl01ah.mathworks.com>...
> n = null(x); % The columns of n will be 'yvec' and 'zvec'
- - - - - - - - - -
  I spotted another misprint. The call on 'null' should be:

 n = null(xvec);

Roger Stafford

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us