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]
Best Answer
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:
where norm(U) is U, 'normalized' to have length 1. What you have coded up is instead
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:
BTW, while it's quite readable, I don't recognize the syntax of the language your are working in. What language is it?