Rotation Math Question

I accidentally stumbled upon this: When you add a identity matrix with a rotation matrix, the matrices’ sum has a rotation half that of the rotation matrix.

Is there any sort of mathematical principle(s) which gives what I’ve done as an equation?

You can (sort of) imagine matrix addition like 3 vector additions. in a typical matrix:

m00 m01 m02 m03
m10 m11 m12 m13
m20 m21 m22 m23
m30 m31 m32 m33

m00 m01 m02 is the X-vector of the local coordinate sytem,
m10 m11 m12 is the Y-vector, and so on. When you add the two vectors, you get something like this:

(1 + m00) m01 m02 m03
m10 (1+m11) m12 m13
m20 m21 (1 + m22) m23
m30 m31 m32 2

If you image the resulting vectors you can see that the local coord vectors are going to be drifting back towards (1,0,0), (0,1,0) and (0,0,1) because of the addition. However the added matrix is no longer homogeneous - it now has wierd scales. You can see this in action by creating 3 cubes , rotating the first one, and running this:


import pymel.core as pm
import pymel.core.datatypes as dt
from itertools import izip

m = pm.xform('pCube1', q=True, m=True)
n = pm.xform('pCube2', q=True, m=True)
z = [k+v for k,v in izip(m, n)]

pm.xform('pCube3', matrix = z)

You’ll see that the third cube is averaging the rotations of the other two but has acquired some odd non-uniform scaling.

So, you can do this trick… up to a point. It does NOT work for translation or scale, and the resulting matrix is no longer uniform scaled. You can remove the funky scaling with a call to matrix.homogenize().

The vector thing is sort of how I thought of trying this. I knew that adding two vectors created a vector bisecting the two, and was wondering if the same thing could happen to rotation matrices. I was only wanting to bisect rotations for another purpose, but I kept hearing euler rotations don’t interpolate well and I didn’t know how to bisect a quaternion, so matrices were my last option…

As long as you only want rotations, it should be OK (with limitations: it won’t correctly interpolate a 180 rotation, for example, or a matrix with a negative scale). You can do a weighted add to get an interpolation as well.

The ‘good’ quaternion interpolation is SLERP or ‘Spherical Linear Interpolation’. It’s slower than vector math but produces nicer rotational interpolations.

This video gives a decent visualization of the difference:

blue = matrix lerp, white = quat slerp

Heres a python implementation of quaternion slerp:

(You’d have to replace numpy.norm with your own normalize function but otherwise it’s all trig)