Interpolating Matrices

Apologies if I am missing something very obvious (likely!) but is there anything wrong with interpolating between two matrices by:

    float d = (float)(targetTime.Ticks - keyframe_start.ticks) / (float)(keyframe_end.ticks - keyframe_start.ticks);
return ((keyframe_start.Transform * (1 - d)) + (keyframe_end.Transform * d));


As in my app, when I try an use this to interpolate between two keyframes, the model begins to 'shrink' - the severity based on how far between the two keyframes the target time is; its worst when the transform split is ~50/50.

• @ChrisE, @JasonD, Thank you for your replies, and for that FAQ (i've needed something like that for a while!) I'll update my code to decompose the matrices and interpolate the components. – sebf Feb 18 '11 at 17:43
• Glad to be helpful! – ChrisE Feb 18 '11 at 19:18
• While interpolating the component vectors & re-ortho-normalizing them will keep the model from shrinking, it can still give odd interpolation results. For instance, when d is at a low value the interpolation will result in less of a change from one frame to the next than it will when d is near it's mid range. One way to get a smoother animation there is to use quaternions and interpolate them. They do not suffer that problem and there is less work in the re-normalizing stage too. – Steve H Feb 19 '11 at 0:29

Put very simply, linear interpolation of matrices is not always a good idea. If you have an animation you are trying to accomplish, and you are using matrices to handle the bones rotation, you can't just take a linear combination of them. You'll need to use slerp, extract the axis of rotation and interpolate the angle and recalculate the rotation matrix, or you'll need to just use quaternions. Translation is linear, rotation is not (except for small angles theta).

• just transform your geometry with two matrices and interpolate linearly between the final transformed vertices. – Dave O. Feb 19 '11 at 3:23
• usually, you don't even have to extract the angle from the matrix, just interpolate BEFORE you construct the transform matrix. – Gustavo Maciel Dec 18 '14 at 8:12

Interpolating the matrices like that isn't going to give a useful result, especially for anything involving a rotation. Ideally you want to decompose your animation into some other format (quaternion for rotation, for example) and then interpolate in that form before building the matrix.

Here is a graphical example of what I meant in the comment I wrote in the comment section of the OP's question. While the ticks representing the d values progress evenly from one vector to the other, the angular change (red lines) are not even. the changes near the middle of the sequence represent greater change than near the ends. so an animation of interpolated vectors will start slow, speed up near the middle, and slow down towards the end. If the angle between start and end is not great, it may not be noticeable.

The varying lengths of the interpolated vectors (red lines) are the reason your model was shrinking in places too as they will scale the model to their lengths.

If you used quaternions, the blue line would arc from vec A to vec B and each tick would cause equal angular change as well as an equal distance along the arc.

• Thank you very much for that description, its a very interesting problem/quirk, thats much clearer seen like that. In my application, what I've done is use XNAs methods to decompose the matrix to Scale, Rotation (as a quat.) and Translation components. Each type has its own Lerp method which I use to interpolate between them and reconstruct the transform for the bone. Not the most efficient way but it works well, I also don't need to normalize the matrix as a matrix (I never could get that code to work!) – sebf Feb 19 '11 at 13:32