def compose_matrix(scale=None, shear=None, angles=None, translate=None,<EOL>perspective=None):
M = numpy.identity(<NUM_LIT:4>)<EOL>if perspective is not None:<EOL><INDENT>P = numpy.identity(<NUM_LIT:4>)<EOL>P[<NUM_LIT:3>, :] = perspective[:<NUM_LIT:4>]<EOL>M = numpy.dot(M, P)<EOL><DEDENT>if translate is not None:<EOL><INDENT>T = numpy.identity(<NUM_LIT:4>)<EOL>T[:<NUM_LIT:3>, <NUM_LIT:3>] = translate[:<NUM_LIT:3>]<EOL>M = numpy.dot(M, T)<EOL><DEDENT>if angles is not None:<EOL><INDENT>R = euler_matrix(angles[<NUM_LIT:0>], angles[<NUM_LIT:1>], angles[<NUM_LIT:2>], '<STR_LIT>')<EOL>M = numpy.dot(M, R)<EOL><DEDENT>if shear is not None:<EOL><INDENT>Z = numpy.identity(<NUM_LIT:4>)<EOL>Z[<NUM_LIT:1>, <NUM_LIT:2>] = shear[<NUM_LIT:2>]<EOL>Z[<NUM_LIT:0>, <NUM_LIT:2>] = shear[<NUM_LIT:1>]<EOL>Z[<NUM_LIT:0>, <NUM_LIT:1>] = shear[<NUM_LIT:0>]<EOL>M = numpy.dot(M, Z)<EOL><DEDENT>if scale is not None:<EOL><INDENT>S = numpy.identity(<NUM_LIT:4>)<EOL>S[<NUM_LIT:0>, <NUM_LIT:0>] = scale[<NUM_LIT:0>]<EOL>S[<NUM_LIT:1>, <NUM_LIT:1>] = scale[<NUM_LIT:1>]<EOL>S[<NUM_LIT:2>, <NUM_LIT:2>] = scale[<NUM_LIT:2>]<EOL>M = numpy.dot(M, S)<EOL><DEDENT>M /= M[<NUM_LIT:3>, <NUM_LIT:3>]<EOL>return M<EOL>
Return transformation matrix from sequence of transformations.

    This is the inverse of the decompose_matrix function.

    Sequence of transformations:
        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

    >>> scale = numpy.random.random(3) - 0.5
    >>> shear = numpy.random.random(3) - 0.5
    >>> angles = (numpy.random.random(3) - 0.5) * (2*math.pi)
    >>> trans = numpy.random.random(3) - 0.5
    >>> persp = numpy.random.random(4) - 0.5
    >>> M0 = compose_matrix(scale, shear, angles, trans, persp)
    >>> result = decompose_matrix(M0)
    >>> M1 = compose_matrix(*result)
    >>> is_same_transform(M0, M1)
    True