% MATRIX2ANGLEAXIS - Homogeneous matrix to angle-axis description % % Usage: t = matrix2angleaxis(T) % % Argument: T - 4x4 Homogeneous transformation matrix % Returns: t - 3-vector giving rotation axis with magnitude equal to the % rotation angle in radians. % % See also: ANGLEAXIS2MATRIX, ANGLEAXIS2MATRIX2, ANGLEAXISROTATE, NEWANGLEAXIS, % NORMALISEANGLEAXIS % Copyright (c) 2008 Peter Kovesi % School of Computer Science & Software Engineering % The University of Western Australia % pk at csse uwa edu au % http://www.csse.uwa.edu.au/ % % Permission is hereby granted, free of charge, to any person obtaining a copy % of this software and associated documentation files (the "Software"), to deal % in the Software without restriction, subject to the following conditions: % % The above copyright notice and this permission notice shall be included in % all copies or substantial portions of the Software. % % The Software is provided "as is", without warranty of any kind. % 2008 - Original version % May 2013 - Code to trap small rotations added function t = matrix2angleaxis(T) % This code follows the implementation suggested by Hartley and Zisserman R = T(1:3, 1:3); % Extract rotation part of T % Trap case where rotation is very small. (See angleaxis2matrix.m) Reye = R-eye(3); if norm(Reye) < 1e-8 t = [T(3,2); T(1,3); T(2,1)]; return end % Otherwise find rotation axis as the eigenvector having unit eigenvalue % Solve (R-I)v = 0; [v,d] = eig(Reye); % The following code assumes the eigenvalues returned are not necessarily % sorted by size. This may be overcautious on my part. d = diag(abs(d)); % Extract eigenvalues [s, ind] = sort(d); % Find index of smallest one if d(ind(1)) > 0.001 % Hopefully it is close to 0 warning('Rotation matrix is dubious'); end axis = v(:,ind(1)); % Extract appropriate eigenvector if abs(norm(axis) - 1) > .0001 % Debug warning('non unit rotation axis'); end % Now determine the rotation angle twocostheta = trace(R)-1; twosinthetav = [R(3,2)-R(2,3), R(1,3)-R(3,1), R(2,1)-R(1,2)]'; twosintheta = axis'*twosinthetav; theta = atan2(twosintheta, twocostheta); t = theta*axis;