Thanks Steve. That helps me clarify a bit. Here's what I've been able to reverse engineer (C# 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);

}

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.