### Geometric Algebra Basics

Usually introductions to GA begin by defining various rules and going over derivations before doing anything useful with them. I will also define some rules but try to get to the interesting stuff more quickly.

#### Vectors

Like for the standard 2D vector algebra in GA we have two basis vectors${e}_{x},{e}_{y}$ using which arbitrary vectors$v=x{e}_{x}+y{e}_{y}$ can be formed. Below is some runnable and editable code that forms such vectors and then displays them as points. The basis vectors${e}_{x},{e}_{y}$ are labeled

`e0`

and `e1`

in the code. We specify the non-zero coefficients for each basis vector when creating a new vector.// Render point at x=10, y=-60

renderPointGA({ e0: 10, e1: -60 })

// Render point at x=-50, y=80

renderPointGA({ e0: -50, e1: 80 }, "red")

#### Geometric Product

The product which defines Geometric Algebra and is its most important aspect is called the Geometric Product. There are two useful rules for using the geometric product which will now be introduced.

##### Rule 1: Basis vectors square to +1

Multiplying two same basis vectors together with the geometric product will result in$+1$ (for now...) if they are the same.$${e}_{x}{e}_{x}=1,{e}_{y}{e}_{y}=1$$ This is similar to how the dot product in standard vector algebra works. Let's verify these results with the code again, this time just logging some text instead of visualizing.

var exSquared = ga.geometricProduct({ e0: 1 }, { e0: 1 })

var eySquared = ga.geometricProduct({ e1: 1 }, { e1: 1 })

log("e0^2:", exSquared)

log("e1^2:", eySquared)

Press run

##### Rule 2: Different basis vectors anti-commute

What is new is that we can also multiply two different basis vectors and the result will not be zero, but instead can't be simplified further.$${e}_{x}{e}_{y}={e}_{xy}$$ ${e}_{xy}$ here is just shorthand for the two basis vectors multiplied together. Such elements made up of two basis vectors are called bivectors.

Importantly the order of the product matters. A rule is that when you swap the factors of a product of basis vectors you pick up a minus sign. We say that the basis vectors anti-commute.$${e}_{xy}={e}_{x}{e}_{y}=-{e}_{y}{e}_{x}=-{e}_{yx}$$

var exEy = ga.geometricProduct({ e0: 1 }, { e1: 1 })

var eyEx = ga.geometricProduct({ e1: 1 }, { e0: 1 })

log("e0 e1:", exEy)

log("e1 e0:", eyEx)

Press run

##### Practice

Let's now use these two basic rules we just learnt and see what some results are when we use them:$$\begin{array}{rlr}{e}_{x}{e}_{y}{e}_{x}& =& \text{(Rewrite as shorthand)}\\ {e}_{xyx}& =& \text{(Swap neighbours on the right, pick up minus sign)}\\ -{e}_{xxy}& =& \text{(Multiplying same basis vectors results in 1, e\_xx = e\_x e\_x = 1)}\\ -{e}_{y}& \end{array}$$ We can verify these results with the code:

var exEy = ga.geometricProduct({ e0: 1 }, { e1: 1 })

var exEyEx = ga.geometricProduct(exEy, { e0: 1 })

log("e0 e1 e0:", exEyEx)

Press run

##### Terminology

Here's a list of some more terminology that is often used in GA

**Multivector**: any element of the algebra (eg. )$1+2{e}_{x}+5{e}_{xy}$ **Basis blade**: basis vectors and any combination of them (eg. in 2D we have four in total: )$1,{e}_{x},{e}_{y},{e}_{xy}$ **Grade**: the degree of a multivector (eg. is grade$1$ ,$0$ is grade${e}_{x}$ ,$1$ it also grade${e}_{x}+5{e}_{y}$ ,$1$ is grade${e}_{xy}$ )$2$

### Rotors

#### Squaring bivectors

Now for something more interesting, let's see what happens if we square the bivector${e}_{xy}$ , that is, multiplying it with itself:

var exEy = { e01: 1 }

var exEySquared = ga.geometricProduct(exEy, exEy)

log("e01^2", exEySquared)

Press run

There is still one caveat. While${e}_{xy}$ squares to$-1$ , so does${e}_{yx}$ . So which one do we use? Let's try to visualize what multiplying a vector does for both of them using${v}^{\prime}={e}_{xy}v$ and${v}^{\prime}={e}_{yx}v$ .

var eXy = { e01: 1 }

var eYx = { e01: -1 } // e_yx = -e_xy

var p = { e0: 70, e1: 0 }

var a = ga.geometricProduct(eXy, p)

var b = ga.geometricProduct(eYx, p)

renderPointGA(p)

renderPointGA(a, "red")

renderPointGA(b, "blue")

We can see that${e}_{xy}$ produces a clockwise (CW) rotation by 90° and${e}_{yx}$ produces a counter-clockwise (CCW) rotation by 90°. We will stick with the CCW version using${e}_{yx}$ . Instead of that to make a CCW rotation we could have also swapped the order of the product (${v}^{\prime}=v{e}_{xy}$ ) but using${e}_{yx}$ instead will allow us to follow the usual conventions later.

#### Rotating 2D vectors using rotors

As mentioned before${e}_{yx}$ can be identified as the imaginary unit$i$ of complex numbers hence we can represent complex numbers as$a+b{e}_{yx}$ and a CCW rotation in the XY plane by an arbitrary angle$\varphi $ can be performed just like with complex numbers using Euler's formula$$R(\varphi )={e}^{\varphi {e}_{yx}}=cos(\varphi )+{e}_{yx}sin(\varphi )$$ The object$R$ you get after exponentiating is called a rotor (because it rotates when you multiply with it). Unlike with complex numbers now however, we can multiply a vector by a rotor directly instead of having to treat vectors as if they were complex numbers.

var phi = Math.PI * 3 / 4 // 135°

// e^(phi e_{yx}) = e^(-phi e_{xy})

var r = ga.exponential({ e01: -phi })

var p = { e0: 70, e1: 0 }

// p rotated by 135° counter-clockwise

var rotatedP = ga.geometricProduct(r, p)

renderPointGA(p)

renderPointGA(rotatedP, "red")

renderInfo(ga.repr(rotatedP), "red")

#### Higher dimensions

It turns out that the two dimensional rotor application formula${v}^{\prime}=Rv$ was slightly special. In the general case it is necessary to use a two sided product$${v}^{\prime}=Rv\stackrel{~}{R}$$ which is also called the sandwich product.$\stackrel{~}{R}$ here stands for reversion of$R$ which just means reversing the order of all basis vectors. For example${e}_{yx}$ becomes${e}_{xy}$ . As we already know from the second rule of the geometric product, such a change of order just produces a minus sign for the bivectors, so$\stackrel{~}{{e}_{yx}}=-{e}_{xy}$ .

Another thing that changes with the sandwich product is that we multiply with the rotor twice, so our rotor will only need to contain half of the rotation angle.$$R(\varphi )={e}^{{e}_{yx}\frac{\varphi}{2}}$$

We can now verify that this will indeed give the same results in 2D as the simple one-sided product

var phi = Math.PI * 3 / 4 // 135°

// e^(phi/2 e_{yx}) = e^(-phi/2 e_{xy})

// Only half the angle required with sandwich product

var r = ga.exponential({ e01: -phi / 2 })

var p = { e0: 70, e1: 0 }

// R p ~R (sandwich product)

// p rotated by 135° counter-clockwise

var rotatedP = ga.geometricProduct(

r,

ga.geometricProduct(p, ga.reversion(r))

)

renderPointGA(p)

renderPointGA(rotatedP, "red")

renderInfo(ga.repr(rotatedP), "red")

In the three dimensional case, if we wanted to create a rotor that rotates in the XZ plane by$\varphi $ CCW our rotor would look like this:$$R(\varphi )={e}^{{e}_{zx}\frac{\varphi}{2}}$$ We can then also combine rotations in different planes into a single rotor by multiplying them. A rotor that rotates by$\varphi $ CCW in the XZ plane followed by a rotation of$\theta $ CCW in the XY plane looks like this$$R(\varphi ,\theta )={e}^{{e}_{yx}\frac{\theta}{2}}{e}^{{e}_{zx}\frac{\varphi}{2}}$$

var phi = Math.PI * 3 / 4 // 135°

var theta = Math.PI / 2 // 90°

// CCW XZ rotation by phi

var r1 = ga3d.exponential({ e02: -phi / 2 })

// CCW XY rotation by theta

var r2 = ga3d.exponential({ e01: -theta / 2 })

// Compose XY and XZ rotation

var r = ga3d.geometricProduct(r2, r1)

var p = { e0: 70, e1: 0, e2: 0 }

// p first rotated by phi in XZ, then by theta in XY

var rotatedP = ga3d.geometricProduct(

r,

ga3d.geometricProduct(p, ga3d.reversion(r))

)

log("Rotated P:", rotatedP)

Press run

These elements that are like the 3D version of complex numbers are called quaternions.

#### More on reversion

Applying the reversion operation on a rotor reverses its effect, for example applying the reversion operation to a rotor that rotates by 90° CCW will make it rotate by 90° CW (ie. -90° CCW). A result of this is that a rotor multiplied by its reversal produces the identity$R\stackrel{~}{R}=1$ which does nothing when applied as demonstrated in the code below. Here we also make use of the

`sandwichProduct()`

function instead of writing the sandwich product using `geometricProduct()`

and `reversion()`

.var phi = Math.PI * 3 / 4 // 135°

var theta = Math.PI / 2 // 90°

var r1 = ga3d.exponential({ e02: -phi / 2 })

var r2 = ga3d.exponential({ e01: -theta / 2 })

// Compose XY and XZ rotation

var r = ga3d.geometricProduct(r2, r1)

var p = { e0: 70, e1: 0, e2: 0 }

// (R ~R) p (R ~P)

var q = ga3d.sandwichProduct(

p,

ga3d.geometricProduct(r, ga3d.reversion(r))

)

log("q:", q)

Press run

### Summary

**Geometric product rule 1**: basis vectors square to +1 ( )${e}_{x}{e}_{x}={e}_{xx}=1,{e}_{y}{e}_{y}={e}_{yy}=1$ **Geometric product rule 2**: different basis vectors anti-commute ( )${e}_{x}{e}_{y}={e}_{xy}=-{e}_{yx}=-{e}_{y}{e}_{x}$ **Rotor in XY plane rotating by**: counter-clockwise$\varphi $ $R(\varphi )={e}^{\varphi {e}_{yx}}=cos(\varphi )+{e}_{yx}sin(\varphi )$ **Reversion**: reverse order of basis vectors (eg. ), inverts rotors${e}_{xyz}={e}_{zyx}=-{e}_{xyz}$ **Apply Rotor**: to$R$ using sandwich product$x$ ${x}^{\prime}=Rx\stackrel{~}{R}$

### Conclusion

In this section we introduced Geometric Algebra. We learnt the basic rules of the Geometric Product and how to work with them. We also learnt about rotors which generalize the rotations created by complex numbers to any dimension and also puts them directly in the context of vectors.

In the next section we will learn how we can introduce translation in the rotors so we can do both translation and rotation using the same rotor and just one sandwich product. This will prove to have many advantages allow even further generalization.