Advertisement

Rotation matrix confirmation

Started by July 12, 2005 04:53 PM
9 comments, last by GameDev.net 19 years, 1 month ago
I was just wondering if anyone would confirm for me wheather or not the following would be correct code to rotate a 4x4 matrix initialized to [ 1, 0, 0, 0] [ 0, 1, 0, 0] [ 0, 0, 1, 0] [ 0, 0, 0, 1] acording to given x, y, and z rotation values (yes, i know it is the most inefficient code ever written, i just want to know if its correct or not before i remove all the calls to sin and cos)
rotMat[0][0] = cos(yrot)*cos(zrot)+sin(yrot)*sin(xrot)*sin(zrot);
rotMat[0][1] = cos(yrot)*-sin(zrot)+sin(yrot)*sin(xrot)*cos(zrot);
rotMat[0][2] = sin(yrot)*cos(xrot);

rotMat[1][0] = cos(xrot)*sin(zrot);
rotMat[1][1] = cos(xrot)*cos(zrot);
rotMat[1][2] = -sin(xrot);

rotMat[2][0] = -sin(yrot)*cos(zrot)+cos(yrot)*sin(xrot)*sin(zrot);
rotMat[2][1] = -sin(yrot)*-sin(zrot)+cos(yrot)*sin(xrot)*cos(zrot);
rotMat[2][2] = cos(yrot)*cos(xrot);
I suspect I did something wrong, as all I know of matrix math I learned in a day over the net almost a year ago, and havent used it since.
- relpats_eht
Hi.

the matrix in my textbook is a little different, but only in a few minus signs. I guess it doesn't matter in the end, but just in case:

rotMat[0][0] = cos(yrot)*cos(zrot)+sin(yrot)*sin(xrot)*sin(zrot);
rotMat[0][1] = cos(yrot)*-sin(zrot)+sin(yrot)*sin(xrot)*cos(zrot);
rotMat[0][2] = -sin(yrot)*cos(xrot);

rotMat[1][0] = cos(xrot)*sin(zrot);
rotMat[1][1] = cos(xrot)*cos(zrot);
rotMat[1][2] = sin(xrot);

rotMat[2][0] = sin(yrot)*cos(zrot)-cos(yrot)*sin(xrot)*sin(zrot);
rotMat[2][1] = -sin(yrot)*sin(zrot)-cos(yrot)*sin(xrot)*cos(zrot);
rotMat[2][2] = cos(yrot)*cos(xrot);
Advertisement
well, if its from a textbook then odds are its alot more correct than mine.

thanks for the help
- relpats_eht
Quote: Original post by relpats_eht
well, if its from a textbook then odds are its alot more correct than mine.

thanks for the help


I only have reference to individual X, Y and Z rotation matrices on hand and don't feel like multiplying them together so I can't verify correctness, but if your version differs from the textbook only by a couple of minus signs, chances are one of these is row-major and the other is column-major, as all three matrices are diagonally symmetrical except for minus signs. Neither is more correct, for example DirectX uses row-major and OpenGL uses column major I believe.
Quote: Original post by Ternary
Quote: Original post by relpats_eht
well, if its from a textbook then odds are its alot more correct than mine.

thanks for the help


I only have reference to individual X, Y and Z rotation matrices on hand and don't feel like multiplying them together so I can't verify correctness, but if your version differs from the textbook only by a couple of minus signs, chances are one of these is row-major and the other is column-major, as all three matrices are diagonally symmetrical except for minus signs. Neither is more correct, for example DirectX uses row-major and OpenGL uses column major I believe.


So instead of creating 5 matrices and multiplying them altogether each frame
Identity
Translate
RotX
RotY
RotZ

in the top order. i can replace the matrix elements with letters
[a,b,c,d].. And so on then do the entire thing once. and simple substitute the letters each frame instead.. Will that be faster or even worht the trouble
----------------------------

http://djoubert.co.uk
I'm not sure why you quoted me. Perhaps you misunderstood. relpats_eht's function creates a matrix that performs X, Y and Z rotations, and to create such a function myself I would have to take the X rotation matrix, Y rotation matrix, and Z rotation matrix and multiply them together, on paper, using a pencil.

As for whether it is worth having one matrix for all three rotations, that's up to you, but I'm going to say no. I would imagine the cost of multiplying 5 matrices together is dwarfed by multiplying the final matrix to each point on a reasonably complex mesh. And afterall, there are seperate matrices because not everything is a mesh with six degrees of freedom.
Advertisement
here's OpenGL's implementation of Rotate
As your leader, I encourage you from time to time, and always in a respectful manner, to question my logic. If you're unconvinced that a particular plan of action I've decided is the wisest, tell me so, but allow me to convince you and I promise you right here and now, no subject will ever be taboo. Except, of course, the subject that was just under discussion. The price you pay for bringing up either my Chinese or American heritage as a negative is - I collect your f***ing head.
That is rotation about an arbitrary axis. It's not the same as the product of the X, Y and Z matrix, which is (the order depends on the order multiplied) rotation about the X axis, then rotation about the Y axis, then about the Z axis.
You will find that rotation a matrix around the X/Y or Z axis is actually quite a simple operation compared to a full matrix multiply. Because only 4 elements of the matrix change, and the rest of the matrix is still identity. Therefor, you can optimize it quite a lot, effecivly you will get 12 mults and 8 adds instead of the 96 and 64 of a normal matrix mult operation (off the top of my head, may be slightly off there). Pre compute the sin/cos values you will use, and you can then wrap it in a 'if (sinRot!=0 && cosRot!=1){}' block to optimize it further when the angle is zero.

Quote:
As for whether it is worth having one matrix for all three rotations, that's up to you, but I'm going to say no. I would imagine the cost of multiplying 5 matrices together is dwarfed by multiplying the final matrix to each point on a reasonably complex mesh. And afterall, there are seperate matrices because not everything is a mesh with six degrees of freedom.


What has to be remembered is that in opengl/d3d etc, vertex->matrix multiplication is done in hardware by the video card. It doesn't matter if it's an identity matrix or a projective scew matrix, no matter, the same maths always is carried out. The difference is that the initial matrix maths is carried out on the cpu, not the video card. So there is the potential for inefficiencies, but this is generally not very common unless you are doing something like skeletal animation. (in which case your main bottle neck would be quaternion->matrix conversions...)

ok, so for a rotation matrix, I have

void Matrix::setRotationRadians(float* angles){    double sinX = sin(angles[0]);    double cosX = cos(angles[0]);    double sinY = sin(angles[1]);    double cosY = cos(angles[1]);    double sinZ = sin(angles[2]);    double cosZ = cos(angles[2]);    double sinXsinZ = sinX*sinZ;    double sinXcosZ = sinX*cosZ;        mat[0][0] = float(cosY*cosZ + sinY*sinXsinZ);    mat[0][1] = float(cosY*-sinZ + sinY*sinXcosZ);    mat[0][2] = float(-sinY*cosX);    mat[1][0] = float(cosX*sinZ);    mat[1][1] = float(cosX*cosZ);    mat[1][2] = float(sinX);        mat[2][0] = float(sinY*cosZ - cosY*sinXsinZ);    mat[2][1] = float(-sinY*sinZ - cosY*sinXcosZ);    mat[2][2] = float(cosY*cosX);}


for an inverserotationmatrix, would i simply have to turn all pluses to minuses and vice versa?
- relpats_eht

This topic is closed to new replies.

Advertisement