Sign in to follow this  

incremental rotation from existing rotation matrix

This topic is 3624 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a rotation matrix for some rotation about X, Y, Z. I want to rotate incrementally up to the full rotation, from my current rotation. I want to step through with each frame rotating incrementally, up until the target is reached. The tricky part is that I don't know the angles that generated the rotations. current_rotation_matrix is the rotation of the object in its local frame. It is obtained by mainiting a horizontal, vertical, and lateral vector which rotate about each other. The object rotates as it moves around space by rotating those vectors around each other by a small amount. Thus it behaves like an airplane or spacecraft. To obtain the target orientation in the object's frame, I take a separate triplet of direction vectors and rotate by the desired orienation in the universal frame. That puts the target rotation into the object's reference frame, and the difference between the two rotation matricies is the amount that the object needs to rotate in its local frame to reach the desired orientation. Adding the matricies orients the object correctly, but in a "snap", instantaneously, not incrementally. (as you'd expect) matrixType current_rotation_matrix = matrixIdentity(); matrixType target_rotation_matrix = matrixRotateY(90); current_rotation_matrix = matrixSum(current_rotation_matrix, target_rotation_matrix); I have attempted various techniques employing Euler angles, with varying degrees of failure. That is the reason I'm asking here. It may be a bug in my code, but it turns out that the operations: vectorType euler = eulerAnglesFromDirectionCosineMatrix(rotation_matrix); matrixType mat = directionCosineMatrixFromEulerAngles(euler); Are not the reverse of each other, as far as the signs, and quadrants become incorrect. Euler angles are ambiguous and my object tends to end up 180 degrees off in one or more axes. I'd like to do it without using Euler angles if posible. I'd like to be able to just divide the target_rotation_matrix by the number of increments, but that doesn't work of course, because of the scaling it introduces. How can I get for example 1/10th of the rotation represented by target_rotation_matrix? (without the Euler conversion, if possible) Thanks in advance.

Share this post


Link to post
Share on other sites
Assuming you have two matrices, A (your starting transform) and B (your target transform), and you want to go from A to B over 10 frames... then you should just interpolate between them.

E.g., current matrix C is:

C = lerp( A, B, i/9.f), where i (the current frame) is in [0,9].

However, this has the issue of not preserving scale (linearly interpolating matrices isn't always the best idea in the world). You can re-normalize the rotation part of your matrix after each lerp to fix that... Or, you can switch to using quaternions. Before each lerp, convert your matrices to quats, and after the lerp, renormalize, and then convert back to matrix. Or, use Slerp (preserves the length of the interpolated quaternions).

Or is this not the fundamental problem? It was hard to tell from your post if you had explicit matrix representations of your starting transform and your target transform.

There are other ways I suppose as well, such as computing a delta quaternion, or even a delta matrix, and applying that. Also, I didn't go into details of the implementation of any of those operations, in the interest of brevity.

Share this post


Link to post
Share on other sites
Ok, thanks. That is the fundamental problem.
Sounds like I need to use lerp and renormalize.
That is probably the simplest thing to do.
But I'm curious about a delta matrix...
If you can give me a pointer I'd appreciate it.

Share this post


Link to post
Share on other sites
The delta matrix would ultimately accomplish the same thing as lerp mathematically, but could conceivably be slightly cheaper. Again taking your start matrix A and target matrix B:

Delta = ( B - A ) / 10.f

Then, your current matrix C is:

C = A + i * Delta, or, if you're applying the delta each frame, on frame 0 set

C = A, then, on each subsequent frame,
C += Delta

Note you'll still have to renormalize the rotation part of your matrix after each addition of Delta. Additionally, this is less flexible as you have to know at the start (when you initialize Delta) how many frames you'll be interpolating over. If the number of frames is variable, I'd just go with lerp.

FWIW, I'd recommend the quaternion route in the long run, but if you're not familiar with them, it might take a little bit of an initial investment in time to get up to speed (there are many resources on the net, however).

Share this post


Link to post
Share on other sites
Thanks. So the delta is the same math as the lerp, just applied differently. Makes sense. I implemented the lerp, and it works as far as the rotations go. But, of course there are scaling artifacts, so I have a bug somewhere in my renormalization code, I suspect. Once I eliminate that I should have it working.

Share this post


Link to post
Share on other sites

This topic is 3624 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this