Windows Development Documentation

Official Microsoft Documentation for Windows Developers

Understanding and Using Quaternions

On This Page

Introduction

Quaternions are a mathematical concept used extensively in computer graphics, robotics, and physics simulations for representing rotations in 3D space. They offer a robust and efficient alternative to other rotation representations, particularly Euler angles.

What Are Quaternions?

A quaternion is a number system that extends complex numbers. It consists of four components: one real component and three imaginary components. In the context of 3D rotations, a quaternion can represent a rotation around an arbitrary axis by a specific angle.

They were first described by Irish mathematician William Rowan Hamilton in 1843.

Mathematical Representation

A quaternion q can be represented as:

q = w + xi + yj + zk

where:

For representing rotations, a unit quaternion (where the magnitude is 1) is typically used. A unit quaternion can be expressed in terms of an angle θ and an axis vector v = (x, y, z):

q = cos(θ/2) + (x*i + y*j + z*k)*sin(θ/2)

Here, w = cos(θ/2) and the vector part (x, y, z) represents the normalized axis of rotation.

Advantages Over Euler Angles

Common Operations

Key operations performed with quaternions include:

DirectXMath Implementation

The DirectXMath library provides a comprehensive set of functions for working with quaternions, primarily using the DirectX::XMVECTOR type, which can represent a 4D vector or a quaternion. A quaternion is typically stored as (x, y, z, w).

Key Structures and Types:

Example: Creating a Quaternion for a 90-degree rotation around the Y-axis:

C++ Example (using DirectXMath)

#include <DirectXMath.h>

// Define the rotation axis (Y-axis) and angle (90 degrees)
DirectX::XMVECTOR rotationAxis = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); // (x, y, z, w)
float angleInRadians = DirectX::XM_PIDIV2; // 90 degrees in radians

// Create the quaternion
DirectX::XMVECTOR quaternion = DirectX::XMQuaternionRotationAxis(rotationAxis, angleInRadians);

// The 'quaternion' XMVECTOR now holds the (x, y, z, w) components of the rotation.
// For example, you can extract components:
// float x = DirectX::XMVectorGetX(quaternion);
// float y = DirectX::XMVectorGetY(quaternion);
// float z = DirectX::XMVectorGetZ(quaternion);
// float w = DirectX::XMVectorGetW(quaternion);
                

Practical Examples

Rotating a Model

To rotate a 3D model, you typically create a rotation matrix from a quaternion and then multiply your model's vertex data by this matrix. Alternatively, you can directly rotate individual vertices represented as quaternions.

// Assuming 'modelQuaternion' represents the desired orientation
DirectX::XMMATRIX rotationMatrix = DirectX::XMMatrixRotationQuaternion(modelQuaternion);

// Apply this matrix to your model's vertices
// For each vertex v: v_rotated = v * rotationMatrix;
                

Camera Control

Quaternions are excellent for camera orientation. You can represent the camera's look direction and up vector, and use quaternion rotations for smooth panning, tilting, and orbiting movements without gimbal lock.

Interpolating Between Orientations

Using Slerp for smooth animation transitions:

// Assume:
// DirectX::XMVECTOR startQuaternion;
// DirectX::XMVECTOR endQuaternion;
// float interpolationFactor; // A value between 0.0 and 1.0

DirectX::XMVECTOR interpolatedQuaternion = DirectX::XMQuaternionSlerp(startQuaternion, endQuaternion, interpolationFactor);