invert QTransform using adjoint() and determinant()

This commit is contained in:
KIU Shueng Chuan 2021-01-08 15:27:42 +08:00
parent 386dcf8180
commit fd85076bb6

View File

@ -2325,25 +2325,31 @@ def isosurface(data, level):
return vertexes, faces return vertexes, faces
def _pinv_fallback(tr):
arr = np.array([tr.m11(), tr.m12(), tr.m13(),
tr.m21(), tr.m22(), tr.m23(),
tr.m31(), tr.m32(), tr.m33()])
arr.shape = (3, 3)
pinv = np.linalg.pinv(arr)
return QtGui.QTransform(*pinv.ravel().tolist())
def invertQTransform(tr): def invertQTransform(tr):
"""Return a QTransform that is the inverse of *tr*. """Return a QTransform that is the inverse of *tr*.
Rasises an exception if tr is not invertible. A pseudo-inverse is returned if tr is not invertible.
Note that this function is preferred over QTransform.inverted() due to Note that this function is preferred over QTransform.inverted() due to
bugs in that method. (specifically, Qt has floating-point precision issues bugs in that method. (specifically, Qt has floating-point precision issues
when determining whether a matrix is invertible) when determining whether a matrix is invertible)
""" """
try: try:
import numpy.linalg det = tr.determinant()
arr = np.array([[tr.m11(), tr.m12(), tr.m13()], [tr.m21(), tr.m22(), tr.m23()], [tr.m31(), tr.m32(), tr.m33()]]) detr = 1.0 / det # let singular matrices raise ZeroDivisionError
inv = numpy.linalg.inv(arr) inv = tr.adjoint()
return QtGui.QTransform(inv[0,0], inv[0,1], inv[0,2], inv[1,0], inv[1,1], inv[1,2], inv[2,0], inv[2,1]) inv *= detr
except ImportError: return inv
inv = tr.inverted() except ZeroDivisionError:
if inv[1] is False: return _pinv_fallback(tr)
raise Exception("Transform is not invertible.")
return inv[0]
def pseudoScatter(data, spacing=None, shuffle=True, bidir=False, method='exact'): def pseudoScatter(data, spacing=None, shuffle=True, bidir=False, method='exact'):