ID:1881276
 
(See the best response by Lummox JR.)
Code:
var/matrix/r = turn(matrix(), rotation)
o.transform = r
animate(o, transform = matrix(width, 0, x, 0, thickness, 0) * r, color = color, time=10)


Problem description:
I am trying to animate a simple segment into a sort of "beam" and while the final product of this animate() is pretty much perfect the animation is pretty jerky.

I don't really understand matrix() or the math behind it, I'd really appreciate it if there's a way to properly animate it.

Best response
There are many ways that matrices can be interpolated. The simplest is linear interpolation. In linear interpolation, picture the original icon as a square. The square's corners all gradually shift over to where the final matrix's transform would put them.

But now, picture rotating an icon by 90°. If linear interpolation were used for that, it would look stupid because the icon would shrink partway through. With simple rotation, you would expect the corners to simply revolve around in a circle, but here their path would be linear. So linear interpolation can't be used because rotation is a very common case.

The solution I ended up going with was to break the matrix down into skew, scale, translation, and rotation. All of these individually can be interpolated linearly, except for rotation in which only the angle goes through linear interpolation. So at each stage of interpolation:

1) Break the start and end matrices down into "SST" (skew, scale, translation) and angle.
2) Do a linear interpolation on SST, and on the angle. (Use the shortest path from angle 1 to angle 2, so for instance from 10° to 350° it treats 350° as -10°.)
3) Apply the interpolated skew and scale to an identity (default) matrix.
4) Rotate the matrix by the appropriate angle.
5) Apply translation to the matrix.

There is a bit of a problem here in that in your specific case, linear interpolation is probably what you would always want so that the endpoints of the beam would always follow a predictable pattern. But there isn't any clear way to handle that.

I'm open to adding some flags to the easing parameter that would alter how this is handled. However because those flags would not be ignored by past versions, and 508 is already underway, that'd probably have to be a 509 feature. (Or alternatively, since unknown easing types would just fall back on linear, I could make the flag available now but in older versions it'd only support linear easing.)