Algebra of quaternions

Back to Geometric algebra in sympy

In this section we study quaternions using , the even sub-algebra of , which is isomorphic to quaternions.

The quaternions live in the 4-dimensional sub-algebra spanned by the basis-blades , , , and ; the even sub-algebra of . We think of a familiar 3-dimensional vector-space being embedded into the subspace spanned by , , and .

The following is a reoccurring theme in geometric algebra: by increasing the dimension of the space, and using the extra dimensions wisely, you may gain new tools for handling the original space. In this case, the extra fourth dimension makes it easy to apply and compose rotations and reflections of the 3-dimensional space. One of the best motivations for using quaternions is that they offer a natural way to smoothly interpolate between two rotated versions of an object. The same thing is difficult to achieve with rotation matrices.

The geometric algebra is also algebra-isomorphic to quaternions. By the choice we can later show how the quaternions are just a half of the story — the story being . In addition, here the operations of geometric algebra and quaternions coincide.

# Description: Tutorial code for Cl(3, 0)+

if True:

Initialization

# Import all symbols from the `sympy` and `sympy.galgebra` packages.
from sympy.galgebra import *
from sympy import *

Defining a basis

# Theorem:
# Cl(3, 0)+ is algebra-isomorphic to quaternions

# Set up Cl_{3, 0}.
e1, e2, e3 = MV.setup('e1 e2 e3', metric='[1, 1, 1]')
i = e1 * e2
j = e1 * e3
k = e2 * e3

print
print 'Algebra of quaternions Cl(3, 0)+'
print '--------------------------------'
print

Quaternion multiplication

# Set up an arbitrary quaternion.
a0, a1, a2, a3 = symbols('a0 a1 a2 a3')
a = a0 + a1 * i + a2 * j + a3 * k

# Set up another arbitrary quaternion.
b0, b1, b2, b3 = symbols('b0 b1 b2 b3')
b = b0 + b1 * i + b2 * j + b3 * k

# What is the product of `a` and `b`?
c = a * b

# Print one component per line.
print 'Quaternion multiplication:'
print c.Fmt(3)
print

# I don't know how to make the package to print 
# `i`, `j`, and `k`.

Quaternion rotation

# Define a rotation axis.
v = 9 * k

# Define a rotation angle.
alpha = pi / 2

# Construct a quaternion representing
# rotation around `v` with angle `alpha`.
q = ((alpha / 2) * (v / v.norm())).exp()

# This is the same as
# q = cos(alpha / 2) + sin(alpha / 2) * (v / v.norm())

# Define a vector to rotate.
v = 3 * i + 6 * j - 7 * k

# Rotate the vector.
rv = q * v * inv(q)

# Output the rotated vector.
print 'Rotate', v, 'around k', '=', rv

Quaternion interpolation

# Define two rotation axes.
v1 = 5 * i - 3 * j + 9 * k
v2 = 3 * i + 4 * j + k

# Define two rotation angles.
alpha1 = pi / 8
alpha2 = pi / 2

# Compute the rotation quaternions.
q1 = ((alpha1 / 2) * (v1 / v1.norm())).exp()
q2 = ((alpha2 / 2) * (v2 / v2.norm())).exp()

# Interpolate midpoint between the quaternions.
t = 0.5

# This is what should be done:
# q = exp((1 - t) * log(q1) + t * log(q2))
# Unfortunately, the package does not support a logarithm.

# Alternatively, one could do
# q = q1 * (inv(q1) * q2)**t * q2
# Unfortunately, the package does not support a power either.

# To create an interesting animation, you would
# linearly interpolate t from 0 to 1, and then
# observe how the object rotates from one
# position to another.

Quaternion reflection

# Define a vector along which to reflect.
q = k

# Define a vector to reflect.
v = 3 * i + 6 * j - 7 * k

# Reflect along q.
rv = -q * v * inv(q)

# Note that this is a reflection along `q`.
# We can also define reflection through `q`;
# just remove the minus. 

# Output the reflected vector.
print 'Reflect', v, 'along k', '=', rv

Files

Tutorial code for Cl(3, 0)+