Wiki

Clone wiki

Core / matrix

Back to Beyond the Codea in-app reference


FunctionIconType-Small.png matrix() function

Introduction

The 'Vector' chapter of Codea's in-app reference documents the matrix() function. The function is returns a userdata value that is a four-dimensional square matrix column-major matrix.

-- ( a11 a12 a13 a14 )
-- (                 )
-- ( a21 a22 a23 a24 )
-- (                 )
-- ( a31 a32 a33 a34 )
-- (                 )
-- ( a41 a42 a43 a44 )

myMatrix = matrix(
    a11, a21, a31, a41,
    a12, a22, a32, a42,
    a13, a23, a33, a43,
    a14, a24, a34, a44)

Scale

For homogenous co-ordinates, a scaling operation is represented by the matrix:

-- (  sx   0   0   0 )
-- (                 )
-- (   0  sy   0   0 )
-- (                 )
-- (   0   0  sz   0 )
-- (                 )
-- (   0   0   0   1 )

sx, sy, sz = 10, 20, 30
myMatrix = matrix(
   sx,  0,  0,  0,
    0, sy,  0,  0,
    0,  0, sz,  0,
    0,  0,  0,  1)
print(myMatrix == matrix():scale(sx, sy, sz)) -- Output: true

Translation

For homogenous co-ordinates, a translation operation is represented by the matrix:

-- (   1   0   0  tx )
-- (                 )
-- (   0   1   0  ty )
-- (                 )
-- (   0   0   1  tz )
-- (                 )
-- (   0   0   0   1 )

tx, ty, tz = 10, 20, 30
myMatrix = matrix(
    1,  0,  0,  0,
    0,  1,  0,  0,
    0,  0,  1,  0,
    tx, ty, tz, 1)
print(myMatrix == matrix():translate(tx, ty, tz)) -- Output: true

Rotation

For homogenous co-ordinates, a rotation operation is represented by the matrix:

-- To rotate angle a about the axis defined by unit vector (nx, ny, nz)
-- c = cos(a), s = sin(a)
--
-- ( nx * nx * (1-c) + c       ny * nx * (1-c) - nz * s  nz * nx * (1-c) + ny * s  0 )
-- (                                                                                 )
-- ( nx * ny * (1-c) + nz * s  ny * ny * (1-c) + c       nz * ny * (1-c) - nx * s  0 )
-- (                                                                                 )
-- ( nx * nz * (1-c) - ny * s  ny * nz * (1-c) + nx * s  nz * nz * (1-c) + c       0 )
-- (                                                                                 )
-- ( 0                         0                         0                         1 )

-- Random normal
local theta = 2 * math.pi * math.random()
local phi = math.pi * (2 * math.random() - 1)
local nx = math.sin(theta) * math.cos(phi)
local ny = math.cos(theta) * math.cos(phi)
local nz = math.sin(phi)

local angle = 30

local a = math.rad(angle)
local c, s = math.cos(a), math.sin(a)
local omc = 1 - c
myMatrix = matrix(
nx * nx * omc + c     , nx * ny * omc + nz * s, nx * nz * omc - ny * s, 0,
ny * nx * omc - nz * s, ny * ny * omc + c     , ny * nz * omc + nx * s, 0,
nz * nx * omc + ny * s, nz * ny * omc - nx * s, nz * nz * omc + c     , 0,
0                     , 0                     , 0                     , 1)
print(myMatrix == matrix():rotate(angle, nx, ny, nz)) -- Output: true (mostly)
print(myMatrix)
print(matrix():rotate(angle, nx, ny, nz))

Updated