def projection_from_matrix(matrix, pseudo=False):
M = numpy.array(matrix, dtype=numpy.float64, copy=False)<EOL>M33 = M[:<NUM_LIT:3>, :<NUM_LIT:3>]<EOL>w, V = numpy.linalg.eig(M)<EOL>i = numpy.where(abs(numpy.real(w) - <NUM_LIT:1.0>) < <NUM_LIT>)[<NUM_LIT:0>]<EOL>if not pseudo and len(i):<EOL><INDENT>point = numpy.real(V[:, i[-<NUM_LIT:1>]]).squeeze()<EOL>point /= point[<NUM_LIT:3>]<EOL>w, V = numpy.linalg.eig(M33)<EOL>i = numpy.where(abs(numpy.real(w)) < <NUM_LIT>)[<NUM_LIT:0>]<EOL>if not len(i):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>direction = numpy.real(V[:, i[<NUM_LIT:0>]]).squeeze()<EOL>direction /= vector_norm(direction)<EOL>w, V = numpy.linalg.eig(M33.T)<EOL>i = numpy.where(abs(numpy.real(w)) < <NUM_LIT>)[<NUM_LIT:0>]<EOL>if len(i):<EOL><INDENT>normal = numpy.real(V[:, i[<NUM_LIT:0>]]).squeeze()<EOL>normal /= vector_norm(normal)<EOL>return point, normal, direction, None, False<EOL><DEDENT>else:<EOL><INDENT>return point, direction, None, None, False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>i = numpy.where(abs(numpy.real(w)) > <NUM_LIT>)[<NUM_LIT:0>]<EOL>if not len(i):<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>point = numpy.real(V[:, i[-<NUM_LIT:1>]]).squeeze()<EOL>point /= point[<NUM_LIT:3>]<EOL>normal = - M[<NUM_LIT:3>, :<NUM_LIT:3>]<EOL>perspective = M[:<NUM_LIT:3>, <NUM_LIT:3>] / numpy.dot(point[:<NUM_LIT:3>], normal)<EOL>if pseudo:<EOL><INDENT>perspective -= normal<EOL><DEDENT>return point, normal, None, perspective, pseudo<EOL><DEDENT>
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