parameters: (matrix)
return_statement: return scale, shear, angles, translate, perspective
docstring: Return sequence of transformations from transformation matrix.
  
      matrix : array_like
          Non-degenerative homogeneous transformation matrix
  
      Return tuple of:
          scale : vector of 3 scaling factors
          shear : list of shear factors for x-y, x-z, y-z axes
          angles : list of Euler angles about static x, y, z axes
          translate : translation vector along x, y, z axes
          perspective : perspective partition of matrix
  
      Raise ValueError if matrix is of wrong type or degenerative.
  
      >>> T0 = translation_matrix([1, 2, 3])
      >>> scale, shear, angles, trans, persp = decompose_matrix(T0)
      >>> T1 = translation_matrix(trans)
      >>> numpy.allclose(T0, T1)
      True
      >>> S = scale_matrix(0.123)
      >>> scale, shear, angles, trans, persp = decompose_matrix(S)
      >>> scale[0]
      0.123
      >>> R0 = euler_matrix(1, 2, 3)
      >>> scale, shear, angles, trans, persp = decompose_matrix(R0)
      >>> R1 = euler_matrix(*angles)
      >>> numpy.allclose(R0, R1)
      True
docstring_summary: Return sequence of transformations from transformation matrix.
docstring_tokens: Return sequence of transformations from transformation matrix .
function: def decompose_matrix(matrix):
      """Return sequence of transformations from transformation matrix.
  
      matrix : array_like
          Non-degenerative homogeneous transformation matrix
  
      Return tuple of:
          scale : vector of 3 scaling factors
          shear : list of shear factors for x-y, x-z, y-z axes
          angles : list of Euler angles about static x, y, z axes
          translate : translation vector along x, y, z axes
          perspective : perspective partition of matrix
  
      Raise ValueError if matrix is of wrong type or degenerative.
  
      >>> T0 = translation_matrix([1, 2, 3])
      >>> scale, shear, angles, trans, persp = decompose_matrix(T0)
      >>> T1 = translation_matrix(trans)
      >>> numpy.allclose(T0, T1)
      True
      >>> S = scale_matrix(0.123)
      >>> scale, shear, angles, trans, persp = decompose_matrix(S)
      >>> scale[0]
      0.123
      >>> R0 = euler_matrix(1, 2, 3)
      >>> scale, shear, angles, trans, persp = decompose_matrix(R0)
      >>> R1 = euler_matrix(*angles)
      >>> numpy.allclose(R0, R1)
      True
  
      """
      M = numpy.array(matrix, dtype=numpy.float64, copy=True).T
      if abs(M[3, 3]) < _EPS:
          raise ValueError("M[3, 3] is zero")
      M /= M[3, 3]
      P = M.copy()
      P[:, 3] = 0.0, 0.0, 0.0, 1.0
      if not numpy.linalg.det(P):
          raise ValueError("matrix is singular")
  
      scale = numpy.zeros((3, ))
      shear = [0.0, 0.0, 0.0]
      angles = [0.0, 0.0, 0.0]
  
      if any(abs(M[:3, 3]) > _EPS):
          perspective = numpy.dot(M[:, 3], numpy.linalg.inv(P.T))
          M[:, 3] = 0.0, 0.0, 0.0, 1.0
      else:
          perspective = numpy.array([0.0, 0.0, 0.0, 1.0])
  
      translate = M[3, :3].copy()
      M[3, :3] = 0.0
  
      row = M[:3, :3].copy()
      scale[0] = vector_norm(row[0])
      row[0] /= scale[0]
      shear[0] = numpy.dot(row[0], row[1])
      row[1] -= row[0] * shear[0]
      scale[1] = vector_norm(row[1])
      row[1] /= scale[1]
      shear[0] /= scale[1]
      shear[1] = numpy.dot(row[0], row[2])
      row[2] -= row[0] * shear[1]
      shear[2] = numpy.dot(row[1], row[2])
      row[2] -= row[1] * shear[2]
      scale[2] = vector_norm(row[2])
      row[2] /= scale[2]
      shear[1:] /= scale[2]
  
      if numpy.dot(row[0], numpy.cross(row[1], row[2])) < 0:
          numpy.negative(scale, scale)
          numpy.negative(row, row)
  
      angles[1] = math.asin(-row[0, 2])
      if math.cos(angles[1]):
          angles[0] = math.atan2(row[1, 2], row[2, 2])
          angles[2] = math.atan2(row[0, 1], row[0, 0])
      else:
          #angles[0] = math.atan2(row[1, 0], row[1, 1])
          angles[0] = math.atan2(-row[2, 1], row[1, 1])
          angles[2] = 0.0
  
      return scale, shear, angles, translate, perspective
function_tokens: def decompose_matrix ( matrix ) : M = numpy . array ( matrix , dtype = numpy . float64 , copy = True ) . T if abs ( M [ 3 , 3 ] ) < _EPS : raise ValueError ( "M[3, 3] is zero" ) M /= M [ 3 , 3 ] P = M . copy ( ) P [ : , 3 ] = 0.0 , 0.0 , 0.0 , 1.0 if not numpy . linalg . det ( P ) : raise ValueError ( "matrix is singular" ) scale = numpy . zeros ( ( 3 , ) ) shear = [ 0.0 , 0.0 , 0.0 ] angles = [ 0.0 , 0.0 , 0.0 ] if any ( abs ( M [ : 3 , 3 ] ) > _EPS ) : perspective = numpy . dot ( M [ : , 3 ] , numpy . linalg . inv ( P . T ) ) M [ : , 3 ] = 0.0 , 0.0 , 0.0 , 1.0 else : perspective = numpy . array ( [ 0.0 , 0.0 , 0.0 , 1.0 ] ) translate = M [ 3 , : 3 ] . copy ( ) M [ 3 , : 3 ] = 0.0 row = M [ : 3 , : 3 ] . copy ( ) scale [ 0 ] = vector_norm ( row [ 0 ] ) row [ 0 ] /= scale [ 0 ] shear [ 0 ] = numpy . dot ( row [ 0 ] , row [ 1 ] ) row [ 1 ] -= row [ 0 ] * shear [ 0 ] scale [ 1 ] = vector_norm ( row [ 1 ] ) row [ 1 ] /= scale [ 1 ] shear [ 0 ] /= scale [ 1 ] shear [ 1 ] = numpy . dot ( row [ 0 ] , row [ 2 ] ) row [ 2 ] -= row [ 0 ] * shear [ 1 ] shear [ 2 ] = numpy . dot ( row [ 1 ] , row [ 2 ] ) row [ 2 ] -= row [ 1 ] * shear [ 2 ] scale [ 2 ] = vector_norm ( row [ 2 ] ) row [ 2 ] /= scale [ 2 ] shear [ 1 : ] /= scale [ 2 ] if numpy . dot ( row [ 0 ] , numpy . cross ( row [ 1 ] , row [ 2 ] ) ) < 0 : numpy . negative ( scale , scale ) numpy . negative ( row , row ) angles [ 1 ] = math . asin ( - row [ 0 , 2 ] ) if math . cos ( angles [ 1 ] ) : angles [ 0 ] = math . atan2 ( row [ 1 , 2 ] , row [ 2 , 2 ] ) angles [ 2 ] = math . atan2 ( row [ 0 , 1 ] , row [ 0 , 0 ] ) else : #angles[0] = math.atan2(row[1, 0], row[1, 1]) angles [ 0 ] = math . atan2 ( - row [ 2 , 1 ] , row [ 1 , 1 ] ) angles [ 2 ] = 0.0 return scale , shear , angles , translate , perspective