BB.Math.Transform (bb v0.15.0)
View SourceHomogeneous transformation matrices for 3D transformations, backed by an Nx tensor.
All transforms are represented as 4x4 matrices in row-major order:
| R11 R12 R13 Tx |
| R21 R22 R23 Ty |
| R31 R32 R33 Tz |
| 0 0 0 1 |Where the upper-left 3x3 is the rotation matrix and the rightmost column is the translation vector.
Conventions
- All angles are in radians
- All distances are in metres
- Rotations use XYZ Euler angles (roll-pitch-yaw)
- Coordinate frame follows right-hand rule
Examples
iex> t = BB.Math.Transform.identity()
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[0.0, 0.0, 0.0]
iex> t = BB.Math.Transform.translation(BB.Math.Vec3.new(1, 2, 3))
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[1.0, 2.0, 3.0]
Summary
Functions
Apply a transform to a 3D point, returning the transformed point.
Compose (multiply) two transformation matrices.
Compose a list of transforms in order.
Create a rotation transform around an arbitrary axis using the axis-angle representation.
Create a transformation matrix from position and orientation.
Create a 4x4 transformation matrix from position and quaternion orientation.
Create a 4x4 transformation matrix from a quaternion (rotation only).
Creates a transform from an existing {4, 4} tensor.
Get the forward vector (Z-axis) from a transformation matrix.
Extract a quaternion from a transform.
Get the right vector (X-axis) from a transformation matrix.
Get the rotation matrix (3x3) from a transform.
Get the translation component of a transform as a Vec3.
Get the up vector (Y-axis) from a transformation matrix.
Create a 4x4 identity transformation matrix.
Compute the inverse of a transformation matrix.
Create a rotation matrix around the X axis (roll).
Create a rotation matrix around the Y axis (pitch).
Create a rotation matrix around the Z axis (yaw).
Returns the underlying {4, 4} tensor.
Create a pure translation matrix from a Vec3.
Create a translation transform along an arbitrary axis.
Types
@type t() :: %BB.Math.Transform{tensor: Nx.Tensor.t()}
Functions
@spec apply_to_point(t(), BB.Math.Vec3.t()) :: BB.Math.Vec3.t()
Apply a transform to a 3D point, returning the transformed point.
Examples
iex> t = BB.Math.Transform.translation(BB.Math.Vec3.new(1, 2, 3))
iex> p = BB.Math.Transform.apply_to_point(t, BB.Math.Vec3.zero())
iex> BB.Math.Vec3.to_list(p)
[1.0, 2.0, 3.0]
Compose (multiply) two transformation matrices.
compose(a, b) returns the transform that applies a first, then b.
Examples
iex> t1 = BB.Math.Transform.translation(BB.Math.Vec3.new(1, 0, 0))
iex> t2 = BB.Math.Transform.translation(BB.Math.Vec3.new(0, 2, 0))
iex> t = BB.Math.Transform.compose(t1, t2)
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[1.0, 2.0, 0.0]
Compose a list of transforms in order.
Examples
iex> transforms = [
...> BB.Math.Transform.translation(BB.Math.Vec3.new(1, 0, 0)),
...> BB.Math.Transform.translation(BB.Math.Vec3.new(0, 1, 0)),
...> BB.Math.Transform.translation(BB.Math.Vec3.new(0, 0, 1))
...> ]
iex> t = BB.Math.Transform.compose_all(transforms)
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[1.0, 1.0, 1.0]
@spec from_axis_angle(BB.Math.Vec3.t(), float()) :: t()
Create a rotation transform around an arbitrary axis using the axis-angle representation.
Uses Rodrigues' rotation formula to compute the rotation matrix.
Parameters
axis: normalised axis Vec3angle: rotation angle in radians
Examples
iex> axis = BB.Math.Vec3.unit_z()
iex> t = BB.Math.Transform.from_axis_angle(axis, :math.pi() / 2)
iex> p = BB.Math.Transform.apply_to_point(t, BB.Math.Vec3.unit_x())
iex> {Float.round(BB.Math.Vec3.x(p), 6), Float.round(BB.Math.Vec3.y(p), 6)}
{0.0, 1.0}
@spec from_origin(%{ position: {float(), float(), float()}, orientation: {float(), float(), float()} }) :: t()
Create a transformation matrix from position and orientation.
The origin map should have:
position: {x, y, z} in metresorientation: {roll, pitch, yaw} in radians
Rotation is applied in XYZ order (roll around X, then pitch around Y, then yaw around Z).
Examples
iex> origin = %{position: {1.0, 2.0, 3.0}, orientation: {0.0, 0.0, 0.0}}
iex> t = BB.Math.Transform.from_origin(origin)
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[1.0, 2.0, 3.0]
@spec from_position_quaternion(BB.Math.Vec3.t(), BB.Math.Quaternion.t()) :: t()
Create a 4x4 transformation matrix from position and quaternion orientation.
Examples
iex> pos = BB.Math.Vec3.new(1, 2, 3)
iex> q = BB.Math.Quaternion.identity()
iex> t = BB.Math.Transform.from_position_quaternion(pos, q)
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[1.0, 2.0, 3.0]
@spec from_quaternion(BB.Math.Quaternion.t()) :: t()
Create a 4x4 transformation matrix from a quaternion (rotation only).
The resulting matrix has the quaternion's rotation in the upper-left 3x3 and zero translation.
Examples
iex> q = BB.Math.Quaternion.from_axis_angle(BB.Math.Vec3.unit_z(), :math.pi() / 2)
iex> t = BB.Math.Transform.from_quaternion(q)
iex> p = BB.Math.Transform.apply_to_point(t, BB.Math.Vec3.unit_x())
iex> {Float.round(BB.Math.Vec3.x(p), 6), Float.round(BB.Math.Vec3.y(p), 6)}
{0.0, 1.0}
@spec from_tensor(Nx.Tensor.t()) :: t()
Creates a transform from an existing {4, 4} tensor.
@spec get_forward_vector(t()) :: BB.Math.Vec3.t()
Get the forward vector (Z-axis) from a transformation matrix.
The forward vector is the third column of the rotation matrix, representing the direction the local Z-axis points in world coordinates.
Examples
iex> t = BB.Math.Transform.identity()
iex> fwd = BB.Math.Transform.get_forward_vector(t)
iex> BB.Math.Vec3.to_list(fwd)
[0.0, 0.0, 1.0]
@spec get_quaternion(t()) :: BB.Math.Quaternion.t()
Extract a quaternion from a transform.
Extracts the 3x3 rotation portion and converts it to a unit quaternion.
Examples
iex> t = BB.Math.Transform.rotation_z(:math.pi() / 2)
iex> q = BB.Math.Transform.get_quaternion(t)
iex> {_axis, angle} = BB.Math.Quaternion.to_axis_angle(q)
iex> Float.round(angle, 6)
1.570796
@spec get_right_vector(t()) :: BB.Math.Vec3.t()
Get the right vector (X-axis) from a transformation matrix.
The right vector is the first column of the rotation matrix, representing the direction the local X-axis points in world coordinates.
Examples
iex> t = BB.Math.Transform.identity()
iex> right = BB.Math.Transform.get_right_vector(t)
iex> BB.Math.Vec3.to_list(right)
[1.0, 0.0, 0.0]
@spec get_rotation(t()) :: Nx.Tensor.t()
Get the rotation matrix (3x3) from a transform.
@spec get_translation(t()) :: BB.Math.Vec3.t()
Get the translation component of a transform as a Vec3.
@spec get_up_vector(t()) :: BB.Math.Vec3.t()
Get the up vector (Y-axis) from a transformation matrix.
The up vector is the second column of the rotation matrix, representing the direction the local Y-axis points in world coordinates.
Examples
iex> t = BB.Math.Transform.identity()
iex> up = BB.Math.Transform.get_up_vector(t)
iex> BB.Math.Vec3.to_list(up)
[0.0, 1.0, 0.0]
@spec identity() :: t()
Create a 4x4 identity transformation matrix.
Examples
iex> t = BB.Math.Transform.identity()
iex> BB.Math.Transform.tensor(t) |> Nx.to_list()
[[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0]]
Compute the inverse of a transformation matrix.
For a valid transformation matrix, this computes the inverse transform.
Create a rotation matrix around the X axis (roll).
Examples
iex> t = BB.Math.Transform.rotation_x(:math.pi() / 2)
iex> v = BB.Math.Transform.apply_to_point(t, BB.Math.Vec3.new(0, 1, 0))
iex> Float.round(BB.Math.Vec3.z(v), 6)
1.0
Create a rotation matrix around the Y axis (pitch).
Create a rotation matrix around the Z axis (yaw).
@spec tensor(t()) :: Nx.Tensor.t()
Returns the underlying {4, 4} tensor.
@spec translation(BB.Math.Vec3.t()) :: t()
Create a pure translation matrix from a Vec3.
Examples
iex> t = BB.Math.Transform.translation(BB.Math.Vec3.new(1, 2, 3))
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[1.0, 2.0, 3.0]
@spec translation_along(BB.Math.Vec3.t(), float()) :: t()
Create a translation transform along an arbitrary axis.
Parameters
axis: normalised axis Vec3distance: translation distance in metres
Examples
iex> axis = BB.Math.Vec3.unit_x()
iex> t = BB.Math.Transform.translation_along(axis, 2.5)
iex> BB.Math.Transform.get_translation(t) |> BB.Math.Vec3.to_list()
[2.5, 0.0, 0.0]