BB.Math.Quaternion (bb v0.15.0)
View SourceUnit quaternion for 3D rotations, backed by an Nx tensor.
Quaternions are stored in WXYZ order (scalar first): [w, x, y, z].
All math operations use Nx for consistent performance and potential GPU acceleration.
All operations return normalised unit quaternions suitable for representing rotations.
The underlying tensor is always {4} shape with :f64 type.
Examples
iex> q = BB.Math.Quaternion.identity()
iex> BB.Math.Quaternion.w(q)
1.0
iex> q1 = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> q2 = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> q3 = BB.Math.Quaternion.multiply(q1, q2)
iex> BB.Math.Quaternion.angular_distance(q3, BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi()))
0.0
Summary
Functions
Computes the angular distance between two quaternions in radians.
Returns the conjugate of a quaternion.
Creates a quaternion from an axis-angle representation.
Creates a quaternion from Euler angles (roll, pitch, yaw).
Creates from a list in WXYZ order.
Creates a quaternion from a 3x3 rotation matrix.
Creates a quaternion from an existing {4} tensor.
Creates a quaternion representing the shortest rotation from one vector to another.
Creates from a list in XYZW order (for ROS/external system compatibility).
Returns the identity quaternion (no rotation).
Returns an identity quaternion as a raw tensor (for batch operations).
Returns the inverse of a quaternion.
Multiplies two quaternions (Hamilton product).
Creates a new quaternion from w, x, y, z components.
Normalises a quaternion to unit length.
Rotates a 3D vector by a quaternion.
Spherical linear interpolation between two quaternions.
Returns the underlying {4} tensor.
Converts a quaternion to axis-angle representation.
Converts a quaternion to Euler angles (roll, pitch, yaw).
Converts to a list in WXYZ order.
Converts a quaternion to a 3x3 rotation matrix.
Converts to a list in XYZW order (for ROS/external system compatibility).
Returns the W (scalar) component.
Returns the X component.
Returns the Y component.
Returns the Z component.
Types
@type t() :: %BB.Math.Quaternion{tensor: Nx.Tensor.t()}
Functions
Computes the angular distance between two quaternions in radians.
Returns a value between 0 and pi.
Examples
iex> q1 = BB.Math.Quaternion.identity()
iex> q2 = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> Float.round(BB.Math.Quaternion.angular_distance(q1, q2), 6)
1.570796
Returns the conjugate of a quaternion.
For unit quaternions, the conjugate equals the inverse.
Examples
iex> q = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> qc = BB.Math.Quaternion.conjugate(q)
iex> Float.round(BB.Math.Quaternion.z(qc), 6)
-0.707107
@spec from_axis_angle(BB.Math.Vec3.t(), number()) :: t()
Creates a quaternion from an axis-angle representation.
The axis should be a BB.Math.Vec3 unit vector (it will be normalised if not).
The angle is in radians.
Examples
iex> q = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> Float.round(BB.Math.Quaternion.w(q), 6)
0.707107
Creates a quaternion from Euler angles (roll, pitch, yaw).
Angles are in radians. Default order is :xyz (roll around X, pitch around Y, yaw around Z).
Supported orders: :xyz, :zyx
Examples
iex> q = BB.Math.Quaternion.from_euler(0, 0, :math.pi() / 2, :xyz)
iex> Float.round(BB.Math.Quaternion.z(q), 6)
0.707107
Creates from a list in WXYZ order.
Examples
iex> q = BB.Math.Quaternion.from_list([1.0, 0.0, 0.0, 0.0])
iex> BB.Math.Quaternion.w(q)
1.0
@spec from_rotation_matrix(Nx.Tensor.t()) :: t()
Creates a quaternion from a 3x3 rotation matrix.
Uses the Shepperd method for numerical stability.
Examples
iex> m = Nx.tensor([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
iex> q = BB.Math.Quaternion.from_rotation_matrix(m)
iex> BB.Math.Quaternion.w(q)
1.0
@spec from_tensor(Nx.Tensor.t()) :: t()
Creates a quaternion from an existing {4} tensor.
The tensor should be in WXYZ order. It will be normalised.
@spec from_two_vectors(BB.Math.Vec3.t(), BB.Math.Vec3.t()) :: t()
Creates a quaternion representing the shortest rotation from one vector to another.
Both vectors should be unit vectors (they will be normalised if not).
Returns the quaternion that rotates from to align with to.
Handles edge cases:
- Parallel vectors (from ≈ to): returns identity quaternion
- Anti-parallel vectors (from ≈ -to): returns 180° rotation around a perpendicular axis
Examples
iex> q = BB.Math.Quaternion.from_two_vectors(BB.Math.Vec3.unit_x(), BB.Math.Vec3.unit_y())
iex> rotated = BB.Math.Quaternion.rotate_vector(q, BB.Math.Vec3.unit_x())
iex> {Float.round(BB.Math.Vec3.x(rotated), 6), Float.round(BB.Math.Vec3.y(rotated), 6)}
{0.0, 1.0}
iex> q = BB.Math.Quaternion.from_two_vectors(BB.Math.Vec3.unit_z(), BB.Math.Vec3.unit_z())
iex> BB.Math.Quaternion.w(q)
1.0
Creates from a list in XYZW order (for ROS/external system compatibility).
Examples
iex> q = BB.Math.Quaternion.from_xyzw_list([0.0, 0.0, 0.0, 1.0])
iex> BB.Math.Quaternion.w(q)
1.0
@spec identity() :: t()
Returns the identity quaternion (no rotation).
Examples
iex> q = BB.Math.Quaternion.identity()
iex> {BB.Math.Quaternion.w(q), BB.Math.Quaternion.x(q), BB.Math.Quaternion.y(q), BB.Math.Quaternion.z(q)}
{1.0, 0.0, 0.0, 0.0}
@spec identity_tensor() :: Nx.Tensor.t()
Returns an identity quaternion as a raw tensor (for batch operations).
Returns the inverse of a quaternion.
For unit quaternions, this equals the conjugate.
Examples
iex> q = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> qi = BB.Math.Quaternion.inverse(q)
iex> qr = BB.Math.Quaternion.multiply(q, qi)
iex> Float.round(BB.Math.Quaternion.w(qr), 6)
1.0
Multiplies two quaternions (Hamilton product).
This composes the rotations: multiply(q1, q2) applies q2 first, then q1.
Examples
iex> q1 = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> q2 = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> q3 = BB.Math.Quaternion.multiply(q1, q2)
iex> {_axis, angle} = BB.Math.Quaternion.to_axis_angle(q3)
iex> Float.round(angle, 6)
3.141593
Creates a new quaternion from w, x, y, z components.
The quaternion is automatically normalised.
Examples
iex> q = BB.Math.Quaternion.new(1, 0, 0, 0)
iex> BB.Math.Quaternion.w(q)
1.0
Normalises a quaternion to unit length.
Examples
iex> q = %BB.Math.Quaternion{tensor: Nx.tensor([2.0, 0.0, 0.0, 0.0])}
iex> qn = BB.Math.Quaternion.normalise(q)
iex> BB.Math.Quaternion.w(qn)
1.0
@spec rotate_vector(t(), BB.Math.Vec3.t()) :: BB.Math.Vec3.t()
Rotates a 3D vector by a quaternion.
Examples
iex> q = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> v = BB.Math.Vec3.unit_x()
iex> rotated = BB.Math.Quaternion.rotate_vector(q, v)
iex> {Float.round(BB.Math.Vec3.x(rotated), 6), Float.round(BB.Math.Vec3.y(rotated), 6)}
{0.0, 1.0}
Spherical linear interpolation between two quaternions.
t should be between 0.0 and 1.0.
Examples
iex> q1 = BB.Math.Quaternion.identity()
iex> q2 = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi())
iex> q_mid = BB.Math.Quaternion.slerp(q1, q2, 0.5)
iex> {_axis, angle} = BB.Math.Quaternion.to_axis_angle(q_mid)
iex> Float.round(angle, 6)
1.570796
@spec tensor(t()) :: Nx.Tensor.t()
Returns the underlying {4} tensor.
@spec to_axis_angle(t()) :: {BB.Math.Vec3.t(), float()}
Converts a quaternion to axis-angle representation.
Returns {axis, angle} where axis is a BB.Math.Vec3 unit vector
and angle is in radians (0 to pi).
Examples
iex> q = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> {axis, angle} = BB.Math.Quaternion.to_axis_angle(q)
iex> Float.round(angle, 6)
1.570796
iex> Float.round(BB.Math.Vec3.z(axis), 1)
1.0
Converts a quaternion to Euler angles (roll, pitch, yaw).
Returns {roll, pitch, yaw} in radians. Default order is :xyz.
Note: Euler angles can have gimbal lock issues near pitch = ±90°.
Examples
iex> q = BB.Math.Quaternion.from_euler(0.1, 0.2, 0.3, :xyz)
iex> {roll, pitch, yaw} = BB.Math.Quaternion.to_euler(q, :xyz)
iex> Float.round(roll, 6)
0.1
Converts to a list in WXYZ order.
Examples
iex> q = BB.Math.Quaternion.identity()
iex> BB.Math.Quaternion.to_list(q)
[1.0, 0.0, 0.0, 0.0]
@spec to_rotation_matrix(t()) :: Nx.Tensor.t()
Converts a quaternion to a 3x3 rotation matrix.
Examples
iex> q = BB.Math.Quaternion.identity()
iex> m = BB.Math.Quaternion.to_rotation_matrix(q)
iex> Nx.to_number(m[0][0])
1.0
Converts to a list in XYZW order (for ROS/external system compatibility).
Examples
iex> q = BB.Math.Quaternion.identity()
iex> BB.Math.Quaternion.to_xyzw_list(q)
[0.0, 0.0, 0.0, 1.0]
Returns the W (scalar) component.
Returns the X component.
Returns the Y component.
Returns the Z component.