Search documentation of bb

# BB.Math.Transform (bb v0.17.0)

Copy Markdown View Source

Homogeneous 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

### Types

t()

### Functions

apply_to_point(transform, vec3)

Apply a transform to a 3D point, returning the transformed point.

compose(transform1, transform2)

Compose (multiply) two transformation matrices.

compose_all(list)

Compose a list of transforms in order.

from_axis_angle(axis, angle)

Create a rotation transform around an arbitrary axis using the axis-angle representation.

from_origin(arg1)

Create a transformation matrix from position and orientation.

from_position_quaternion(pos, q)

Create a 4x4 transformation matrix from position and quaternion orientation.

from_quaternion(q)

Create a 4x4 transformation matrix from a quaternion (rotation only).

from_tensor(tensor)

Creates a transform from an existing `{4, 4}` tensor.

get_forward_vector(transform)

Get the forward vector (Z-axis) from a transformation matrix.

get_quaternion(transform)

Extract a quaternion from a transform.

get_right_vector(transform)

Get the right vector (X-axis) from a transformation matrix.

get_rotation(transform)

Get the rotation matrix (3x3) from a transform.

get_translation(transform)

Get the translation component of a transform as a Vec3.

get_up_vector(transform)

Get the up vector (Y-axis) from a transformation matrix.

identity()

Create a 4x4 identity transformation matrix.

inverse(transform)

Compute the inverse of a transformation matrix.

rotation_x(angle)

Create a rotation matrix around the X axis (roll).

rotation_y(angle)

Create a rotation matrix around the Y axis (pitch).

rotation_z(angle)

Create a rotation matrix around the Z axis (yaw).

tensor(transform)

Returns the underlying `{4, 4}` tensor.

translation(v)

Create a pure translation matrix from a Vec3.

translation_along(axis, distance)

Create a translation transform along an arbitrary axis.

## Types

# t()

    @type t() :: %BB.Math.Transform{tensor: Nx.Tensor.t()}

## Functions

# apply_to_point(transform, vec3)

    @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(transform1, transform2)

    @spec compose(t(), t()) :: t()

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_all(list)

    @spec compose_all([t()]) :: t()

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]

# from_axis_angle(axis, angle)

    @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 Vec3
- `angle`: 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}

# from_origin(arg1)

    @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 metres
- `orientation`: {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]

# from_position_quaternion(pos, q)

    @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]

# from_quaternion(q)

    @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}

# from_tensor(tensor)

    @spec from_tensor(Nx.Tensor.t()) :: t()

Creates a transform from an existing `{4, 4}` tensor.

# get_forward_vector(transform)

    @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]

# get_quaternion(transform)

    @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

# get_right_vector(transform)

    @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]

# get_rotation(transform)

    @spec get_rotation(t()) :: Nx.Tensor.t()

Get the rotation matrix (3x3) from a transform.

# get_translation(transform)

    @spec get_translation(t()) :: BB.Math.Vec3.t()

Get the translation component of a transform as a Vec3.

# get_up_vector(transform)

    @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]

# identity()

    @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]]

# inverse(transform)

    @spec inverse(t()) :: t()

Compute the inverse of a transformation matrix.

For a valid transformation matrix, this computes the inverse transform.

# rotation_x(angle)

    @spec rotation_x(float()) :: t()

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

# rotation_y(angle)

    @spec rotation_y(float()) :: t()

Create a rotation matrix around the Y axis (pitch).

# rotation_z(angle)

    @spec rotation_z(float()) :: t()

Create a rotation matrix around the Z axis (yaw).

# tensor(transform)

    @spec tensor(t()) :: Nx.Tensor.t()

Returns the underlying `{4, 4}` tensor.

# translation(v)

    @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]

# translation_along(axis, distance)

    @spec translation_along(BB.Math.Vec3.t(), float()) :: t()

Create a translation transform along an arbitrary axis.

## Parameters

- `axis`: normalised axis Vec3
- `distance`: 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]