 # Anim8or Community

• May 26, 2020, 08:29:48 pm • Welcome, Guest ### News:

An update to Anim8or, v1.00b, is available with a few bug fixes. Get your copy HERE. See the "ReadMe" file for details.

Pages: 

### AuthorTopic: Conversion of jointangle to quaternion  (Read 2782 times)

#### SomariHater

• Guest ##### Conversion of jointangle to quaternion
« on: September 02, 2018, 05:58:45 pm »

I'm trying to figure out how to interpret the joint angles in the sequence section of an8 files. If someone could help me convert the joint angle into a quaternion or a rotation matrix or even XYZ Euler angles, that would be great. (It is okay to assume every keyframe has "X", "Y", and "Z" values for simplicity. I can figure out the interpolation. Also, assume there is just one bone besides the root bone. I can figure out the hierarchy.)

I am trying to reverse engineer it, but I'm getting lost (the an8 spec doesn't say how to interpret the value as far as I can tell). When I set the "Orientation (PYR)" of a bone in figure mode to 0, 45, 45, Anim8or saves a bone orientation quaternion of (0.14645 -0.35355 -0.35355 0.85355) into the figure section of the file. This is what I expect for XYZ Euler angles.

However, if the "Orientation (PYR)" is 0, 0, 0 in figure mode, and I set the "Joint Angles (XYZ)" of a bone in sequence mode to 0, 45, 45, Anim8or displays a very different rotation than figure mode. By manually rotating the bone in sequence mode, I was able to figure out that a "Joint Angle (XYZ)" of 38.5, -61.4, -24.8 produces a similar result to a "Orientation (PYR)" of 0, 45, 45. I attached some pictures to show what I mean.

So, if anyone could help me decode what "Joint Angle (XYZ)" means, that would be awesome. Thanks. Also, if you need more information let me know. Logged

#### SomariHater

• Guest ##### Re: Conversion of jointangle to quaternion
« Reply #1 on: September 02, 2018, 11:00:28 pm »

I found LibAn8 (https://sourceforge.net/p/liban8/code/HEAD/tree/). It looks like it translates a "Joint Angles (XYZ)" of 0, 45, 45 into the quaternion (0.14645 0.35355 0.35355 0.85355). That is the same as how Anim8or translates a "Orientation (PYR)" of 0, 45, 45 except that the Y and Z positions are positive instead of negative.

That means, LibAn8 claims that an "Orientation (PYR)" of 0, 45, 45 is equivalent to a "Joint Angles (XYZ)" of 0, -45, -45 even though they give different  results in Anim8or. I'm still confused.
« Last Edit: September 03, 2018, 12:12:37 am by SomariHater » Logged

#### Raxx

• Hero Member
•     • Posts: 1480
•  ##### Re: Conversion of jointangle to quaternion
« Reply #2 on: September 03, 2018, 03:35:58 am »

Have you looked at Steve's writeup here? http://www.anim8or.com/learn/technical/quaternions_and_anim8or/quaternions_and_anim8or.htm This topic has also been brought up a lot in the forums, you may find the answer to what you're looking for in the search results here. Logged

#### SomariHater

• Guest ##### Re: Conversion of jointangle to quaternion
« Reply #3 on: September 03, 2018, 10:33:08 am »

Yes. I read that, and I've read similar posts like this one: http://www.anim8or.com/smf/index.php/topic,4861.msg35328.html#msg35328. However,  it seems like the writeup doesn't answer this question, and an answer was never determined in that other post.

The angles in figure mode match the writeup and match what I expect for euler angles. For instance, if I increase the "yaw" or angle about the y axis in figure mode, when viewed from the top, the object spins clockwise (which is consistent with the "simple Euler rotations" in the writeup).

However, sequence mode isn't behaving like I expect. For instance, if I increase the angle about the y axis in sequence mode, when viewed from the top, the figure spins counter-clockwise.

In figure mode, if I apply a Y angle of 45 degrees, and a Z angle of 45 degrees, when viewed from the top, the object tilts to the bottom right.

In sequence mode, if I apply a Y angle of 45 degrees, and a Z angle of 45 degrees, when viewed from the top, the object tilts left with a twist.

I'm probably making a stupid mistake somewhere, but the angles don't seem to mean the same thing in figure and sequence mode. I think if the writeup showed how the axes moved in sequence mode and the order of the rotations, then I could understand better. Logged

#### Steve

• Hero Member
•     • Posts: 1810
•  ##### Re: Conversion of jointangle to quaternion
« Reply #4 on: September 03, 2018, 12:24:35 pm »

The convention that Anim8or uses is:

Looking down an axis in the negative direction, a positive rotation turns clockwise. Some applications do the opposite. Here is a simple axis model and a drawing: Logged

#### SomariHater

• Guest ##### Re: Conversion of jointangle to quaternion
« Reply #5 on: September 03, 2018, 05:13:12 pm »

Thanks Steve. That helps me clarify a bit. Here's what I've been able to reverse engineer (C# code):

Code: [Select]
`   struct Vector   {      public double X;      public double Y;      public double Z;   }   struct Quaternion   {      public double X;      public double Y;      public double Z;      public double W;   }   // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/   static Quaternion Multiply(Quaternion a, Quaternion b)   {      return new Quaternion      {         X = a.X * b.W + a.Y * b.Z - a.Z * b.Y + a.W * b.X,         Y = -a.X * b.Z + a.Y * b.W + a.Z * b.X + a.W * b.Y,         Z = a.X * b.Y - a.Y * b.X + a.Z * b.W + a.W * b.Z,         W = -a.X * b.X - a.Y * b.Y - a.Z * b.Z + a.W * b.W,      };   }   // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm   static Quaternion ToQuaternionFromAxisAngle(Vector axis, double angleDegrees)   {      double sin = System.Math.Sin(angleDegrees * System.Math.PI / 180 / 2);      double cos = System.Math.Cos(angleDegrees * System.Math.PI / 180 / 2);      return new Quaternion      {         X = axis.X * sin,         Y = axis.Y * sin,         Z = axis.Z * sin,         W = cos,      };   }   static Quaternion ToQuaternionFromFigureAngles(double angleDegreesX, double angleDegreesY, double angleDegreesZ)   {      // Anim8or rotates clockwise instead of counter-clockwise (confirmed by Steve)      Quaternion quatX = ToQuaternionFromAxisAngle(new Vector { X = 1, Y = 0, Z = 0 }, -angleDegreesX);      Quaternion quatY = ToQuaternionFromAxisAngle(new Vector { X = 0, Y = 1, Z = 0 }, -angleDegreesY);      Quaternion quatZ = ToQuaternionFromAxisAngle(new Vector { X = 0, Y = 0, Z = 1 }, -angleDegreesZ);      // Anim8or seems to apply -Y then -X then -Z in figure mode      return Multiply(Multiply(quatY, quatX), quatZ);   }   static Quaternion ToQuaternionFromSequenceAngles(double angleDegreesX, double angleDegreesY, double angleDegreesZ)   {      // Anim8or rotates counter-clockwise      Quaternion quatX = ToQuaternionFromAxisAngle(new Vector { X = 1, Y = 0, Z = 0 }, angleDegreesX);      Quaternion quatY = ToQuaternionFromAxisAngle(new Vector { X = 0, Y = 1, Z = 0 }, angleDegreesY);      Quaternion quatZ = ToQuaternionFromAxisAngle(new Vector { X = 0, Y = 0, Z = 1 }, angleDegreesZ);      // Anim8or seems to apply X then Z then Y in sequence mode      return Multiply(Multiply(quatX, quatZ), quatY);   }`
The above code is not optimized for clarity and simplicity. It looks like in Figure mode Anim8or actually uses -Y-X-Z Euler angles, that is a negative Y rotation is applied first then a negative X rotation then a negative Z rotation. It also looks like in Sequence mode Anim8or uses XZY Euler angles, that is a positive X rotation is applied first then a positive Z rotation then a positive Y rotation. This time I made sure all the signs are correct, and I tested X, Y, and Z angles. In my previous posts I was wrong in some of my statements since I ignored flipped signs and didn't test X rotations.

I will post corrections if I find that I made a mistake. Let me know if you think there is a problem with my sample code. Logged
Pages: