rotation of vector on diagonal plane

I have a right hand 3d coordinate system, and a vector at [1,1,0]. Using rotations about the x y and z axis, I want to rotate this vector in an orbit about an axis orthogonal to the vector. So that a half rotation of the vector puts it at [-1,-1,0]. In other words, a "diagonal orbit" about the origin. However, I need to describe the path of the vector using x y and z rotations.

I'm having trouble coming up with the correct solution...

Thanks

Rick

Decomposing a rotation matrix

Any rotation matrix about the origin can be expressed as the product of three rotations, one about each axis. So what you are asking is certainly possible. But I am not quite sure why you want to express the rotation like this : it is nothing like so meaningful as finding the axis and the amount of rotation, and the calculation is messy.

I presume you know how to calculate the rotation matrix using conjugation: i.e. pick a new orthonormal coordinate system with one axis the axis of rotation and one the vector. The matrix for the rotation is easy in the new coordinate system, and then you use the usual formula for change of basis to calculate the matrix in the original coordinate system. Given your vector is nice this should be an easy calculation

Then you want to decompose this matrix into rotation about the x,y,z axes. Obviously you get a different answer depending on what order you do things in. The answer is not usually unique - you can often get to the final position in more than one way.

I wrote some C code to do this calculation for a general rotation matrix. I think I decomposed on the basis of rotating first about x,then y,then z. I worked things out by calculating the product of three rotations and then used trig identities to see how I could recover the original values.

To understand the code:

transform is my 3*3 matrix, and I address it as a vector, so transform[0] is the first entry in the first row, transform[5] is the last entry on the second row.

Code:

`y_rot = asin(transform[6]);`

if (transform[7] || transform[8])

{

x_rot = -atan2(transform[7],transform[8]);

z_rot = -atan2(transform[3],transform[0]);

if (x_rot < 0 && z_rot < 0)

{

y_rot = pi-y_rot;

x_rot = atan2(transform[7],-transform[8]);

z_rot = atan2(transform[3],-transform[0]);

}

}

else

{

x_rot = atan2(transform[1],transform[4]);

if (transform[6] < 0)

x_rot = -x_rot;

z_rot = 0;

}

atan2 calculates an angle between -pi and pi radians. atan2(y,x) is arctan(y/x) + some multiple of half pi chosen based on the quadrant implied by the sign of y and x.

I should warn you that I do everything with left hand coordinates because that is more natural for my application. However, I don't think that will make any difference to the calculation at all.

Rotation matrices by conjugation

Here is an example of what I mean. Your original vector is (1,1,0). Lets call that y, and your axis of rotation is orthogonal to this. Lets call that z. To make things easy let's assume it is (0,0,1). Now y cross z which I make to be (1,-1,0), but I suppose could be (-1,1,0) depending on your sign convention for the cross product is a third vector orthogonal to both the other two which we can call x. (In my programs I use an LHS coordinate system, and picked the sign of the cross product so that (1,0,0) cross (0,1,0) is (0,0,1). So I think what I'm doing would work just as well in an ordinary RHS system)

So if we normalise the vectors to length 1 by dividing the first and third by sqrt(2) we have a new orthonormal coordinate system,(A rotation by theta about z looks like $\displaystyle \begin{bmatrix}cos(\theta)&-sin(\theta)&0\\sin(\theta)&cos(\theta)&0\\0&0&1\en d{bmatrix}$, so it is very easy to express any rotation. Let us call this matrix M

Now the matrix that tells us how to get from our new coordinates to our original coordinates is simply [x,y,z] i.e. $\displaystyle \begin{bmatrix}\frac{1}{\sqrt{2}}&\frac{1}{\sqrt{2 }}&0\\ \frac{-1}{\sqrt{2}}&\frac{1}{\sqrt{2}}&0\\0&0&1\end{bmatr ix}$. Call that matrix N

So the rotation matrix for a rotation of theta in our original coordinate system is N * M * N^-1.

Obviously you can do this for any rotation about any axis, though this example will be particularly easy to compute. In fact here I'd be tempted not to bother dividing by $\displaystyle \sqrt{2}$ at all and to use the adjugate matrix instead of the inverse, and then finally just halve all the entries in the final matrix, but you have to be careful with tricks like that as the two basis vectors in the plane being rotated must be the same length.

Once you've computed this matrix you can then apply my method from the last post to compute the x,y, and z rotations required. It might be worth checking what I have done is doing things in the order you want by computing the product

$\displaystyle

\begin{bmatrix}cos(\zeta)&-sin(\zeta)&0\\sin(\zeta)&cos(\zeta)&0\\0&0&1\end{b matrix}*

\begin{bmatrix}cos(\eta)&0&-sin(\eta)\\0&1&0\\sin(\eta)&0&cos(\eta)\end{bmatri x}*

\begin{bmatrix}1&0&0\\0&cos(\xi)&-sin(\xi)\\0&sin(\xi)&cos(\xi)\end{bmatrix}$

That's obviously the most general matrix you can get by multiplying three rotations about the axes. Check that my code usually recovers xi,eta and zeta. (There will certainly be times when it won't).

Conjugation isn't the only way to compute 3D rotation matrices. Some people use quaternions, but I like conjugation as it is easy to work out how to do it from scratch when you have forgotten what order the matrices should go in, and it works for other kinds of transformation as well.