# Quaternion

A quaternion is commonly used to represent a 3D rotation. Like `Float4`, it consists of four floating-point components `x`, `y`, `z` and `w`.

Only unit quaternions (ie. quaternions with unit length) represent valid 3D rotations. The `x`, `y` and `z` components give the direction of the rotation axis, while the `w` component is the cosine of half the rotation angle. Rotation follows the right-hand rule in a right-handed coordinate system.

When working with quaternions and vectors, the `*` operator behaves differently depending on the type of the operands:

• If `a` and `b` are both `Quaternion`, `a * b` returns their Hamilton product (composition).
• If `q` is a unit `Quaternion` and `v` is a `Float3`, `q * v` rotates `v` using `q`.
• If `a` and `b` are both `Float4`, `a * b` performs componentwise multiplication.

`#include <ply-math/Matrix.h>`

Also included from `<ply-math/Base.h>`.

## Data Members

`float x` [code]
`float y` [code]
`float z` [code]
`float w` [code]

`w` is the fourth component. It follows `z` sequentially in memory.

## Constructors

` Quaternion::Quaternion()` [code]

Constructs an uninitialized `Quaternion`.

` Quaternion::Quaternion(float x, float y, float z, float w)` [code]

Constructs a `Quaternion` from the given components.

``````Quaternion q = {0, 0, 0, 1};
``````
` Quaternion::Quaternion(const Float3& v, float w)` [code]

Constructs a `Quaternion` from a `Float3` and a fourth component.

## Conversion Functions

`const Float3& Quaternion::asFloat3() const` [code]

Returns a const reference to the first three components as a `Float3` using type punning. This should only be used as a temporary expression.

`const Float4& Quaternion::asFloat4() const` [code]

Casts to `Float4` using type punning. This should only be used as a temporary expression.

## Creation Functions

`static Quaternion Quaternion::identity()` [code]

Returns the identity quaternion `{0, 0, 0, 1}`.

`static Quaternion Quaternion::fromAxisAngle(const Float3& unitAxis, float radians)` [code]

Returns a quaternion that represents a rotation around the given axis. `unitAxis` must have unit length. The angle is specified in radians. Rotation follows the right-hand rule in a right-handed coordinate system.

`static Quaternion Quaternion::fromUnitVectors(const Float3& start, const Float3& end)` [code]

Returns a unit quaternion that transforms `start` to `end`. Both input vectors must have unit length.

`static Quaternion Quaternion::fromOrtho(const Float3x3& m)` [code]
`static Quaternion Quaternion::fromOrtho(const Float3x4& m)` [code]
`static Quaternion Quaternion::fromOrtho(const Float4x4& m)` [code]

Converts a rotation matrix to a unit quaternion.

## Rotation Functions

`Quaternion Quaternion::inverted() const` [code]

Given a unit quaternion, returns a unit quaternion that represents its inverse rotation.

This function actually returns the conjugate of the given quaternion by negating its `x`, `y` and `z` components, with the understanding that the conjugate of a unit quaternion is also its inverse.

`Float3 Quaternion::rotateUnitX() const` [code]
`Float3 Quaternion::rotateUnitY() const` [code]
`Float3 Quaternion::rotateUnitZ() const` [code]

Rotates the special vectors (1, 0, 0), (0, 1, 0) and (0, 0, 1) by the given quaternion using fewer instructions than `operator*()`.

• `q.rotateUnitX()` is equivalent to `q * Float3{1, 0, 0}`
• `q.rotateUnitY()` is equivalent to `q * Float3{0, 1, 0}`
• `q.rotateUnitZ()` is equivalent to `q * Float3{0, 0, 1}`

This function will probably be replaced by an overload of `operator*()` that accepts `Axis3` values.

`Float3 operator*(const Quaternion& q, const Float3& v)` [code]

Rotates the vector `v` by the quaternion `q`. `q` must have unit length.

`Quaternion operator*(const Quaternion& a, const Quaternion& b)` [code]

Composes two quaternions using the Hamilton product. If both quaternions have unit length, the resulting quaternion represents a rotation by `b` followed by a rotation by `a`.

## Quaternion Functions

`Quaternion Quaternion::normalized() const` [code]

Returns a unit quaternion having the same direction as `this`. The input quaternion must not be zero. When many unit quaternions are composed together, it's a good idea to occasionally re-normalize the result to compensate for any drift caused by floating-point imprecision.

`Quaternion operator-(const Quaternion& q)` [code]

Unary negation. All components of the original quaternion are negated. If the quaternion has unit length, the resulting quaternion represents the same 3D rotation as the original quaternion.

## Interpolation Functions

`Quaternion Quaternion::negatedIfCloserTo(const Quaternion& other) const` [code]

Returns either `this` or `-this`, whichever is closer to `other`. If `this` has unit length, the resulting quaternion represents the same 3D rotation as `this`.

In general, when interpolating between arbitrary quaternions `a` and `b`, it's best to interpolate from `a` to `b.negatedIfCloserTo(a)` since this form takes the shortest path.

`Quaternion mix(const Quaternion& a, const Quaternion& b, float f)` [code]

Interpolates between two quaternions. Performs a linear interpolation on the components of `a.negatedIfCloserTo(b)` and `b`, then normalizes the result.