Quaternion rotations

Started by
6 comments, last by Coz 14 years ago
I have no problem at using a single Quaternion to rotate a point, or with interpolating between two quaternions. I think about Quaternions as some sort of axis-angle rotation. However, handling axis separately is difficult for me. For example, I have a floating character that is looking in a direction. For this I just rotated the character around the Y-axis, since the character should keep it's feet down and face up, so the rotation angle around the X and Z axis are be 0. Now, presume that something applies torque to the character. Now my character has to correct it's orientation by applying torque to look in that direction, and it's what I'm having problems with. I can't just override the orientation instead of applying torque, because then the character's orientation won't interact with any incoming forces during that time. And this torque is represented by a XYZ vector. I converted the quaternion's Y-axis rotation to Euler and this works fine, even thought there might be a less complex and computationally-intensive way. Now, should I do the same for the X and Z axis? what's the best way to extract the rotations around each axis while keeping this function fast?
Advertisement
I dont think your character should react to torques in this manor. It should be handled at a higher level, with animations and stuff.

But anyways. I'm not sure how accurate it is but it works pretty well if you project a torque or angular vector onto another to perceive the rotation from a particular axis.

If the character is to handle an arbitrary torque but only around the vertical axis you can project all incoming torques onto that axis.
Quote:Original post by bzroom
I dont think your character should react to torques in this manor. It should be handled at a higher level, with animations and stuff.


I plan to add an animation too.

Quote:But anyways. I'm not sure how accurate it is but it works pretty well if you project a torque or angular vector onto another to perceive the rotation from a particular axis.


I just mentioned torque to make it clear why I need each angle independently.

My problem is not with applying the torque, but with getting the angles from the Y-axis independently from the X and Z axis rotations, from a quaternion. And I'm afraid that using Euler angles for more than one axis will make rotations dependent on the order.

Quote:If the character is to handle an arbitrary torque but only around the vertical axis you can project all incoming torques onto that axis.


That doesn't sounds so bad, but I would rather have my character to be affected through all axis so that it feels more responsive. I guess this would be a second choice if I can't pull the first one off.
You can use this quaternion formula



Where qi is the initial quaternion, and can represent the y-axis aligned orientation of the character. The Δq quaternion represents the interaction, or animation, or whatever.

There are a few ways to calculate Δq. You can use an axis and angle, or you can use my current favorite method, where you use the initial and final vectors to construct Δq. This method was discussed in a recent post on this forum, as well as on my blog (look at trick #3). This trick is useful for doing things like pointing the characters face towards something.

One thing you need to be aware of, is that any vectors that you use to construct Δq need to be in the local space of qi. If you use the axis angle method, the axis needs to be specified relative to the character, not relative to the world. If you are going to use the initial/final vector trick, this applies as well. Both vectors need to be specified in the characters local space. However, the initial vector is likely not to change especially if it is the direction that the character is looking.

EDIT: the link to my blog is OK, but you should look at trick #2, not trick #3

[Edited by - Eric_Brown on March 25, 2010 4:58:15 PM]
Thank you, VERY useful. =]
Quote:[...]you can use my current favorite method, where you use the initial and final vectors to construct Δq.[...]


A small follow-up: I ended up using Euler angles any ways. Though I definitely will use the useful information you gave in the future, to extract independent axis from the 3D vector, I would have to construct 3 normalized 2D vectors, which means 3 costly sqrt calls.

One of my issues that I blamed on Euler angles was that there are different ways to express the same rotation, even when you define the rotation order, and that was wreaking havoc when an angle jumped from 0 to 180( even when I didn't apply any torque around that axis ); I modified the algorithm, thought it means a few more basic operations, using the information from euclideanspace.com .
Quaternions are susceptible to the same order-of-concatenation limitation as Euler angles. Quaternions are just far more intuitive IMO.
Okay so, Euler angles works fine except when the object has to pass from the -180 to +180 degrees boundary( because the smallest angle between my desired direction and the current direction switches signs ).

So I took part of Eric_Brown's method, I used a vector pointing forward in local space, rotated it by the orientation Quaternion and one pointing in the desired direction that I want, but instead of using a quaternion, I got the perpendicular vector between them using a cross product, normalized it, and multiplied this by the angle between both vectors, which resulted in a 3D vector representing proper torque.

For the special cases where the vectors are parallel, I multiplied the components of the forward and desired vector, and if any result is negative, then the vectors are opposite, so it's an angle of 180 degrees. In case it was 0 degrees, I would obviously apply no torque.

In the case of 180 degrees, I apply a torque of 0.001 radians per second through the Y-axis, since there's no way to figure out the right path. The direction will get fixed in the next frame anyway, and it doesn't introduces and visual artifacts.

This topic is closed to new replies.

Advertisement