# Averaging Matrices

This topic is 4614 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

How would I go about taking two matrices and finding the average between the two? And if you can answer that, is it possible to have different matrices with different weights combined together? I'm doing this for animation since I haven't found a way to have more than 2 track working together in DirectX. I can just go through and transform the vertices and then weight the transformed ones, but I'm looking for a way that I can do it before it hits the shader.

##### Share on other sites
Assuming your matrices are relatively sane (just rotations and translations) and you want a relatively smooth averaging, one method would be to extract the translation components and get a weighted average as normal. Then transform the rotation information of each matrix into a pair of quaternions. The quaternions can then be interpolated between with slerp. Then combine the new quaternion and the weightee average of the translations into a new matrix.

##### Share on other sites
Would taking Matrix1 and multiplying it by it's weight in a scale matrix and adding it to Matrix2 and multiplying that by it's weight in a scale matrix work?

Scale Matrix
[Weight, 0, 0, 0]
[0, Weight, 0, 0]
[0, 0, Weight, 0]
[0, 0, 0, Weight]

##### Share on other sites
Not really. Simple linear combinations of general transformation matrices won't preserve the proper invariants. For lack of a better term, such an approach will make things look really funky.

##### Share on other sites
No, as SiCrane said you cannot in general add matrices to "add" their effect. For example, if you have a matrix A that rotates your object X degrees around some axis then the matrix (A+A) does not rotate your object (X+X) degrees around the same axis.

The best (and most common) way of interpolating 4x4 matrices for animation is to use linear interpolation of the translation (position) and SLERP for the orientations (using quaternions).

- Kasper Fauerby

##### Share on other sites
As they say. You don't "add" rotations, you multiply them, that's why averaging via adding doesn't work as you expect.
It's still a legitimate operation, just it doesn't do what you want it to do.
Let's you draw some mesh M with matrix C=A+t*(B-A)=(1-t)*A+t*B. It is the weighted average.
Result will be the same as if you would linearly interpolate vertices between 2 meshes, mesn M1 that is result of transforming original mesh with A and mesh M2 that is result of transforming original mesh with B
It is clear enough that it will not do what you want it to do - mesh will not correctly rotate between 2 rotations. For example, if it's bottle that is rotated[between M1 and M2] 180 degrees around axis, you'll get bottle collapsing into line, and then expanding back rotated. Sort of weird. [grin]

In general, interpolation of rotation between matrix1 and matrix2 is doable as
f(a)=exp(log(matrix1)+a*(log(matrix2)-log(matrix1)))=exp((1-a)*log(matrix1)+a*log(matrix2)))
and average as
exp(0.5*(log(matrix1)+log(matrix2)))
but it requirs matrix logarithm and exponentiation, (which in core is rather similar to this quaternion thingy they talk about, but is quite a lot more complex and weird.) So better just use quaternions.

For performing weighted change between one quaternion and other quaternion (probably what you really meant by averaging), use SLERP.

[Edited by - Dmytry on July 4, 2005 4:26:08 AM]

##### Share on other sites
I'm facing almost the same problem as Bosh: I like to combine some quaternions (let's say 4 or 5) to perform animation blending.
If I like to combine just 2 I use slerp or lerp, but what should I do to combine 4 or 5 quaternion, each of them having some weight attached?

##### Share on other sites
Quote:
 I'm facing almost the same problem as Bosh: I like to combine some quaternions (let's say 4 or 5) to perform animation blending.If I like to combine just 2 I use slerp or lerp, but what should I do to combine 4 or 5 quaternion, each of them having some weight attached?
You might look into quaternion squad().

##### Share on other sites
I have found a way to get out all of the rotations, scales, and translations. Except for the scale of x. It comes out way off every time and I don't know how to get it out. All of the numbers come out a bit off, you know, like .0001 off. So it may be float inaccurcy. If you have any suggestions please let me know. Oh, and I know the the way to find the scale of z is a little bit slow, any suggestions on that would be great as well.

Matrix mat = Matrix.Scaling(2, 4, 2) * Matrix.RotationYawPitchRoll(0, 0.7853981634f, 1.570796327f) * Matrix.Translation(10, 2, 7);			Vector3 angle = new Vector3();Vector3 scale = new Vector3();Vector3 translate = new Vector3();translate.X = mat.M41;translate.Y = mat.M42;translate.Z = mat.M43;angle.X = (float)(Math.Atan(mat.M23/mat.M33));angle.Y = (float)(Math.Atan(-mat.M13/(mat.M23/Math.Sin(angle.X))));scale.Z = -mat.M13/(float)(Math.Sin(angle.Y));angle.Z = (float)(Math.Acos(mat.M22*(Math.Cos(angle.Y)/mat.M12)-(Math.Sin(angle.X)*Math.Sin(angle.Y))/Math.Cos(angle.X)));scale.X = mat.M11/(float)(Math.Cos(angle.Y) * Math.Cos(angle.Z);scale.Y = mat.M12/(float)(Math.Cos(angle.Y) * Math.Sin(angle.Z));

• 13
• 11
• 22
• 11
• 15