View Source Graphmath.Mat44 (graphmath v3.0.0)

4x4 matrices and 3D transformations, using tuples of floats.

Reflection and shear constructors act on three spatial coordinates and preserve the fourth, homogeneous coordinate. Use transform_point/2 for points (w = 1) and transform_vector/2 for directions (w = 0), so that translation affects only points. A shear can change X, Y or Z; w is not another spatial axis.

perspective/4 and ortho/6 project right-handed camera coordinates with -Z forward into the OpenGL normalized device depth range [-1, +1]. Perspective projection requires keeping the output of apply_left/2 and dividing its first three coordinates by w; transform_point/2 does not perform that step.

Tuples store matrix rows in order. apply(a, v) computes the column-vector product A**v. Graphics constructors use row vectors: transform_point/2 and transform_vector/2 multiply {x,y,z,1} and {x,y,z,0} by A** from the left, then drop the fourth coordinate. Use apply_left(v, a) or apply_transpose(a, v) for the corresponding full four-component product.

For full vectors, apply_left(v, multiply(a, b)) applies a first, then b.

Camera and billboard helpers use a right-handed basis with local -Z forward, +Y up and +X right. orient/3 and the billboard constructors map local coordinates into world space; look_at/3 maps world space into camera space.

Summary

Functions

add(a,b) adds one mat44 to another mat44.

apply( a, v ) transforms a vec4 by a mat44.

apply_left( v, a ) transforms a vec4 by a mat44, applied on the left.

apply_left_transpose( v, a ) transforms a vec3 by a transposed mat33, applied on the left.

apply_transpose( a, v ) transforms a vec4 by a a transposed mat44.

at( a, i, j) selects an element of a mat44.

Returns the signed minor at zero-based row i and column j.

column0( a ) selects the first column of a mat44.

column1( a ) selects the second column of a mat44.

column2( a ) selects the third column of a mat44.

column3( a ) selects the fourth column of a mat44.

Returns the determinant of a.

diag( a ) selects the diagonal of a mat44.

identity() creates an identity mat44.

inverse(a) calculates the inverse matrix

Creates a right-handed world-to-camera view matrix.

Creates a spherical billboard at position facing camera_position.

Creates a cylindrical billboard at position, constrained to axis.

Creates a 3D affine reflection across nx*x + ny*y + nz*z = offset.

make_rotate_x( theta ) creates a mat44 that rotates a vec3 by theta radians about the +X axis.

make_rotate_y( theta ) creates a mat44 that rotates a vec3 by theta radians about the +Y axis.

make_rotate_Z( theta ) creates a mat44 that rotates a vec3 by theta radians about the +Z axis.

make_scale( k ) creates a mat44 that uniformly scales.

make_scale( sx, sy, sz, sw ) creates a mat44 that scales each axis independently.

Creates a 3D affine X shear: x' = x + ky*y + kz*z.

Creates a 3D affine Y shear: y' = y + kx*x + kz*z.

Creates a 3D affine Z shear: z' = z + kx*x + ky*y.

make_translate( tx, ty, tz ) creates a mat44 that translates a point by tx, ty, and tz.

multiply( a, b ) multiply two matrices a and b together.

multiply_transpose( a, b ) multiply two matrices a and b<sup>T</sup> together.

Creates a rigid local-to-world transform at position, looking along forward.

Creates a right-handed orthographic projection for row vectors.

Creates a right-handed perspective projection for row vectors.

round( a, sigfigs ) rounds every element of a mat44 to some number of decimal places.

row0( a ) selects the first row of a mat44.

row1( a ) selects the second row of a mat44.

row2( a ) selects the third row of a mat44.

row3( a ) selects the fourth row of a mat44.

scale( a, k ) scales every element in a mat44 by a coefficient k.

Returns the Graphmath.Mat33 obtained by deleting row i and column j.

subtract(a,b) subtracts one mat44 from another mat44.

Returns the trace, the sum of the diagonal entries.

Transforms a 3D point {x, y, z} using the row-vector product {x, y, z, 1.0} a.

Transforms a 3D direction {x, y, z} using the row-vector product {x, y, z, 0.0} a.

zero() creates a zeroed mat44.

Types

@type mat44() ::
  {float(), float(), float(), float(), float(), float(), float(), float(),
   float(), float(), float(), float(), float(), float(), float(), float()}
@type vec3() :: {float(), float(), float()}
@type vec4() :: {float(), float(), float(), float()}

Functions

@spec add(mat44(), mat44()) :: mat44()

add(a,b) adds one mat44 to another mat44.

a is the first mat44.

b is the second mat44.

This returns a mat44 which is the element-wise sum of a and b.

@spec apply(mat44(), vec4()) :: vec4()

apply( a, v ) transforms a vec4 by a mat44.

a is the mat44 to transform by.

v is the vec4 to be transformed.

This returns a vec4 representing A**v**.

This is the "full" application of a matrix, and uses all elements.

@spec apply_left(vec4(), mat44()) :: vec4()

apply_left( v, a ) transforms a vec4 by a mat44, applied on the left.

a is the mat44 to transform by.

v is the vec4 to be transformed.

This returns a vec4 representing v**A**.

This is the "full" application of a matrix, and uses all elements.

Link to this function

apply_left_transpose(arg1, arg2)

View Source
@spec apply_left_transpose(vec4(), mat44()) :: vec4()

apply_left_transpose( v, a ) transforms a vec3 by a transposed mat33, applied on the left.

a is the mat44 to transform by.

v is the vec4 to be transformed.

This returns a vec4 representing v**A**<sup>T</sup>.

This is the "full" application of a matrix, and uses all elements.

Link to this function

apply_transpose(arg1, arg2)

View Source
@spec apply_transpose(mat44(), vec4()) :: vec4()

apply_transpose( a, v ) transforms a vec4 by a a transposed mat44.

a is the mat44 to transform by.

v is the vec4 to be transformed.

This returns a vec4 representing A<sup>T</sup>v.

This is the "full" application of a matrix, and uses all elements.

@spec at(mat44(), non_neg_integer(), non_neg_integer()) :: float()

at( a, i, j) selects an element of a mat44.

a is the mat44 to index.

i is the row integer index [0,3].

j is the column integer index [0,3].

This returns a float from the matrix at row i and column j.

@spec cofactor(mat44(), 0..3, 0..3) :: float()

Returns the signed minor at zero-based row i and column j.

This is the determinant of submatrix(a, i, j), negated when i + j is odd. Indices must be integers from 0 through 3; invalid indices raise FunctionClauseError.

@spec column0(mat44()) :: vec4()

column0( a ) selects the first column of a mat44.

a is the mat44 to take the first column of.

This returns a vec4 representing the first column of a.

@spec column1(mat44()) :: vec4()

column1( a ) selects the second column of a mat44.

a is the mat44 to take the second column of.

This returns a vec4 representing the second column of a.

@spec column2(mat44()) :: vec4()

column2( a ) selects the third column of a mat44.

a is the mat44 to take the third column of.

This returns a vec4 representing the third column of a.

@spec column3(mat44()) :: vec4()

column3( a ) selects the fourth column of a mat44.

a is the mat44 to take the fourth column of.

This returns a vec4 representing the fourth column of a.

@spec determinant(mat44()) :: float()

Returns the determinant of a.

@spec diag(mat44()) :: vec4()

diag( a ) selects the diagonal of a mat44.

a is the mat44 to take the diagonal of.

This returns a vec4 representing the diagonal of a.

@spec identity() :: mat44()

identity() creates an identity mat44.

This returns an identity mat44.

@spec inverse(mat44()) :: mat44()

inverse(a) calculates the inverse matrix

a is a mat44 to be inverted

Returs a mat44 representing a<sup>-1</sup>

Raises an error when you try to calculate inverse of a matrix whose determinant is zero

@spec look_at(vec3(), vec3(), vec3()) :: mat44()

Creates a right-handed world-to-camera view matrix.

eye is the camera position, center is a target point, and up is a direction controlling roll. The eye maps to the origin and the target maps onto the negative Z axis. Local +Y is up and local +X is right.

This is the inverse of orient(eye, center - eye, up). Apply with transform_point/2 or apply_left/2, following the row-vector convention.

Raises ArithmeticError when eye and center coincide, up is zero, or the cross product of the normalized viewing and up directions has length at most 1.0e-12.

Examples

iex> view = Graphmath.Mat44.look_at({0.0, 0.0, 5.0}, {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0})
iex> Graphmath.Mat44.transform_point(view, {2.0, 3.0, 0.0})
{2.0, 3.0, -5.0}
Link to this function

make_billboard(position, arg2, camera_up)

View Source
@spec make_billboard(vec3(), vec3(), vec3()) :: mat44()

Creates a spherical billboard at position facing camera_position.

The billboard lies in its local XY plane, with its front pointing along local -Z. Its front faces the camera, and local +Y follows the perpendicular component of camera_up. The result is a local-to-world transform; apply it with transform_point/2 or apply_left/2.

Equivalent to orient(position, camera_position - position, camera_up). Raises ArithmeticError when the positions coincide, camera_up is zero, or the cross product of the normalized facing and up directions has length at most 1.0e-12.

Link to this function

make_billboard_axis(arg1, arg2, axis)

View Source
@spec make_billboard_axis(vec3(), vec3(), vec3()) :: mat44()

Creates a cylindrical billboard at position, constrained to axis.

Local +Y stays aligned with the normalized axis. The billboard's front (local -Z) faces the projection of camera_position - position onto the plane perpendicular to axis. Moving the camera along the axis does not change the billboard's orientation.

The result is a right-handed local-to-world transform. Apply it with transform_point/2 or apply_left/2.

Raises ArithmeticError for a zero axis, coincident positions, or when the cross product of the normalized facing and axis directions has length at most 1.0e-12. In particular, a camera on the rotation axis does not define a facing direction.

Link to this function

make_reflect(arg, offset)

View Source
@spec make_reflect(vec3(), float()) :: mat44()

Creates a 3D affine reflection across nx*x + ny*y + nz*z = offset.

The normal may have any nonzero length. offset is the plane equation constant; it is a signed distance only when the normal has unit length. Scaling the normal and offset by the same nonzero factor leaves the mirror unchanged. A zero normal raises ArithmeticError.

Use transform_point/2 for points and transform_vector/2 for directions. The homogeneous coordinate is preserved; translation affects only points.

@spec make_rotate_x(float()) :: mat44()

make_rotate_x( theta ) creates a mat44 that rotates a vec3 by theta radians about the +X axis.

theta is the float of the number of radians of rotation the matrix will provide.

This returns a mat44 which rotates by theta radians about the +X axis.

@spec make_rotate_y(float()) :: mat44()

make_rotate_y( theta ) creates a mat44 that rotates a vec3 by theta radians about the +Y axis.

theta is the float of the number of radians of rotation the matrix will provide.

This returns a mat44 which rotates by theta radians about the +Y axis.

@spec make_rotate_z(float()) :: mat44()

make_rotate_Z( theta ) creates a mat44 that rotates a vec3 by theta radians about the +Z axis.

theta is the float of the number of radians of rotation the matrix will provide.

This returns a mat44 which rotates by theta radians about the +Z axis.

@spec make_scale(float()) :: mat44()

make_scale( k ) creates a mat44 that uniformly scales.

k is the float value to scale by.

This returns a mat44 whose diagonal is all ks.

Link to this function

make_scale(sx, sy, sz, sw)

View Source
@spec make_scale(float(), float(), float(), float()) :: mat44()

make_scale( sx, sy, sz, sw ) creates a mat44 that scales each axis independently.

sx is a float for scaling the x-axis.

sy is a float for scaling the y-axis.

sz is a float for scaling the z-axis.

sw is a float for scaling the w-axis.

This returns a mat44 whose diagonal is { sx, sy, sz, sw }.

Note that, when used with vec3s via the transform methods, sw will have no effect.

@spec make_shear_x(float(), float()) :: mat44()

Creates a 3D affine X shear: x' = x + ky*y + kz*z.

The other spatial coordinates and homogeneous coordinate are unchanged. Use transform_point/2 or transform_vector/2 with 3 spatial components.

@spec make_shear_y(float(), float()) :: mat44()

Creates a 3D affine Y shear: y' = y + kx*x + kz*z.

The other spatial coordinates and homogeneous coordinate are unchanged. Use transform_point/2 or transform_vector/2 with 3 spatial components.

@spec make_shear_z(float(), float()) :: mat44()

Creates a 3D affine Z shear: z' = z + kx*x + ky*y.

The other spatial coordinates and homogeneous coordinate are unchanged. Use transform_point/2 or transform_vector/2 with 3 spatial components.

Link to this function

make_translate(tx, ty, tz)

View Source
@spec make_translate(float(), float(), float()) :: mat44()

make_translate( tx, ty, tz ) creates a mat44 that translates a point by tx, ty, and tz.

make_translate( tx, ty, tz ) creates a mat44 that translates a vec3 by (tx, ty, tz).

tx is a float for translating along the x-axis.

ty is a float for translating along the y-axis.

tz is a float for translating along the z-axis.

This returns a mat44 which translates by a vec3 { tx, ty, tz }.

@spec multiply(mat44(), mat44()) :: mat44()

multiply( a, b ) multiply two matrices a and b together.

a is the mat44 multiplicand.

b is the mat44 multiplier.

This returns the mat44 product of the a and b.

Link to this function

multiply_transpose(arg1, arg2)

View Source
@spec multiply_transpose(mat44(), mat44()) :: mat44()

multiply_transpose( a, b ) multiply two matrices a and b<sup>T</sup> together.

a is the mat44 multiplicand.

b is the mat44 multiplier.

This returns the mat44 product of the a and b<sup>T</sup>.

Link to this function

orient(arg1, forward, up)

View Source
@spec orient(vec3(), vec3(), vec3()) :: mat44()

Creates a rigid local-to-world transform at position, looking along forward.

Uses a right-handed basis: local -Z follows forward, local +X points right, and local +Y follows the component of up perpendicular to forward. Both direction inputs are normalized internally; up is a roll hint and need not be perpendicular to forward.

Apply with transform_point/2 or transform_vector/2. The translation is position, so the local origin maps to position. For a camera view matrix (world-to-camera), use look_at/3.

Raises ArithmeticError for a zero direction or when the cross product of the normalized forward and up directions has length at most 1.0e-12.

Examples

iex> pose = Graphmath.Mat44.orient({2.0, 3.0, 4.0}, {0.0, 0.0, -1.0}, {0.0, 1.0, 0.0})
iex> Graphmath.Mat44.transform_point(pose, {1.0, 2.0, -3.0})
{3.0, 5.0, 1.0}
Link to this function

ortho(x_min, x_max, y_min, y_max, near, far)

View Source
@spec ortho(float(), float(), float(), float(), float(), float()) :: mat44()

Creates a right-handed orthographic projection for row vectors.

Maps X bounds x_min and x_max to -1 and +1, and Y bounds y_min and y_max to -1 and +1. The camera looks down -Z: eye-space z = -near maps to depth -1, and z = -far maps to depth +1 (the OpenGL convention).

Each pair of bounds must have distinct endpoints; equal endpoints raise ArithmeticError. Reversed bounds flip the corresponding axis. Unlike perspective/4, near and far may be zero or negative, allowing volumes that extend behind the eye.

Preserves the homogeneous coordinate, so transform_point/2 can apply this projection directly. With apply_left/2, a point's output w remains 1.

Examples

iex> projection = Graphmath.Mat44.ortho(-2.0, 6.0, -4.0, 4.0, 1.0, 3.0)
iex> Graphmath.Mat44.transform_point(projection, {2.0, 0.0, -2.0})
{0.0, 0.0, 0.0}
Link to this function

perspective(fov_y, aspect, near, far)

View Source
@spec perspective(float(), float(), float(), float()) :: mat44()

Creates a right-handed perspective projection for row vectors.

fov_y is the vertical field of view in radians, aspect is width / height, and near and far are positive distances along the camera's -Z direction. Requires 0 < fov_y < pi, aspect > 0, and 0 < near < far. Invalid parameters raise ArithmeticError.

Maps the near and far planes to normalized device depths -1 and +1, respectively, following the OpenGL depth convention. Apply with apply_left/2 to a homogeneous point {x, y, z, 1.0}, then divide the first three output coordinates by the fourth (w = -z). No clipping or division is performed by this constructor. transform_point/2 discards w and is unsuitable for completing a perspective projection.

Examples

iex> projection = Graphmath.Mat44.perspective(:math.pi() / 2, 1.0, 1.0, 3.0)
iex> {x, y, z, w} = Graphmath.Mat44.apply_left({0.0, 0.0, -1.0, 1.0}, projection)
iex> {x / w, y / w, z / w}
{0.0, 0.0, -1.0}
@spec round(mat44(), 0..15) :: mat44()

round( a, sigfigs ) rounds every element of a mat44 to some number of decimal places.

a is the mat44 to round.

sigfigs is an integer on [0,15] of the number of decimal places to round to.

This returns a mat44 which is the result of rounding a.

@spec row0(mat44()) :: vec4()

row0( a ) selects the first row of a mat44.

a is the mat44 to take the first row of.

This returns a vec4 representing the first row of a.

@spec row1(mat44()) :: vec4()

row1( a ) selects the second row of a mat44.

a is the mat44 to take the second row of.

This returns a vec4 representing the second row of a.

@spec row2(mat44()) :: vec4()

row2( a ) selects the third row of a mat44.

a is the mat44 to take the third row of.

This returns a vec4 representing the third row of a.

@spec row3(mat44()) :: vec4()

row3( a ) selects the fourth row of a mat44.

a is the mat44 to take the fourth row of.

This returns a vec4 representing the fourth row of a.

@spec scale(mat44(), float()) :: mat44()

scale( a, k ) scales every element in a mat44 by a coefficient k.

a is the mat44 to scale.

k is the float to scale by.

This returns a mat44 a scaled element-wise by k.

Link to this function

submatrix(arg, int1, int2)

View Source
@spec submatrix(mat44(), 0..3, 0..3) :: Graphmath.Mat33.mat33()

Returns the Graphmath.Mat33 obtained by deleting row i and column j.

The remaining entries retain their row-major order. Indices are zero-based integers from 0 through 3; invalid indices raise FunctionClauseError.

This returns a matrix. Its determinant is the corresponding scalar minor.

@spec subtract(mat44(), mat44()) :: mat44()

subtract(a,b) subtracts one mat44 from another mat44.

a is the minuend.

b is the subtraherd.

This returns a mat44 formed by the element-wise subtraction of b from a.

@spec trace(mat44()) :: float()

Returns the trace, the sum of the diagonal entries.

Link to this function

transform_point(arg1, arg2)

View Source
@spec transform_point(mat44(), vec3()) :: vec3()

Transforms a 3D point {x, y, z} using the row-vector product {x, y, z, 1.0} a.

Returns the first three coordinates, including the effect of translation. Use with 3D affine matrices. No perspective division is performed. Use apply_left/2 to supply and retain all four coordinates explicitly.

Link to this function

transform_vector(arg1, arg2)

View Source
@spec transform_vector(mat44(), vec3()) :: vec3()

Transforms a 3D direction {x, y, z} using the row-vector product {x, y, z, 0.0} a.

Returns the first three coordinates. The zero homogeneous coordinate excludes translation; rotations, scales, reflections and shears still affect the vector. Use apply_left/2 to supply and retain all four coordinates explicitly.

@spec zero() :: mat44()

zero() creates a zeroed mat44.

This returns a zeroed mat44.