Concatenating? rotations

Started by
5 comments, last by Sneftel 15 years, 3 months ago
I need to concatenate(i think thats the correct word) multiple rotations(maybe translations too), so that in the end I have fully concatenated angles(and positions), like when you multiply a series of matrices together, but I need the results in angles not a matrix, and Im wondering what the best way to do this is. Ive tried making a transformation matrix for each one, multiplying them together, and then extracting the information from the resulting matrix, but im not getting the right numbers from my matrix, so are there any other ways to do this? Heres my functions: vector matXvec(mat3 mat,vector vec)//transform a vector by a matrix { vector temp; temp.x = vec.x * mat[0][0] + vec.y * mat[1][0] + vec.z * mat[2][0]; temp.y = vec.x * mat[0][1] + vec.y * mat[1][1] + vec.z * mat[2][1]; temp.z = vec.x * mat[0][2] + vec.y * mat[1][2] + vec.z * mat[2][2]; return temp; } vector angFromMat(mat3 mat)//extract angles from a 3x3 matrix { vector angle; if(mat[2][0]<1) { if(mat[2][0]>-1) { angle.x=asin(mat[2][0]); angle.y=atan2(-mat[2][1],mat[2][2]); angle.z=atan2(-mat[1][0],mat[0][0]); } else { angle.x=-atan2(mat[0][1],mat[1][1]); angle.y=-PI/2; angle.z=0; } } else { angle.x=atan2(mat[0][1],mat[1][1]); angle.y=PI/2; angle.z=0; } return angle; } mat3 rotMat(float rx,float ry,float rz)//create a rotation matrix { mat3 mat; mat[0][0]=cos(ry)*cos(rz); mat[0][1]=-cos(ry)*sin(rz); mat[0][2]=sin(ry); mat[1][0]=cos(rz)*sin(rx)*sin(ry)+cos(rx)*sin(rz); mat[1][1]=cos(rx)*cos(rz)-sin(rx)*sin(ry)*sin(rz); mat[1][2]=-cos(ry)*sin(rx); mat[2][0]=-cos(rx)*cos(rz)*sin(ry)+sin(rx)*sin(rz); mat[2][1]=cos(rz)*sin(rx)+cos(rx)*sin(ry)*sin(rz); mat[2][2]=cos(rx)*cos(ry); for(int i=0;i<3;i++) for(int j=0;j<3;j++) return mat; } mat3 matXmat(mat3 a,mat3 b)//multiply two matrices together { mat3 ret; int i, j; // row and column counters for (j = 0; j < 3; j++) // transform by columns first for (i = 0; i < 3; i++) // then by rows ret[j] = a[0] * b[0][j] + a[1] * b[1][j] + a[2] * b[2][j]; return ret }
Advertisement
The usual solution is to convert to matrices/quaternions, multiply and then convert back to angles. While we are at it, if you stop using angles the problem goes away.

Since I am converting to matrices, multiplying, and converting back, whats wrong with my code?
Quote:...whats wrong with my code?
Here are some things that could be wrong:

1. The angles you're getting back alias the angles you put in (that is, they're correct, they're just a different - and equivalent - representation of the given orientation).

2. The code that builds the Euler-angle matrix and the code that extracts the Euler angles assume different conventions (e.g. row vs. column vectors).

3. There's a bug/typo/copy-and-paste error in your code somewhere.

I doubt anyone will take it upon themselves to proof your code because a) it's not formatted correctly (use [ source ] tags to correct this), and b) this kind of stuff is tedious and difficult both to write and to proof and debug.

And to echo alvaro, I'll ask, why exactly do you need the final orientation in Euler-angle form?
1: not the problem, ive accounted for that
2: ive tried the various combinations, and none work

I didnt know about the source tags, Ill make sure to use them in the future

I need angles, because Im trying to pre multiply the matrices together, and get the rotations out, so I can then interpolate the angles, and get smooth(in a circle) animation of my points vs interpolating the matrices and having my points move in a straight line
Quote:I need angles, because Im trying to pre multiply the matrices together, and get the rotations out, so I can then interpolate the angles, and get smooth(in a circle) animation of my points vs interpolating the matrices and having my points move in a straight line
If your intent is to interpolate between two or more orientations, using Euler angles is, generally speaking, not the way to do it.

A typical approach to interpolating between two rigid-body transforms (i.e. rotation and translation only) is to interpolate the positions linearly, and interpolate the orientations in quaternion form using SLERP or NLERP. (You can interpolate between orientations directly in matrix form as well, but it's somewhat messy and inefficient.)
Quote:Original post by zacaj
I need angles, because Im trying to pre multiply the matrices together, and get the rotations out, so I can then interpolate the angles, and get smooth(in a circle) animation of my points vs interpolating the matrices and having my points move in a straight line
Linearly interpolated euler angles will NOT result in a smooth animation between rotations. It'll usually give rather silly results, actually. If you need to interpolate between rotations, either convert to quaternions and use SLERP, or (equivalently) convert to axis-angle rotations, find the cross product of the two axes, and use that to create the interpolated rotation part.

This topic is closed to new replies.

Advertisement