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
Functions
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Returns the determinant of a.
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.
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
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}
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 }.
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.
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>.
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}
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}
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}
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.
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.
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.
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.
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.
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.
@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.
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.
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.
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.
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.