Skip to content

Commit

Permalink
ENH: allow threshold for mat2axangle precision
Browse files Browse the repository at this point in the history
Allow user to set precision for mat2axangle check for rotation matrix
precision.

Make default threshold more liberal.
  • Loading branch information
matthew-brett committed Aug 21, 2015
1 parent cb6fd51 commit c14ef30
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
8 changes: 6 additions & 2 deletions transforms3d/axangles.py
Expand Up @@ -112,12 +112,16 @@ def axangle2aff(axis, angle, point=None):
return M


def mat2axangle(mat):
def mat2axangle(mat, unit_thresh=1e-5):
"""Return axis, angle and point from (3, 3) matrix `mat`
Parameters
----------
mat : array-like shape (3, 3)
Rotation matrix
unit_thresh : float, optional
Tolerable difference from 1 when testing for unit eigenvalues to
confirm `mat` is a rotation matrix.
Returns
-------
Expand All @@ -143,7 +147,7 @@ def mat2axangle(mat):
M = np.asarray(mat, dtype=np.float)
# direction: unit eigenvector of R33 corresponding to eigenvalue of 1
L, W = np.linalg.eig(M.T)
i = np.where(abs(np.real(L) - 1.0) < 1e-8)[0]
i = np.where(np.abs(L - 1.0) < unit_thresh)[0]
if not len(i):
raise ValueError("no unit eigenvector corresponding to eigenvalue 1")
direction = np.real(W[:, i[-1]]).squeeze()
Expand Down
20 changes: 19 additions & 1 deletion transforms3d/tests/test_axangles.py
Expand Up @@ -9,7 +9,7 @@

from .samples import euler_tuples

from numpy.testing import assert_array_almost_equal
from numpy.testing import assert_array_almost_equal, assert_almost_equal

from nose.tools import assert_raises

Expand Down Expand Up @@ -42,6 +42,24 @@ def test_aa_points():
assert_array_almost_equal(RP, RP_back)


def test_mat2axangle_thresh():
# Test precision threshold to mat2axangle
axis, angle = mat2axangle(np.eye(3))
assert_almost_equal(axis, [0, 0, 1])
assert_almost_equal(angle, 0)
offset = 1e-6
mat = np.diag([1 + offset] * 3)
axis, angle = mat2axangle(mat)
assert_almost_equal(axis, [0, 0, 1])
assert_almost_equal(angle, 0)
offset = 1e-4
mat = np.diag([1 + offset] * 3)
assert_raises(ValueError, mat2axangle, mat)
axis, angle = mat2axangle(mat, 1e-4)
assert_almost_equal(axis, [0, 0, 1])
assert_almost_equal(angle, 0)


def test_angle_axis_imps():
for x, y, z in euler_tuples:
M = ttb.euler2mat(z, y, x)
Expand Down

0 comments on commit c14ef30

Please sign in to comment.