Jump to content
  • Advertisement
Sign in to follow this  
stu2000

Quaternion Fun!

This topic is 2905 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

Hey I have massive problems understanding quaternions, which is a huge problem for me as a programmer here is my problem:

I have two quaternions which represent two orientations of an object in local space:

Quaternion current_orientation
Quaternion desired_orientation

I would like to get from one to the other using something like as follows:

Quaternion offset <- some value that can be added or multiplied or anything to currrent orientation to get to desired orientation
offset_chunk <- equally divisible chunk of the offset quaternion such that adding/multiplying it to current orientation N number of times over N frames/timesteps will result in a smooth rotation from current Orientation to desired_orientation

Could someone please show me how to calculate the offset quaternion from the two provided quaternions current_orientation and desired_orientation. (represented x, y, z, w please i j k etc only if you have to) and also show me how to derive offset_chunk quaternion from that, and how you would apply the offset chunk each frame, ie a multiplication or addition and normalization etc.

Very much apprecitated.
Stu

Share this post


Link to post
Share on other sites
Advertisement
Okay, ive decided to work around the problem by using matrices. I figure once i have the matrix offset i can just multiply the current rotation by the offset each frame to get the final result.

I already have the full rotation i desire. If i divide each of the 9 elements in the totalRotationOffset by N would that produce the 'chunk matrix' i desire to rotate by for each of the N frames?

Stu

Share this post


Link to post
Share on other sites
You will eventually find out that linear interpolation with matrices is not going to get you the desired result. Which means you will end up having to use quaternion. My advice, learn the mathematical basis behind quaternion or any other concept before blindly using them. Once you have the foundation then its a simple as applying what you have learn. Everyone on the forum can 'show' you, but only you can absorb the knowledge ('learn' ) from what is shown.

Share this post


Link to post
Share on other sites
Dividing the matrix elements by N will simply scale the matrix by 1/N. Since matrix transformations accumulate by multiplication, you need the N:th root of the matrix, and arbitrary matrix roots are not trivial to compute in general.

I agree with cgrant, doing this with matrices is probably not the best solution. if you have a start and end quaternion, the interpolation between the rotations is trivial.

Share this post


Link to post
Share on other sites
Hehe...what is going on here!? You posted the same question in the DirectX forum, and SLERP was suggested. You ditched that thread, re-posted here, SLERP was suggested again, and you ignored it, saying you were going to linearly interpolate matrices instead (or something). Do you have something against SLERP? :-)

Remember you can ask follow-up questions - it's allowed ;) If you're not sure what SLERP is or how it relates to your problem, just ask.

Anyway, you can do what you're asking about using SLERP. However, to answer your specific question, you can compute the 'difference value' that you're asking about by multiplying one of the quaternions by the conjugate of the other. Then, you can use quaternion exp() or log() or something (I can't remember off the top of my head and I'm not going to look it up right now) to compute a 'delta' quaternion that you can then use to rotate incrementally from the first orientation to the second. (Basically what this boils down to is converting the 'difference' quaternion to axis-angle form, scaling the angle, and then converting back.) The end result will the same as with SLERP, more or less (although the means of getting there is a little different).

You can do the same sort of thing with matrices but it's both less efficient and (arguably) less elegant.

Share this post


Link to post
Share on other sites
Quote:
Original post by Brother Bob
Dividing the matrix elements by N will simply scale the matrix by 1/N. Since matrix transformations accumulate by multiplication, you need the N:th root of the matrix, and arbitrary matrix roots are not trivial to compute in general.

I agree with cgrant, doing this with matrices is probably not the best solution. if you have a start and end quaternion, the interpolation between the rotations is trivial.


Yes I should have though of that.
Surely a simpler solution would be to Get the two direction vectors from the two rotations, assuming a direction vector of (0,0,1) when no rotation applied, representing say V0. R1 and R2 would represent the two rotation matrices of orientation, then,

V1 = V0 * R1
V2 = V0 * R2

cross product of v1, v2 gets the axis of rotation
angle of rotation (theta) = acos(v1•v2) (since v1 and v2 are already normalised)

then just divide theta by N (the number of frames desired)

Now just derive the rotationOffsetMatrix chunk from the axis of rotation and the new theta

This is EXACTLY the same as Part III: Spherical Linear Interpolations (SLERPS) in this gamedev article: 'Do We Really Need Quaternions?' http://www.gamedev.net/reference/articles/article1199.asp

Share this post


Link to post
Share on other sites
Yes, that is probably the preferred solution if you have a start and end direction you want to rotate between. As I said, if you start with quaternions though, interpolation with quaternions is probably more convenient. So chose the tool that fits the job.

As the saying goes; if all you have is a hammer, then all problems look like a nail. Don't focus only on solving it with matrices. You said you had quaternions, so solve it with quaternions.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Hehe...what is going on here!? You posted the same question in the DirectX forum, and SLERP was suggested. You ditched that thread, re-posted here, SLERP was suggested again, and you ignored it, saying you were going to linearly interpolate matrices instead (or something). Do you have something against SLERP? :-)

Remember you can ask follow-up questions - it's allowed ;) If you're not sure what SLERP is or how it relates to your problem, just ask.

Anyway, you can do what you're asking about using SLERP. However, to answer your specific question, you can compute the 'difference value' that you're asking about by multiplying one of the quaternions by the conjugate of the other. Then, you can use quaternion exp() or log() or something (I can't remember off the top of my head and I'm not going to look it up right now) to compute a 'delta' quaternion that you can then use to rotate incrementally from the first orientation to the second. (Basically what this boils down to is converting the 'difference' quaternion to axis-angle form, scaling the angle, and then converting back.) The end result will the same as with SLERP, more or less (although the means of getting there is a little different).

You can do the same sort of thing with matrices but it's both less efficient and (arguably) less elegant.


Yes thx for that. I didn't deliberately 'ditch' it. I posted the question, left the forum, and I'd forgotten to put up 'email when someone responds' and then couldnt find it again. Since i had run a search and nothing came up, i had assumed my browser hadn't posted before i had closed the tab window. Many apologies. Dont know why i posted in the DirectX section.

Share this post


Link to post
Share on other sites
Quote:
Original post by Brother Bob
Yes, that is probably the preferred solution if you have a start and end direction you want to rotate between. As I said, if you start with quaternions though, interpolation with quaternions is probably more convenient. So chose the tool that fits the job.

As the saying goes; if all you have is a hammer, then all problems look like a nail. Don't focus only on solving it with matrices. You said you had quaternions, so solve it with quaternions.


Really I have both. Quaternions only pop up because send and receive them over net instead of matrices as it costs less bandwidth, but most of the time dealing with matrices, as all the rotations I get and set in the code are in terms of 3d or 4d Matrix

In terms of speed, isn't performing one matrix multiplication (9 multiplications on 3x3 matrix) cheaper than performing a Slerp every frame? I only have to calculate the offset matrix once roughly every 6.25 frames at worst performance. ie probably more frames pass by than just 6.25 .

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!