Extracting the Axis a Quaternion is rotating around from the Quaternion itself Directly

7.8k Views Asked by At

Quaternion has components X, Y, Z, and W. If you created a Quaternion with input being a 3D Vector representing the axis (X,Y,Z) and a floating point number representing the amount to rotate around that axis(W). Can you extract the X,Y, and Z components used to construct the Quaternion from the Quaternion itself.

I'm looking for a solution that would allow me to extract the original axis from the Quaternion which has already been multiplied by itself several times. (So the axis internally never changes from the input axis actually) As in, the amount I want to rotate around the axis that I initially stored in the Quaternion is no longer inside but the axis remains.

I am not looking for any solution that requires converting the Quaternion itself to a different representation first, like a Rotation Matrix.

Can this be done or does the 4D nature of Quaternions not allow this?

If this helps...

When creating the Quaternion you would do...

QUATERNION( const VECTOR<Q> &axis, const Q &angle )
{       
     Q a = angle / 2;
     Q sin_a = sin( a );
     this->w = cos( a );
     this->x = axis.x * sin_a;
     this->y = axis.y * sin_a;
     this->z = axis.z * sin_a;
     this->Normalize(); 
}

 void Normalize()
 {  
     Q m = ( x *x + y * y + z * z + w * w );

      if( m < 0.991 || m > 1.001 )
      {
          m = sqrt( m );
          x = x / m;
          y = y / m;
          z = z / m;
          w = w / m;
      }
 }
2

There are 2 best solutions below

0
On

You can just read it directly. The pure quaternion part of the unit rotation quaternion is of the form $\sin(\theta/2)u$ where $u$ has unit length as a 3-vector and is the axis of rotation. Just normalize the pure quaternion part and you have it.

0
On

Every quaternion $z=a+\mathbf{i}b+\mathbf{j}c+\mathbf{k}d=a+\mathbf{v}$ can be expressed in exponential (polar) form as: $$ z = |z|\left(\cos \theta +\mathbf{n}\sin \theta \right)=|z| e^ {\mathbf{n} \theta}= e^{\ln |z| + \mathbf{n} \theta} $$ with: $$ \begin{cases} & |z|= \sqrt{a^2+b^2+c^2+d^2} \qquad|\mathbf{v}|=\sqrt{b^2+c^2+d^2} \\ & \cos \theta=\dfrac{a}{|z|} \qquad \sin \theta=\dfrac{|\mathbf{v}|}{|z|}\\ & \mathbf{n}=\dfrac{\mathbf{v}}{|z|\sin \theta}=\dfrac{\mathbf{v}}{|\mathbf v|} \end{cases} $$ If $z$ is a unitary quaternion than we have $|z|=1$ and $\mathbf n$ is the versor of the of the axis of a rotation of angle $2\theta$ represented, for a vector $\mathbf{x}$ ( that is a pure imaginary quaternion) by the product: $$ R_{\mathbf{n},2\theta}(\mathbf{x})=e^ {\mathbf{n} \theta}\mathbf{x}e^ {-\mathbf{n} \theta} $$

Since rotations around the same axis commutes, if you have a quaternion that represents $n$ rotations of angle $2\theta$ around the same axis, you can use this method to extract the axis $\mathbf{n}$.