parameters: (matrix, pseudo=False)
docstring: Return projection plane and perspective point from projection matrix.
  
      Return values are same as arguments for projection_matrix function:
      point, normal, direction, perspective, and pseudo.
  
      >>> point = numpy.random.random(3) - 0.5
      >>> normal = numpy.random.random(3) - 0.5
      >>> direct = numpy.random.random(3) - 0.5
      >>> persp = numpy.random.random(3) - 0.5
      >>> P0 = projection_matrix(point, normal)
      >>> result = projection_from_matrix(P0)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
      >>> P0 = projection_matrix(point, normal, direct)
      >>> result = projection_from_matrix(P0)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
      >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=False)
      >>> result = projection_from_matrix(P0, pseudo=False)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
      >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=True)
      >>> result = projection_from_matrix(P0, pseudo=True)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
docstring_summary: Return projection plane and perspective point from projection matrix.
docstring_tokens: Return projection plane and perspective point from projection matrix .
function: def projection_from_matrix(matrix, pseudo=False):
      """Return projection plane and perspective point from projection matrix.
  
      Return values are same as arguments for projection_matrix function:
      point, normal, direction, perspective, and pseudo.
  
      >>> point = numpy.random.random(3) - 0.5
      >>> normal = numpy.random.random(3) - 0.5
      >>> direct = numpy.random.random(3) - 0.5
      >>> persp = numpy.random.random(3) - 0.5
      >>> P0 = projection_matrix(point, normal)
      >>> result = projection_from_matrix(P0)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
      >>> P0 = projection_matrix(point, normal, direct)
      >>> result = projection_from_matrix(P0)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
      >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=False)
      >>> result = projection_from_matrix(P0, pseudo=False)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
      >>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=True)
      >>> result = projection_from_matrix(P0, pseudo=True)
      >>> P1 = projection_matrix(*result)
      >>> is_same_transform(P0, P1)
      True
  
      """
      M = numpy.array(matrix, dtype=numpy.float64, copy=False)
      M33 = M[:3, :3]
      w, V = numpy.linalg.eig(M)
      i = numpy.where(abs(numpy.real(w) - 1.0) < 1e-8)[0]
      if not pseudo and len(i):
          # point: any eigenvector corresponding to eigenvalue 1
          point = numpy.real(V[:, i[-1]]).squeeze()
          point /= point[3]
          # direction: unit eigenvector corresponding to eigenvalue 0
          w, V = numpy.linalg.eig(M33)
          i = numpy.where(abs(numpy.real(w)) < 1e-8)[0]
          if not len(i):
              raise ValueError("no eigenvector corresponding to eigenvalue 0")
          direction = numpy.real(V[:, i[0]]).squeeze()
          direction /= vector_norm(direction)
          # normal: unit eigenvector of M33.T corresponding to eigenvalue 0
          w, V = numpy.linalg.eig(M33.T)
          i = numpy.where(abs(numpy.real(w)) < 1e-8)[0]
          if len(i):
              # parallel projection
              normal = numpy.real(V[:, i[0]]).squeeze()
              normal /= vector_norm(normal)
              return point, normal, direction, None, False
          else:
              # orthogonal projection, where normal equals direction vector
              return point, direction, None, None, False
      else:
          # perspective projection
          i = numpy.where(abs(numpy.real(w)) > 1e-8)[0]
          if not len(i):
              raise ValueError(
                  "no eigenvector not corresponding to eigenvalue 0")
          point = numpy.real(V[:, i[-1]]).squeeze()
          point /= point[3]
          normal = - M[3, :3]
          perspective = M[:3, 3] / numpy.dot(point[:3], normal)
          if pseudo:
              perspective -= normal
          return point, normal, None, perspective, pseudo
function_tokens: def projection_from_matrix ( matrix , pseudo = False ) : M = numpy . array ( matrix , dtype = numpy . float64 , copy = False ) M33 = M [ : 3 , : 3 ] w , V = numpy . linalg . eig ( M ) i = numpy . where ( abs ( numpy . real ( w ) - 1.0 ) < 1e-8 ) [ 0 ] if not pseudo and len ( i ) : # point: any eigenvector corresponding to eigenvalue 1 point = numpy . real ( V [ : , i [ - 1 ] ] ) . squeeze ( ) point /= point [ 3 ] # direction: unit eigenvector corresponding to eigenvalue 0 w , V = numpy . linalg . eig ( M33 ) i = numpy . where ( abs ( numpy . real ( w ) ) < 1e-8 ) [ 0 ] if not len ( i ) : raise ValueError ( "no eigenvector corresponding to eigenvalue 0" ) direction = numpy . real ( V [ : , i [ 0 ] ] ) . squeeze ( ) direction /= vector_norm ( direction ) # normal: unit eigenvector of M33.T corresponding to eigenvalue 0 w , V = numpy . linalg . eig ( M33 . T ) i = numpy . where ( abs ( numpy . real ( w ) ) < 1e-8 ) [ 0 ] if len ( i ) : # parallel projection normal = numpy . real ( V [ : , i [ 0 ] ] ) . squeeze ( ) normal /= vector_norm ( normal ) return point , normal , direction , None , False else : # orthogonal projection, where normal equals direction vector return point , direction , None , None , False else : # perspective projection i = numpy . where ( abs ( numpy . real ( w ) ) > 1e-8 ) [ 0 ] if not len ( i ) : raise ValueError ( "no eigenvector not corresponding to eigenvalue 0" ) point = numpy . real ( V [ : , i [ - 1 ] ] ) . squeeze ( ) point /= point [ 3 ] normal = - M [ 3 , : 3 ] perspective = M [ : 3 , 3 ] / numpy . dot ( point [ : 3 ] , normal ) if pseudo : perspective -= normal return point , normal , None , perspective , pseudo