## Quaternions part 1

For a while I’ve been thinking about quaternions. Here’s an introduction to the mathematical basis of quaternions for representing rotations in 3d.

### Why would you use a quaternion?

Quaternions are a convenient way to represent rotations in 3 dimensional space. Unit quaternions (quaternions of length 1) are used for this purpose. The main advantage they have over Euler angles is that they can be interpolated without looking awful. You can compose rotations by multiplying quaternions, much like with rotation matricies, but a unit quaternions is always a rotation, while a 3×3 matrix could be a number of other types of (possibly undesirable) transformations. This property means that you can multiply or interpolate a bunch of quaternions, and even if there is some numerical inaccuracy, you can just normalize the result and you still have a rotation.

There are other uses outside of game development and other 3d math, but they are rather rare. They have uses in relativity, and dual quaternions can be used to represent spatial displacement.

### What is a quaternion?

Much like complex numbers or polynomials, quaternions are real numbers extended with additional elements.

Polynomials can be generated by taking the real numbers, and adding a new element ‘x’ such that multiplication and addition are both still associative and commititave. For example, is a polynomial, and is a polynomial, and is a polynomial, and is a polynomial.

The general form of a polynomial is

A complex number is very similar to a polynomial, but with an additional rule that the new element, , has the property that. So, any integer power of greater than 1 is in . Instead of , you could just write .

The general form of a complex number is .

Quaternions can be generated by extending the real numbers with 3 new elements , , and , such that . It’s important to note that multiplication with , ,and is not commutative in general. You can show that , but , for example. As a result of these rules, any quaternion can be written as , where , , , and are real numbers. You might notice that when , you have the complex numbers. Another way to write quaternions is , where is a real number, and is a 3 dimensional vector. This alternate representation is convenient for some operations.

### How do you multiply quaternions?

Multiplication can be derived right from the definition. I’m not going to go into detail in this post, but the basis elements (1, i, j, k) form a multiplicative group with the following multiplication table:

using multiplication of the basis elements, we can derive multiplication of general quaternions.

let

then

and by rearanging, you can get:

where

so

**How do you apply the rotation?**

Say you have a vector u that you want to rotate by a unit quaternion q. You can do it by treating the vector as a quaternion, and performing an operation called conjugation.

The inverse of a quaternion is

because

and for a unit quaternion, this simplifies to

And to compose roations, you can conjugate twice

so composing rotations is the same as multiplying quaternions.

**How do you construct a quaternion from another representation?**

If you have an axis-angle representation, with axis , and angle , the quaternion is:

you can also go backwards, and convert from quaternion to axis-angle representation.

This post covered multiplication, inverse, conjugation, and axis-angle representation, so it should be enough math to make a crude quaternion library, but you really need the Slerp function for it to be worth the effort. In another post, I will explain why conjugation is rotation, and how the Slerp function works.

part 2 is up now.

Twisted Oak Studios offers consulting and development on high-tech interactive projects. Check out our portfolio, or Give us a shout if you have anything you think some really rad engineers should help you with.

## Archive

- strilanc
- What Quantum Computers Do Faster, with Caveats
- Naming Things: Fail-Useful
- Detecting Simple Cycles Forming, Faster
- Third Party Bit Commitment
- Angular Velocity is Simple
- Collection Equality is Hard
- Deadlocks in Practice: Don’t Hold Locks While Notifying
- Brute Force Parallelization
- A Year’s Worth of Opinions about Objective-C
- Referencing Substrings Faster, without Leaking Memory
- Not Crying Over Old Code
- Exploring Universal Ternary Gates
- Impractical Experiments #2: Securing Peer to Peer Fog of War against Map Hacks
- Achieving Exponential Slowdown by Enumerating Twice
- Using Immortality to Kill Accidental Callback Cycles
- Cancellation Tokens (and Collapsing Futures) for Objective-C
- Visualizing the Eigenvectors of a Rotation
- Collapsing Futures in Objective-C
- Bug Hunting #1: Garbled Audio from End to End
- Impractical Experiments #1: Representing Numbers as Polynomials
- Implementing Quantum Pseudo-Telepathy
- Turn On Your Damn Warnings
- Big-O Made Trivial
- Unfathomable Bugs #7: The Broken Oven
- Solomonoff’s Mad Scientist
- Yearly Blogging Roundup #1
- What isn’t a Monad
- Searching a Sorted Matrix Faster
- How to Read Nested Ternary Operators
- Making Sublime Text 2 Jump to the Correct Line with Unity on OS X
- My Bug, My Bad #4: Reading Concurrently
- Whole API Testing with Reflection
- Optimizing a Parser Combinator into a memcpy
- Don’t Treat Paths Like Strings
- Breaking a Toy Hash Function
- Counting Iterators Lazily
- Unfathomable Bugs #6: Pretend Precision
- My Bug, My Bad #3: Accidentally Attacking WarCraft 3
- Collapsing Types vs Monads (followup)
- Collapsing Futures: Easy to Use, Hard to Represent
- Eventual Exceptions vs Programming in a Minimal Functional Style
- The Mystery of Flunf
- Explain it like I’m Five: The Socialist Millionaire Problem and Secure Multi-Party Computation
- Computer Science Blows My Mind
- A visit to Execution Labs in Montréal
- Transmuting Dice, Conserving Entropy
- Rule of Thumb: Ask for the Clock
- Rule of Thumb: Use Purposefully Weakened Methods
- Rule of thumb: Preconditions Should be Checked Explicitly
- Intersecting Linked Lists Faster
- Mouse Path Smoothing for Jack Lumber
- My Bug, My Bad #2: Sunk by Float
- Repeat Yourself Differently
- Grover’s Quantum Search Algorithm
- Followup to Non-Nullable Types vs C#
- Optimizing Just in Time with Expression Trees
- When One-Way Latency Doesn’t Matter
- Determining exactly if/when/where a moving line intersected a moving point
- Emulating Actors in C# with Async/Await
- Making an immutable queue with guaranteed constant time operations
- Improving Checked Exceptions
- Perishable Collections: The Benefits of Removal-by-Lifetime
- Decoupling shared control
- Decoupling inlined UI code
- Linq to Collections: Beyond IEnumerable<T>
- Publish your .Net library as a NuGet package
- When null is not enough: an option type for C#
- Unfathomable Bugs #5: Readonly or not
- Minkowski sums: examples
- My Bug, My Bad #1: Fractal Spheres
- Working around the brittle UI Virtualization in Windows 8
- Encapsulating Angles
- Unfathomable Bugs #4: Keys that aren’t
- How would I even use a monad (in C#)?
- Useful/Interesting Methods #1: Observable.WhenEach
- Unfathomable Bugs #3: Stringing you along
- Anonymous Implementation Classes – A Design Pattern for C#
- Tasks for ActionScript 3 – Improving on Event-Driven Programming
- Minkowski sums and differences
- Non-Nullable Types vs C#: Fixing the Billion Dollar Mistake
- Unfathomable Bugs #2: Slashing Out
- Script templates and base classes
- Unity font extraction
- Abusing “Phantom Types” to Encode List Lengths Into Their Type
- Constructive Criticism of the Reactive Extensions API
- Quaternions part 3
- Quaternions part 2
- Quaternions part 1
- Unfathomable Bugs #1: You can have things! You can have things IN things! You can have …
- Coroutines – More than you want to know
- Asset Bundle Helper
- The Visual Studio goes away
- .Net’s time traveling StopWatch
- Introducing Catalyst