PDA

View Full Version : Quaternion Rotation and MEL


MichaelDarkAngel
09-07-2006, 03:34 AM
In an ascii model file I am currently writing a set of import/export scripts for there is the following line.

orientation 0.0 0.0 -1.0 -1.5708

This corresponds to a rotation of the object in question as follows

X: 0.0 Y: 0.0 Z: 90.0

Easy enough to figure out -1.5708 radians is -90 degress. The -1.0 I assume to mean rotate on the Z-axis the inverse of the angle of rotation.

Well that all seemed simple enough until I ran across this later in the same model file

orientation 0.51909 0.440471 -0.732482 -4.41171

Which corresponds to a rotation of the object it is attached to as follows

X: -169.0 Y: 66.0 Z: -82.5

I've read several articles on quaternion rotation and quaternions in general, looked at a few scripts and programs that actually perform quaternion rotation and I'm no closer to figuring out how the four values in my orientation line come together to spit out the x,y,z rotation values.

I know MQuaternion is part of the API. How would I use MEL to pass the orientation values to the MQuaternion class so that I can end up with the rotation values to plug into the rotateAxis attribute?

Thanks for any help,

MDA

jadamburke
09-07-2006, 04:42 AM
a quaternion is defined by a 3d vector (XYZ position) and a scalar value (rotation in radians about that vector). This is the four values you are seeing.

(x, y, z, r)

Your close but the first three values define a point in space not a rotation about euler axes. an imaginary line between this point and the origin is called a 3d vector. This is the axis about which the 4th value is to rotate.

there's probably a better way to do this in maya but you could use a few math mel commands to turn your quaternions into euler.

you can use the angleBetween function to get the euler rotation between two points. but we don't have two points, so we could make one up, and then rotate it by the quaternion to get the second point using the rot function. something like this:

vector $firstPoint = <<1.0,0,0>>;
vector $quatVec = <<0.51909,0.440471,-0.732482>>;
float $quatRotation = -4.41171;
vector $secondPoint = rot($firstPoint,$quatVec,$quatRotation);
float $eulerRotation[] = `angleBetween -euler -v1 ($firstPoint.x) ($firstPoint.y) ($firstPoint.z) -v2 ($secondPoint.x) ($secondPoint.y) ($secondPoint.z)`;
print $eulerRotation;

MichaelDarkAngel
09-07-2006, 05:45 AM
a quaternion is defined by a 3d vector (XYZ position) and a scalar value (rotation in radians about that vector). This is the four values you are seeing.

(x, y, z, r)

That much of what I read on the subject I understood. It's your next statement that has helped to put it into a better perspective for me.

Your close but the first three values define a point in space not a rotation about euler axes. an imaginary line between this point and the origin is called a 3d vector. This is the axis about which the 4th value is to rotate.

there's probably a better way to do this in maya but you could use a few math mel commands to turn your quaternions into euler.

you can use the angleBetween function to get the euler rotation between two points. but we don't have two points, so we could make one up, and then rotate it by the quaternion to get the second point using the rot function. something like this:

And I've looked at angleBetween and rot but because I didn't understand what orientation was telling me in the first place I couldn't figure out how to make it work. I'll try what you suggested and see if that does the trick.

Thanks,

MDA

MichaelDarkAngel
09-07-2006, 07:01 AM
Ran it through a few tests. Works pretty good for the first situation.

The second situation however does not calculate properly and I can't figure out why.

It gets the Y and Z rotation pretty darn close, but not the X rotation.

In my example from my first post, the x,y,z should be

X: -169.0 Y: 66.0 Z: -82.5

Your script provides the following

X: -59.324254 Y: 65.999911 Z: -82.5

It has happened in two other tests also. This one is off by almost 110 degrees, the second was close to 104 degrees and the third was almost 97 degrees. Tried a few different things to correct this but I'm not sure what could be causing it.

Three different vectors with three different angles of rotation, all three provided the proper y and z-axis rotations but not the correct x-axis rotation.

Not sure where to go now.

Thanks again,

MDA

jadamburke
09-11-2006, 06:44 PM
yeah, i made a wrong assumption and the results made me think it was correct. The vector that you choose to rotate by the quaternion (using the rot() function) has to lie on the plane perpendicular to the quaternion axis, otherwise the result will be off. \

So there is an extra step involved. To find a vector perpendicular to the quaternion vector we can use the cross product function cross() to find it. cross() requires two input vectors (which define a plane) and it returns a vector perpendicular. So the first vector is the quaternion axis vector. The second point we can make up. The result will lie on the plane perpendicular to the quaternion axis vector. We then rotate this result by the quaternion to get the second point and then use the angleBetween() to measure the euler angle between.


vector $firstPoint = cross(<<0.51909,0.440471,-0.732482>>,<<.5,.5,.5>>);
vector $quatVec = <<0.51909,0.440471,-0.732482>>;
float $quatRotation = -4.41171;
vector $secondPoint = rot($firstPoint,$quatVec,$quatRotation);
float $eulerRotation[] = `angleBetween -euler -v1 ($firstPoint.x) ($firstPoint.y) ($firstPoint.z) -v2 ($secondPoint.x) ($secondPoint.y) ($secondPoint.z)`;
print $eulerRotation;


This will orient the object exactly as the result values you have been giving but the actual euler values will be different. The angleBetween function only returns euler angles in the XYZ rotation order and like a constraint, it doesn't exceed 360 degree rotations so I don't know how usefull all this will actually be.

MichaelDarkAngel
09-11-2006, 10:43 PM
Thanks so much :bounce:

I never expected anyone else to give it a shot, much less the same person, and had just about given up on having them import at the proper angel.

I really appreciate you coming back for round two. It works beautifully.

Thanks again,

CGTalk Moderation
09-11-2006, 10:43 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.