parameters: (matrix)
return_statement: return angle, direction, point
docstring: Return rotation angle and axis from rotation matrix.
      >>> angle = (random.random() - 0.5) * (2*math.pi)
      >>> direc = numpy.random.random(3) - 0.5
      >>> point = numpy.random.random(3) - 0.5
      >>> R0 = rotation_matrix(angle, direc, point)
      >>> angle, direc, point = rotation_from_matrix(R0)
      >>> R1 = rotation_matrix(angle, direc, point)
      >>> is_same_transform(R0, R1)
      True
docstring_summary: Return rotation angle and axis from rotation matrix.
      >>> angle = (random.random() - 0.5) * (2*math.pi)
      >>> direc = numpy.random.random(3) - 0.5
      >>> point = numpy.random.random(3) - 0.5
      >>> R0 = rotation_matrix(angle, direc, point)
      >>> angle, direc, point = rotation_from_matrix(R0)
      >>> R1 = rotation_matrix(angle, direc, point)
      >>> is_same_transform(R0, R1)
      True
docstring_tokens: Return rotation angle and axis from rotation matrix . >>> angle = ( random . random () - 0 . 5 ) * ( 2 * math . pi ) >>> direc = numpy . random . random ( 3 ) - 0 . 5 >>> point = numpy . random . random ( 3 ) - 0 . 5 >>> R0 = rotation_matrix ( angle direc point ) >>> angle direc point = rotation_from_matrix ( R0 ) >>> R1 = rotation_matrix ( angle direc point ) >>> is_same_transform ( R0 R1 ) True
function: def rotation_from_matrix(matrix):
      """Return rotation angle and axis from rotation matrix.
      >>> angle = (random.random() - 0.5) * (2*math.pi)
      >>> direc = numpy.random.random(3) - 0.5
      >>> point = numpy.random.random(3) - 0.5
      >>> R0 = rotation_matrix(angle, direc, point)
      >>> angle, direc, point = rotation_from_matrix(R0)
      >>> R1 = rotation_matrix(angle, direc, point)
      >>> is_same_transform(R0, R1)
      True
      """
      R = numpy.array(matrix, dtype=numpy.float64, copy=False)
      R33 = R[:3, :3]
      # direction: unit eigenvector of R33 corresponding to eigenvalue of 1
      l, W = numpy.linalg.eig(R33.T)
      i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0]
      if not len(i):
          raise ValueError("no unit eigenvector corresponding to eigenvalue 1")
      direction = numpy.real(W[:, i[-1]]).squeeze()
      # point: unit eigenvector of R33 corresponding to eigenvalue of 1
      l, Q = numpy.linalg.eig(R)
      i = numpy.where(abs(numpy.real(l) - 1.0) < 1e-8)[0]
      if not len(i):
          raise ValueError("no unit eigenvector corresponding to eigenvalue 1")
      point = numpy.real(Q[:, i[-1]]).squeeze()
      point /= point[3]
      # rotation angle depending on direction
      cosa = (numpy.trace(R33) - 1.0) / 2.0
      if abs(direction[2]) > 1e-8:
          sina = (R[1, 0] + (cosa-1.0)*direction[0]*direction[1]) / direction[2]
      elif abs(direction[1]) > 1e-8:
          sina = (R[0, 2] + (cosa-1.0)*direction[0]*direction[2]) / direction[1]
      else:
          sina = (R[2, 1] + (cosa-1.0)*direction[1]*direction[2]) / direction[0]
      angle = math.atan2(sina, cosa)
      return angle, direction, point
function_tokens: def rotation_from_matrix ( matrix ) : R = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) R33 = R [ : 3 , : 3 ] # direction: unit eigenvector of R33 corresponding to eigenvalue of 1 l , W = numpy . linalg . eig ( R33 . T ) i = numpy . where ( abs ( numpy . real ( l ) - 1.0 ) < 1e-8 ) [ 0 ] if not len ( i ) : raise ValueError ( "no unit eigenvector corresponding to eigenvalue 1" ) direction = numpy . real ( W [ : , i [ - 1 ] ] ) . squeeze ( ) # point: unit eigenvector of R33 corresponding to eigenvalue of 1 l , Q = numpy . linalg . eig ( R ) i = numpy . where ( abs ( numpy . real ( l ) - 1.0 ) < 1e-8 ) [ 0 ] if not len ( i ) : raise ValueError ( "no unit eigenvector corresponding to eigenvalue 1" ) point = numpy . real ( Q [ : , i [ - 1 ] ] ) . squeeze ( ) point /= point [ 3 ] # rotation angle depending on direction cosa = ( numpy . trace ( R33 ) - 1.0 ) / 2.0 if abs ( direction [ 2 ] ) > 1e-8 : sina = ( R [ 1 , 0 ] + ( cosa - 1.0 ) * direction [ 0 ] * direction [ 1 ] ) / direction [ 2 ] elif abs ( direction [ 1 ] ) > 1e-8 : sina = ( R [ 0 , 2 ] + ( cosa - 1.0 ) * direction [ 0 ] * direction [ 2 ] ) / direction [ 1 ] else : sina = ( R [ 2 , 1 ] + ( cosa - 1.0 ) * direction [ 1 ] * direction [ 2 ] ) / direction [ 0 ] angle = math . atan2 ( sina , cosa ) return angle , direction , point