COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Axis Angle to quaternion and quaternion to Axis angle question sal22

• Email
• Follow

```Sorry if this is a double post the last post never showed up

Axis Angle to quaternion and quaternion to Axis angle question sal22
comp.soft-
sys.matlab,alt.math.recreational,sci.math.research,sci.math,sci.math.num-
analysis
Greetings All

Link to text file/question 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 to the text file since the
formating sometimes gets messed up.

http://db.tt/nVv8Ivj

%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)
%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
%thetaconvert = (theta*pi/180)./norm(theta*pi/180) %convert deg to
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]

tia sal22

```
 0

See related articles to this posting

```Rick T <ratulloch@gmail.com> wrote in message <6879b37e-4c8b-4329-b0fd-01f923a93ba4@35g2000prb.googlegroups.com>...

(snip)

> 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
> 	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

The above is incorrect. You need to normalize the [px,py,pz] into a unit pointing vector prior to using it in the quaternion construction. e.g.,

px=vect(1,1);py=vect(1,2);pz=vect(1,3);
pnorm = norm(vect(1:3));
px = px / pnorm;
py = py / pnorm;
pz = pz / pnorm;
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

After getting this working, you might consider vectorizing your code and making better use of MATLAB functions. e.g., there is no need for px, py, and pz individually. Just use vect directly. and there is no need for your deg to rad conversion, just use the built-in functions cosd and sind directly. e.g.,

function Q= quat(vect,theta)
Q = [cosd(theta/2) sind(theta/2)*vect/norm(vect)];
end

>
> 	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

There is no way to recover a non-unit pointing vector from a quaternion because that information is not present in the unit quaternion. The best you can hope for is to recover a normalized version of your [0.3 0.1 0.6] vector.

> 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

Using acos to recover the angle is not the most robust method. For small angles the Q(1,1) element loses that information. e.g., try this:

>> Q = quat([1 1 1],1e-10)

Q =

1.000000000000000   0.000000000000873   0.000000000000873   0.000000000000873

>> Q(1)

ans =

1

You can see that the first element Q(1) is exactly 1. There is no angle information left in this element ... it is all contained in the Q(2:4) elements. To recover the angle from the quaternion it is best to use the atan2 function using all the elements of Q.  I will let you work on that detail yourself. (Hint: You know that the Q(1) term is cos(angle/2) ... what is norm(Q(2:4))?).

Also I will point out that your quattoaxis function has no protection against division by zero in the case that q1w = 1. You should work on fixing that also.

James Tursa
```
 0

```P.S. You should have a look at these excellent submissions on the FEX by John Fuller:

http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors

http://www.mathworks.com/matlabcentral/fileexchange/27653-euler-angle-dcm-quaternion-and-euler-vector-conversionteaching-gui

His quaternion convention is different from yours (he has the scalar part last whereas you have it first, and the sign convention of the rotation is different), but you can still effectively use them for comparison with your code for checking purposes.

James Tursa
```
 0

```On Jan 17, 1:43=A0pm, "James Tursa"
<aclassyguy_with_a_k_not_...@hotmail.com> wrote:
> P.S. You should have a look at these excellent submissions on the FEX by =
John Fuller:
>
> http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to...
>
> http://www.mathworks.com/matlabcentral/fileexchange/27653-euler-angle...
>
> His quaternion convention is different from yours (he has the scalar part=
last whereas you have it first, and the sign convention of the rotation is=
different), but you can still effectively use them for comparison with you=
r code for checking purposes.
>
> James Tursa

Thanks!!!! I'll make the recommended changes and have a look at the

:-)
```
 0