Hi all,
I’m using Euler’s rotation matrix for rotation about an arbitrary 3D axis. The problem is that if I rotate for a long time or in great angles, it seems like the precision is lost (at least that’s what I think the problem is) and the model starts scaling up quickly. What do you guys think about a way of fixing this?
Thanks,
md2model1_->rotate( dt * 10, Vec3D( 1, 1, 0 ) );
void
Entity::rotate( float angle, Vec3D axis )
{
Mat44 tMat;
float c = cos(angle);
float s = sin(angle);
float mc = 1 - c;
float axy = axis.y * axis.x;
float axz = axis.z * axis.x;
float azy = axis.z * axis.y;
float saxx = s * axis.x;
float saxy = s * axis.y;
float saxz = s * axis.z;
float mxaxysqr = mc * axis.y * axis.y;
float mazy = mc * azy;
float maxz = mc * axz;
float maxy = mc * axy;
tMat.x11 = c + mc * axis.x * axis.x;
tMat.x12 = maxy - saxz;
tMat.x13 = maxz + saxy;
tMat.x21 = maxy + saxz;
tMat.x22 = c + mxaxysqr;
tMat.x23 = mazy - saxx;
tMat.x31 = maxz - saxy;
tMat.x32 = mazy + saxx;
tMat.x33 = c + mxaxysqr;
//Apply the transformation matrix to the model's xformation.
tMatrix_ = tMatrix_ * tMat;
//Save the new axis.
xAxis_ = tMat * xAxis_; xAxis_.normalize();
yAxis_ = tMat * yAxis_; yAxis_.normalize();
zAxis_ = tMat * zAxis_; zAxis_.normalize();
}
One thing you can do is to accumulate the total angle in a variable and then use it as a parameter for your rotate function. But you have to modify your rotate function to do that because when you call model->rotate(angle,axis) you multiply the current transform with the previous transform. Or if you have a load identity function to make tMatrix equal to identity after each iteration of your rendering loop, you can do something like this:
I think the only solution is to use quaternion to represent rotation. Look at this paper at section 4 page 21. That section of the paper explain why quaternion are better than matrix to describe rotation.
So I did added quaternions to my code however; I am having a hard time appending quaternions. If I do one rotation, everything works fine until I start doing multiple.
Below is the function that rotates a quaternion by a certain angle around an axis:
For future reference… There is a very nice Quaternion implementation in the OpenSceneGraph API. I used it to solve a couple of problems with new functions in my maths library the other day. Code is so much easier to read than maths papers!