General Category > General Anim8or Forum

Conversion of jointangle to quaternion

<< < (2/2)

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


--- Code: ---   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);
   }
--- End code ---

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.

Navigation

[0] Message Index

[*] Previous page

Go to full version