Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

Axis Angle to quaternion and quaternion to Axis angle question

Greetings All (matlab / octave code)

Link to text file in case formatting gets messed up http://db.tt/nVv8Ivj

I created two functions one to convert axis angle to quaternion and another one to convert quaternion to axis angle as far as I can tell the formulas are correct the question I have is when I create a quaternion from the axis angle format example: x=.3 y=.1 z=.6 and the angle is 45 degrees I get (0.962730w 0.119633i 0.039878j 0.239266k) which is correct when I check it. But when I plug this quaternion number back into my function I get back angle is 31.384 degrees x=.44233, y=.14744 z=.88465 I was expecting to get back x=.3 y=.1 z=.6 and the angle of 45 degrees the same thing I put in

Does anyone know what I'm doing wrong? The reason I'm doing it this way is to do rotations on values in arrays and not get gimbal lock. I also plan to plot it and animate it, and the axis angle format (x,y,z angle) is easier to understand when it comes to plotting

Iv'e included the code below with a link above to the text file since the formating sometimes gets messed up.

`%Vector taken in [i j k], angle in degrees
%quaterions given in Format [w xi yj zk] or [w x y z] 
%
%Example of using function:  ccc=quat([.3 .1 .6],45)  
%Answer should be ->
%0.962730w   0.119633i   0.039878j   0.239266k

function Q= quat(vect,theta)
 Q = zeros(1,4);
 xyz_and_angle=[vect theta]    %displays inputed data and theta angle before deg to rad conversion
 %thetaconvert = (theta*pi/180)./norm(theta*pi/180) %convert deg to rad
 thetaconvert=theta*pi/180;
 px=vect(1,1);py=vect(1,2);pz=vect(1,3); 
 Q(1,1) = cos(thetaconvert/2); %w value
 Q(1,2)= px*sin(thetaconvert/2); % x value
 Q(1,3)= py*sin(thetaconvert/2); % y value
 Q(1,4)= pz*sin(thetaconvert/2); % z value

 q1w=Q(1,1);%qw value
 q1x=Q(1,2);%qx value
 q1y=Q(1,3);%qy value
 q1z=Q(1,4);%qz value

 %Normalize Quaternion due to floating point errors
      qnorm=sqrt(q1w^2+q1x^2+q1y^2+q1z^2) 
      Q=Q./qnorm %normalize Q array


%quaterions taken in Format [w xi yj zk] or [w x y z] 
    %example ccc=[0.962730   0.119633   0.039878   0.239266]
    %ccc2=quattoaxis(ccc)
    %Answer comes back as angle is 31.384 degrees x=.44233, y=.14744 z=.88465
    %not sure if the answer is right I thought it would be
    %x=.3 y=.1 z=.6 and the angle of 45 degrees the same thing I put in above

function Q= quattoaxis(quat)
 Q = zeros(1,4);
 q1w=quat(1,1);q1x=quat(1,2);q1y=quat(1,3);q1z=quat(1,4);
 %Get angle from quat

 %convert Quaternion to Axis
 Q(1,1) = 2*acos(q1w) *180/pi %w / angle, I  also included radians to degrees
 Q(1,2)= q1x/sqrt(1-q1w^2)  %x
 Q(1,3)= q1y/sqrt(1-q1w^2) %y
 Q(1,4)= q1z/sqrt(1-q1w^2)   %z

 axisangle=Q(1,1) %w / angle, I  also included radians to degrees
 axisx=Q(1,2) %x
 axisy=Q(1,3) %y
 axisz=Q(1,4)   %z



%Normalize axis angle  due to floating point errors
    qnorm=sqrt(axisx^2+axisy^2+axisz^2) 
    axisx=Q(1,2)/qnorm; %x
 axisy=Q(1,3)/qnorm; %y
 axisz=Q(1,4)/qnorm;  %z

    Q=[axisangle axisx axisy axisz]
share|improve this question
add comment

1 Answer 1

Right off the bat, a reality check shows something amiss here.

Given ANY axis U = (xi, yj, zk) and a rotational angle alpha, the w (i.e., real) value of the resulting quaternion should be cos(alpha/2). But if alpha is 45 degrees, then w = cos(pi/8.0) should be around 0.924... and not somewhere about 0.963..., as you seem to expect when 'correctly' calculating ccc=quat([.3 .1 .6], 45).

Your error is that the axis rotation quaternion given axis U and rotation angle alpha assumes that U is already normalized (has length 1.0). So your formula should (in an ideal world, without any round-off error) be:

 norm(U)*sin(alpha/2) + cos(alpha/2). 

where norm(U) is U, 'normalized' to have length 1. What you have coded up is instead

 norm(U*sin(alpha/2) + cos(alpha/2)).

As a test, try using your existing code to evaluate ccc = quat([300, 100, 600], 45). It will be much more 'off' than your example (where U is 'relatively' close to being normalized).

That should make sense: the quaternion that rotates 45 degrees around the axis (.3, .1, .6) should be exactly the same quaternion that rotates 45 degrees around the axis (300, 100, 600). In both caes, it's really the same axis: the latter is just a 'longer version' of the former.

Since we are not in an idealized world lacking round-off error, what you want to do is first, normalize the axis of rotation U; then construct the quaternion, and then normalize the quaternion:

 norm(norm(U)*sin(alpha/2) + cos(alpha/2))

BTW, while it's quite readable, I don't recognize the syntax of the language your are working in. What language is it?

share|improve this answer
    
It seems to be Matlab. –  Hauke Strasdat Nov 4 '11 at 8:44
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.