Hello! I discovered the wonderful world of geometric algebra a few months ago and recently started experimenting with using PGA to implement computer graphics and physics simulation. I’m a C++ programmer with a programming background but not a math background - my formal math education stops at undergrad calculus and linear algebra 101.

So far I have been able to use motors to transform a simulated object by making simple motors based on translations and rotation angles and then multiplying them. This seems to work well for now - I’m able to translate and rotate objects in a way that feels intuitive to me. Eventually I would like to be able to use motors directly rather than track the object’s position & rotation separately, but I’m not at that point yet.

The problem comes when I try to apply only half of the transformation. My understanding is that this should be equivalent to the motor’s square root - and indeed, when I calculate the square root of the simple translation and motors separately I end up translating/rotating the object by half of what the original motor does. But when I take the square root of the combined general motor, I get strange results. I apply rotation first, then translate, resulting in the object rotating about its own center. The full motor does this, but the square root of that motor mixes the translation and rotation components together such that the object does not rotate about its center - in fact, I can’t really understand what it is doing at all.

I’m using the following formula for the square root:

normalize( (1 + m)(1 + <m>[0] - (1/2)<m>[4]) )

And just to be sure, I also normalize the input motor beforehand, though my understanding is that this shouldn’t be necessary provided that I normalize the result.

At first I thought this to be a bug in my code, but then on a whim I decided to square the result motor and see what happens - and I do indeed end up with the original motor. I think that the square root is applying a bizarre screw motion that ends up being cancelled out when applied twice.

My question is: does the square root really do this? If so, and my code is correct, then how would I apply exactly half of a translation and half of a rotation at the same time?

I ended up going ahead and implementing the exp and log functions, and they behave as I would expect them to. I’m not sure why my original square root ended up producing something that squared to the original motor (maybe there’s more than one square root and it found a different one?), but in any case, I can use pow(m, 0.5) and get the behavior that I want.

Here you can see the general idea behind there being two square roots.
The exp of half of the logarithm e^{\log R \over 2} will give you only one.

As the paper linked above explains, (using overline for normalisation), renormalizing \overline{1+R} does the same thing, but you have to be sure to use the correct norm. That is one based on \tilde R R, which is not always a scalar! (But it is for <6D always a Study number, which has an easy and well defined inverse and square root).

Since the square root will show up a lot in practical GA use, I recommend implementing an efficient version of it because e^{\log{R} \over 2} is a very slow approach.

To understand where the ‘1 +’ approach comes from, consider two unit length vectors a,b. We know their geometric product ab produces twice the transformation needed to take b to a. We also know that their bisectors \overline{a + b} and \overline{a - b} are halfway the vectors a and b. So the product a\overline{(a+b)} and a\overline{(a-b)} both produce ‘halfway version’ (one the short path, the other the long path).

\sqrt{ab} = a(\overline{a \pm b})

This gives us a great formula for the square root if we know a and b. The normalisation of the sum or difference of two vectors never requires the Study approach. But of course we sometimes only know ab without knowing a or b explicitly. So to resolve that we basically just work out the brackets.

In the final rewrite we use that unit vectors square to +1 and we arrive at an expression that uses only ab and doesn’t require us to know a or b explicitly. The cost of that is that we must now renormalize the motor which is a tiny bit harder than renormalizing the sum of a and b.