ID:1881375
 
Did you know the matrix() proc is extremely flexible? There are only a few documented forms.

matrix()             // returns an identity matrix
matrix(a,b,c,d,e,f) // returns a matrix with these numbers
matrix(m1) // returns a copy of m1, in a new datum

But peeking inside stddef.dm unveils a whole new side to this proc. In your project, create a new file called stddef.dm and it will be filled in for you. Go on, I'll wait.

As you can see there, the matrix() proc is called in all kinds of interesting ways from within the built-in /matrix datum. All of the special operations call matrix() with a few arguments, the last of which is an opcode. If the opcode includes MATRIX_MODIFY, as most of them do in the datum, then the first matrix sent to the proc is changed by the calculation. Otherwise, a new matrix is returned.

For the first time, behold the full panoply of options!

/*
Arguments m1 and m2, when present, are matrices.
All other arguments are numbers.

When the last argument includes MATRIX_MODIFY, m1 is modified and is also
the return value. Otherwise, all input matrices are unmodified, and a new
matrix is created.
*/


// return an identity matrix (1,0,0,0,1,0)
matrix()

// return a matrix with values a through f already calculated
matrix(a,b,c,d,e,f)

// return a copy of matrix m1
matrix(m1)
matrix(m1, MATRIX_COPY)

// add two matrices
matrix(m1, m2, MATRIX_ADD) // m1 + m2
matrix(m1, m2, MATRIX_ADD | MATRIX_MODIFY) // m1 += m2

// subtract two matrices
matrix(m1, m2, MATRIX_SUBTRACT) // m1 - m2
matrix(m1, m2, MATRIX_SUBTRACT | MATRIX_MODIFY) // m1 -= m2

// multiply two matrices
matrix(m1, m2, MATRIX_MULTIPLY) // m1 * m2
matrix(m1, m2, MATRIX_MULTIPLY | MATRIX_MODIFY) // m1 *= m2
// Division m1/m2 is changed to m1 * ~m2

// multiply a matrix by a constant
matrix(m1, n, MATRIX_MULTIPLY) // m1 * n
matrix(m1, n, MATRIX_MULTIPLY | MATRIX_MODIFY) // m1 *= n
// Division m1/n is changed to m1 * (1/n)

// invert a matrix
matrix(m1, MATRIX_INVERT) // ~m1
matrix(m1, MATRIX_INVERT | MATRIX_MODIFY)

// create a scaled matrix
matrix(scale, MATRIX_SCALE)
matrix(x, y, MATRIX_SCALE)

// scale a matrix
matrix(m1, scale, MATRIX_SCALE)
matrix(m1, x, y, MATRIX_SCALE)
matrix(m1, scale, MATRIX_SCALE | MATRIX_MODIFY) // m1.Scale(scale)
matrix(m1, x, y, MATRIX_SCALE | MATRIX_MODIFY) // m1.Scale(x,y)

// create a rotation matrix (angle is clockwise)
matrix(angle, MATRIX_ROTATE)

// rotate a matrix
matrix(m1, angle, MATRIX_ROTATE) // turn(m1,angle)
matrix(m1, angle, MATRIX_ROTATE | MATRIX_MODIFY) // m1.Turn(angle)

// create a translation matrix
matrix(x, y, MATRIX_TRANSLATE)

// translate a matrix
matrix(m1, x, y, MATRIX_TRANSLATE)
matrix(m1, x, y, MATRIX_TRANSLATE | MATRIX_MODIFY) // m1.Translate(x,y)

// interpolate two matrices (n=0 is m1, n=1 is m2)
matrix(m1, m2, n, MATRIX_INTERPOLATE) // m1.Interpolate(m2,n)
matrix(m1, m2, n, MATRIX_INTERPOLATE | MATRIX_MODIFY)

The interpolation function is unusual for the datum in that unlike the other datum operations, by default it does not modify src. (Mostly because really, who'd want it to?)

Interpolation is done by the same method that animation uses: Each matrix is broken down into skew, scale, rotation angle, and translation. All of these are interpolated separately, then an identity matrix is changed to include the new skew and scale, rotation, and translation respectively. (If you want linear interpolation, it would be m1*(1-n) + m2*n.)

One fun fact about interpolation is that it can extrapolate too. n does not have to be limited to the 0 to 1 range.
I only know a little bit about matrices in relation to 3D graphics. What are some applications on BYOND?
Matrices in 3D graphics are used for transforming things in a 3D space. In BYOND, they're only 2D and are used for 2D transformations. (I would have considered 3D, but the software rendering mode can't handle it, and anyway BYOND itself is still very much 2D.)

So this for instance will spin an icon in a complete rotation every second:

animate(src, transform=matrix(108,MATRIX_ROTATE), time=3, loop=-1)
animate(transform=matrix(-108,MATRIX_ROTATE), time=4)
animate(transform=null, time=3)