Vectors describe positions, directions, and velocities. Use them to move objects, aim at a target, or measure the distance between points.
Add a velocity vector to a position to move an object. Velocity has both a direction and a speed; the example below uses it to fire bullets toward a touch.
Shooting bullets toward a touch
function setup()
bullets = {}
origin = vec2(WIDTH/2, HEIGHT/2)
end
function draw()
background(20, 25, 35)
-- Move and draw each bullet
for i = #bullets, 1, -1 do
local b = bullets[i]
b.pos = b.pos + b.vel * DeltaTime
fill(255, 220, 50)
ellipse(b.pos.x, b.pos.y, 8, 8)
-- Remove once off-screen
if b.pos.x < 0 or b.pos.x > WIDTH or
b.pos.y < 0 or b.pos.y > HEIGHT then
table.remove(bullets, i)
end
end
-- Draw turret
fill(100, 180, 255)
ellipse(origin.x, origin.y, 28, 28)
end
function touched(touch)
if touch.state == BEGAN then
local dir = (vec2(touch.x, touch.y) - origin):normalized()
table.insert(bullets, {
pos = vec2(origin.x, origin.y),
vel = dir * 600 -- 600 pixels per second
})
end
endSubtracting two positions gives a direction vector. :normalized() scales it to length 1 so that multiplying by 600 always produces the same speed, no matter how far away the touch was.
:rotate(angleRadians) rotates a vec2 by an angle. Rotating an offset vector each frame and adding it to a center point produces natural circular motion — no trigonometry functions needed.
Objects orbiting a center point
function setup()
center = vec2(WIDTH/2, HEIGHT/2)
moons = {
{ offset = vec2(140, 0), speed = 1.2, size = 18, r = 255, g = 100, b = 100 },
{ offset = vec2(220, 0), speed = 0.7, size = 24, r = 100, g = 180, b = 255 },
{ offset = vec2( 80, 0), speed = 2.4, size = 12, r = 120, g = 255, b = 140 },
}
end
function draw()
background(10, 12, 20)
-- Central body
fill(255, 200, 80)
ellipse(center.x, center.y, 40, 40)
for _, moon in ipairs(moons) do
moon.offset = moon.offset:rotate(moon.speed * DeltaTime)
local pos = center + moon.offset
-- Draw orbit ring
stroke(60, 65, 80)
strokeWidth(1)
noFill()
ellipse(center.x, center.y, moon.offset:length() * 2, moon.offset:length() * 2)
-- Draw moon
noStroke()
fill(moon.r, moon.g, moon.b)
ellipse(pos.x, pos.y, moon.size, moon.size)
end
endEach moon stores only its offset from the center. Rotating that offset by speed * DeltaTime radians per frame moves it around the orbit automatically.
The dot product of two normalized vectors equals cos(θ) where θ is the angle between them. This makes it a fast way to ask “is this target within my field of view?” without computing any angles.
dot == 1 → same direction (0°)dot == 0 → perpendicular (90°)dot == -1 → opposite (180°)If you want a 120° cone (60° either side of forward), pre-compute math.cos(math.pi/3) and compare the dot product against it.
Guard with a cone of vision
function setup()
guardPos = vec2(WIDTH/2, HEIGHT/2)
guardDir = vec2(0, 1) -- facing up
fovCos = math.cos(math.pi / 3) -- 60° half-angle → 120° total FOV
sightDist = 220
end
function draw()
background(25, 30, 40)
-- Guard slowly rotates
guardDir = guardDir:rotate(0.6 * DeltaTime)
local touchPos = vec2(CurrentTouch.x, CurrentTouch.y)
local toTouch = touchPos - guardPos
local dist = toTouch:length()
-- Dot product test: within range AND within cone?
local spotted = dist < sightDist and dist > 1 and
guardDir:dot(toTouch / dist) >= fovCos
-- Draw sight cone (two edge lines)
local left = guardDir:rotate( math.pi/3) * sightDist
local right = guardDir:rotate(-math.pi/3) * sightDist
stroke(spotted and color(255, 80, 80, 120) or color(80, 200, 80, 80))
strokeWidth(1)
fill(spotted and color(255, 80, 80, 30) or color(80, 200, 80, 20))
-- draw the cone as two lines from guard
line(guardPos.x, guardPos.y, guardPos.x + left.x, guardPos.y + left.y)
line(guardPos.x, guardPos.y, guardPos.x + right.x, guardPos.y + right.y)
-- Draw guard
noStroke()
fill(150, 190, 255)
ellipse(guardPos.x, guardPos.y, 28, 28)
-- Draw touch target
fill(spotted and color(255, 80, 80) or color(80, 255, 80))
ellipse(touchPos.x, touchPos.y, 20, 20)
fill(255)
fontSize(20)
text(spotted and "SPOTTED!" or "hidden", WIDTH/2, 50)
endMove your finger around the screen. The guard rotates slowly — watch for the moment the dot product crosses the threshold and the target is detected.
:lerp(target, t) blends between two vectors. Calling it every frame with a small t (proportional to DeltaTime) makes an object ease toward its target — the further away it is, the faster it moves, gradually slowing as it closes in.
Use this for a following camera, a homing enemy, or a smoothly changing health bar.
Camera that lags behind the player
function setup()
playerPos = vec2(WIDTH/2, HEIGHT/2)
cameraPos = vec2(WIDTH/2, HEIGHT/2)
end
function draw()
-- Player snaps to touch
if CurrentTouch.state ~= ENDED then
playerPos = playerPos:lerp(
vec2(CurrentTouch.x, CurrentTouch.y), 12 * DeltaTime)
end
-- Camera lazily follows
cameraPos = cameraPos:lerp(playerPos, 4 * DeltaTime)
background(20, 28, 38)
-- World grid, offset by camera
local offset = vec2(WIDTH/2, HEIGHT/2) - cameraPos
stroke(45, 55, 70)
strokeWidth(1)
for gx = -8, 8 do
for gy = -8, 8 do
local wx = gx * 70 + offset.x
local wy = gy * 70 + offset.y
line(wx - 6, wy, wx + 6, wy)
line(wx, wy - 6, wx, wy + 6)
end
end
-- Player is always drawn at the screen center (the camera follows them)
noStroke()
fill(100, 220, 110)
ellipse(WIDTH/2, HEIGHT/2, 26, 26)
endThe factor 4 DeltaTime controls lag — increase it to snap the camera closer, decrease it for more cinematic drift. The player uses 12 DeltaTime to stay responsive.
:reflect(normal) changes a direction as if it had bounced off a surface. Use it to make a ball bounce off walls.
The normal always points away from the surface: vec2(1, 0) for a left wall, vec2(0, 1) for a floor, and so on.
Ball bouncing around the screen
function setup()
pos = vec2(WIDTH/2, HEIGHT/2)
vel = vec2(280, 350)
radius = 22
end
function draw()
background(18, 22, 32)
pos = pos + vel * DeltaTime
-- Bounce off left/right
if pos.x - radius < 0 then
pos.x = radius
vel = vel:reflect(vec2(1, 0))
elseif pos.x + radius > WIDTH then
pos.x = WIDTH - radius
vel = vel:reflect(vec2(-1, 0))
end
-- Bounce off bottom/top
if pos.y - radius < 0 then
pos.y = radius
vel = vel:reflect(vec2(0, 1))
elseif pos.y + radius > HEIGHT then
pos.y = HEIGHT - radius
vel = vel:reflect(vec2(0, -1))
end
-- Draw shadow
fill(0, 0, 0, 60)
ellipse(pos.x + 6, pos.y - 6, radius * 2, radius * 2)
-- Draw ball
fill(255, 100, 60)
ellipse(pos.x, pos.y, radius * 2, radius * 2)
endThe same pattern works for angled surfaces — just use the surface’s perpendicular as the normal. A 45° ramp has normal vec2(1, 1):normalized().
:distance() measures the distance between two positions. Compare it with a radius to check whether a player is close enough to pick up a coin.
Collecting coins
function setup()
playerPos = vec2(WIDTH/2, HEIGHT/2)
coins = {}
for i = 1, 12 do
table.insert(coins, vec2(
math.random(60, WIDTH - 60),
math.random(60, HEIGHT - 60)))
end
score = 0
end
function draw()
background(22, 28, 38)
-- Player follows touch
if CurrentTouch.state ~= ENDED then
playerPos = playerPos:lerp(
vec2(CurrentTouch.x, CurrentTouch.y), 10 * DeltaTime)
end
-- Collect any coin within range
for i = #coins, 1, -1 do
if playerPos:distance(coins[i]) < 38 then
table.remove(coins, i)
score = score + 1
end
end
-- Draw coins
fill(255, 200, 40)
for _, c in ipairs(coins) do
ellipse(c.x, c.y, 22, 22)
end
-- Draw player
fill(80, 160, 255)
ellipse(playerPos.x, playerPos.y, 30, 30)
fill(255)
fontSize(22)
text("Score: " .. score, WIDTH/2, HEIGHT - 40)
if #coins == 0 then
fontSize(36)
text("All collected!", WIDTH/2, HEIGHT/2)
end
endFor performance with many objects, compare :distance2() against the squared radius instead — it skips the square root entirely.
vec2, vec3 and vec4 support swizzling, which lets you read or write multiple components in any order using xyzw (or equivalently rgba) notation.
v1 = vec4(1, 2, 3, 4)
v2 = vec3(5, 6, 7)
-- Reading — any combination of components
print(v1.wzyx) -- prints '(4.0, 3.0, 2.0, 1.0)'
print(v1.zzz) -- prints '(3.0, 3.0, 3.0)'
print(v2.xz) -- prints '(5.0, 7.0)'
-- Writing — assign to a subset of components at once
v1.yx = vec2(5, 6) -- v1 is now '(6.0, 5.0, 3.0, 4.0)'
v1.xyz = v2.yzx -- v1 is now '(6.0, 7.0, 5.0, 4.0)'Swizzling is particularly useful when working with shader code or converting between vec3 positions and vec4 homogeneous coordinates:
local pos3 = vec3(1, 2, 3)
-- Lift to homogeneous coords (w = 1 for a position)
local pos4 = vec4(pos3.x, pos3.y, pos3.z, 1)
-- Extract just the XZ plane (useful for flat-ground games)
local flat = pos3.xz -- returns vec2(1, 3)
v = vec2(1, 2)
v = vec2(1) -- set both x and y to 1
v = vec2() -- set both x and y to 0
This type represents a 2D vector. Most mathematical operators such as equality, addition, subtraction, multiplication and division are provided, so you can use vec2 data types similarly to how you use numerical types.
| x | number. Initial x value of the vector |
| y | number. Initial y value of the vector |
vec2.x
The x component of this vector
vec2.y
The y component of this vector
vec2.min(v1, v2)
Return a vec2 containing the component-wise minimum of two vectors
| v1 | vec2. The first vector |
| v2 | vec2. The second vector |
vec2 |
A new vec2 with the minimum of each component |
vec2.max(v1, v2)
Return a vec2 containing the component-wise maximum of two vectors
| v1 | vec2. The first vector |
| v2 | vec2. The second vector |
vec2 |
A new vec2 with the maximum of each component |
vec2.length
The length of this vector
vec2.length2
The squared length of this vector
vec2:normalize()
Normalize this vector in-place
vec2:normalized()
Return a normalized copy of this vector
vec2 |
A normalized copy of this vector |
vec2:dot(v)
Perform a scalar dot product with another vector and return the result
| v | vec2. The other vector |
number |
The scalar dot product |
vec2:distance(v)
Calculate the Euclidean distance to another vector
| v | vec2. The other vector |
number |
The distance between the two vectors |
vec2:distance2(v)
Calculate the squared Euclidean distance to another vector
| v | vec2. The other vector |
number |
The squared distance between the two vectors |
vec2:reflect(normal)
Reflect this vector about a normal
| normal | vec2. The normal vector to reflect about |
vec2 |
The reflected vector |
vec2:refract(normal, ior)
Refract this vector through a surface with a given index of refraction
| normal | vec2. The surface normal |
| ior | number. The index of refraction |
vec2 |
The refracted vector |
vec2:lerp(v, t)
Interpolate this vector with another by a given factor
| v | vec2. The target vector |
| t | number. The interpolation factor (typically between 0 and 1) |
vec2 |
The interpolated vector |
vec2:abs()
Return a copy of this vector with component-wise absolute values
vec2 |
A copy with all components made positive |
vec2:unpack()
Unpack this vector as individual number values
| value | The x and y components as separate values |
vec2:cross(v)
Compute the 2D cross product (perp dot product) with another vector
| v | vec2. The other vector |
number |
The scalar cross product result |
vec2:rotate(angleRadians)
Rotate this vector by a given angle in radians
| angleRadians | number. The angle of rotation in radians |
vec2 |
The rotated vector |
vec2:rotate90()
Rotate this vector by 90 degrees
vec2 |
The rotated vector |
vec2:angleBetween(v)
Calculate the oriented angle between this vector and another, between -pi and pi
| v | vec2. The other vector |
number |
The oriented angle in radians between -pi and pi |
vec3(x, y, z)
Create a new vec3 by setting each component individually
| x | number. The x component |
| y | number. The y component |
| z | number. The z component |
vec3 |
vec3()
Create a new vec3 by setting all components to zero
vec3 |
vec3(v)
Create a new vec3 by setting all components to the same value
| v | number. The x, y and z values |
vec3 |
vec3.min(v1, v2)
Return a vec3 containing the component-wise minimum of two vectors
| v1 | vec3. The first vector |
| v2 | vec3. The second vector |
vec3 |
A new vec3 with the minimum of each component |
vec3.max(v1, v2)
Return a vec3 containing the component-wise maximum of two vectors
| v1 | vec3. The first vector |
| v2 | vec3. The second vector |
vec3 |
A new vec3 with the maximum of each component |
vec3.x
The x component of this vector
vec3.y
The y component of this vector
vec3.z
The z component of this vector
vec3.length
The length of this vector
vec3.length2
The squared length of this vector
vec3:normalize()
Normalize this vector in-place
vec3:normalized()
Return a normalized copy of this vector
vec3 |
A normalized copy of this vector |
vec3:dot(v)
Perform a scalar dot product with another vector and return the result
| v | vec3. The other vector |
number |
The scalar dot product |
vec3:cross(v)
Perform a cross product with another vec3 and return the result
| v | vec3. The other vector |
vec3 |
A vector perpendicular to both input vectors |
vec3:distance(v)
Calculate the Euclidean distance to another vector
| v | vec3. The other vector |
number |
The distance between the two vectors |
vec3:distance2(v)
Calculate the squared Euclidean distance to another vector
| v | vec3. The other vector |
number |
The squared distance between the two vectors |
vec3:reflect(normal)
Reflect this vector about a normal
| normal | vec3. The normal vector to reflect about |
vec3 |
The reflected vector |
vec3:refract(normal, ior)
Refract this vector through a surface with a given index of refraction
| normal | vec3. The surface normal |
| ior | number. The index of refraction |
vec3 |
The refracted vector |
vec3:lerp(v, t)
Interpolate this vector with another by a given factor
| v | vec3. The target vector |
| t | number. The interpolation factor (typically between 0 and 1) |
vec3 |
The interpolated vector |
vec3:abs()
Return a copy of this vector with component-wise absolute values
vec3 |
A copy with all components made positive |
vec3:unpack()
Unpack this vector as individual number values
| value | The x, y and z components as separate values |
vec4(x)
Create a new vec4 by setting all components to the same value, or each one individually
| x | number. The x component (also used for y, z and w when called with a single argument) |
vec4 |
vec4.min(v1, v2)
Return a vec4 containing the component-wise minimum of two vectors
| v1 | vec4. The first vector |
| v2 | vec4. The second vector |
vec4 |
A new vec4 with the minimum of each component |
vec4.max(v1, v2)
Return a vec4 containing the component-wise maximum of two vectors
| v1 | vec4. The first vector |
| v2 | vec4. The second vector |
vec4 |
A new vec4 with the maximum of each component |
vec4.x
The x component of this vector
vec4.y
The y component of this vector
vec4.z
The z component of this vector
vec4.w
The w component of this vector
vec4.length
The length of this vector
vec4.length2
The squared length of this vector
vec4:normalize()
Normalize this vector in-place
vec4:normalized()
Return a normalized copy of this vector
vec4 |
A normalized copy of this vector |
vec4:dot(v)
Perform a scalar dot product with another vector and return the result
| v | vec4. The other vector |
number |
The scalar dot product |
vec4:distance(v)
Calculate the Euclidean distance to another vector
| v | vec4. The other vector |
number |
The distance between the two vectors |
vec4:distance2(v)
Calculate the squared Euclidean distance to another vector
| v | vec4. The other vector |
number |
The squared distance between the two vectors |
vec4:reflect(normal)
Reflect this vector about a normal
| normal | vec4. The normal vector to reflect about |
vec4 |
The reflected vector |
vec4:refract(normal, ior)
Refract this vector through a surface with a given index of refraction
| normal | vec4. The surface normal |
| ior | number. The index of refraction |
vec4 |
The refracted vector |
vec4:lerp(v, t)
Interpolate this vector with another by a given factor
| v | vec4. The target vector |
| t | number. The interpolation factor (typically between 0 and 1) |
vec4 |
The interpolated vector |
vec4:abs()
Return a copy of this vector with component-wise absolute values
vec4 |
A copy with all components made positive |
vec4:unpack()
Unpack this vector as individual number values
| value | The x, y, z and w components as separate values |
quat()
Create a new quat
quat |
quat.lookRotation(forward, up)
Create a rotation that points in the forward direction, oriented using up
| forward | vec3. The forward direction |
| up | vec3. The up direction used for orientation |
quat |
A quat that points in the forward direction |
quat.fromToRotation(from, to)
Create a rotation that rotates from one direction to another
| from | vec3. The direction to rotate from |
| to | vec3. The direction to rotate to |
quat |
A quat containing the relative rotation from from to to |
quat.angleAxis(angle, axis)
Create a rotation of angle degrees around an axis
| angle | number. The amount of rotation in degrees |
| axis | vec3. The axis of rotation |
quat |
A new quat representing the rotation |
quat.eulerAngles(x, y, z)
Create a rotation from euler angles (yaw, pitch, roll) in degrees
| x | number. The amount of rotation about the x axis (pitch) in degrees |
| y | number. The amount of rotation about the y axis (yaw) in degrees |
| z | number. The amount of rotation about the z axis (roll) in degrees |
quat |
A new quat representing the combined rotation |
quat.x
The x imaginary component
quat.y
The y imaginary component
quat.z
The z imaginary component
quat.w
The scalar (real) component
quat.angles
A set of euler angles (in degrees) that produces the same rotation as this quaternion
Note: euler angles derived from a quaternion are ambiguous and should not be relied upon for smooth interpolation
quat:slerp(q, t)
Spherically interpolate between this quaternion and another
| q | quat. The target quaternion |
| t | number. The interpolation amount (between 0 and 1) |
quat |
A new quat spherically interpolated from this to q by t |
quat:conjugate()
Return the conjugate of this quaternion
quat |
A new quat containing the conjugate (inverse rotation) |
quat:normalize()
Normalize this quaternion in-place
quat:normalized()
Return a normalized copy of this quaternion
quat |
A normalized copy of this quaternion |
mat2
A simple 2x2 matrix. Individual entries can be accessed via a 1-based index
m = mat2(1) -- init with diagonals set to 1
print(m[1]) -- prints '1.0'
mat2()
Create a new mat2: default (identity), diagonal scalar, two vec2 columns, or all 4 entries
mat2 |
mat2:inverse()
Return the inverse of this matrix
mat2 |
The inverse of this matrix |
mat2:transpose()
Return the transpose of this matrix
mat2 |
The transpose of this matrix |
mat2:determinant()
Return the determinant of this matrix
number |
The determinant |
mat2:row(index)
Return the row at a given index
| index | number. The 1-based row index |
vec2 |
The row at the given index |
mat2:column(index)
Return the column at a given index
| index | number. The 1-based column index |
vec2 |
The column at the given index |
mat3
A simple 3x3 matrix. Individual entries can be accessed via a 1-based index
m = mat3(1) -- init with diagonals set to 1
print(m[1]) -- prints '1.0'
mat3()
Create a new mat3: default (identity), diagonal scalar, three vec3 columns, or all 9 entries
mat3 |
mat3:inverse()
Return the inverse of this matrix
mat3 |
The inverse of this matrix |
mat3:transpose()
Return the transpose of this matrix
mat3 |
The transpose of this matrix |
mat3:determinant()
Return the determinant of this matrix
number |
The determinant |
mat3:row(index)
Return the row at a given index
| index | number. The 1-based row index |
vec3 |
The row at the given index |
mat3:column(index)
Return the column at a given index
| index | number. The 1-based column index |
vec3 |
The column at the given index |
mat4
A 4x4 matrix typically used for 3D homogeneous transformations. Individual entries can be accessed via a 1-based index
m = mat4(1) -- init with diagonals set to 1
print(m[1]) -- prints '1.0'
mat4()
Create a new mat4: default (identity), diagonal scalar, four vec4 columns, or all 16 entries
mat4 |
mat4.lookAt(eye, center, up)
Create a look-at view matrix
| eye | vec3. The position of the camera |
| center | vec3. The point to look at |
| up | vec3. The up direction |
mat4 |
A view matrix looking from eye toward center |
mat4.lookAt(matrix, eye, center, up)
Apply a look-at transform to an existing matrix
| matrix | mat4. The matrix to apply the transform to |
| eye | vec3. The position of the camera |
| center | vec3. The point to look at |
| up | vec3. The up direction |
mat4 |
The transformed matrix |
mat4.orbit(origin, distance, x, y)
Create an orbit view matrix centered on a point
| origin | vec3. The point to orbit around |
| distance | number. The distance from the origin |
| x | number. The horizontal orbit angle in degrees |
| y | number. The vertical orbit angle in degrees |
mat4 |
An orbit view matrix |
mat4.orbit(matrix, origin, distance, x, y)
Apply an orbit transform to an existing matrix
| matrix | mat4. The matrix to apply the transform to |
| origin | vec3. The point to orbit around |
| distance | number. The distance from the origin |
| x | number. The horizontal orbit angle in degrees |
| y | number. The vertical orbit angle in degrees |
mat4 |
The transformed matrix |
mat4.ortho(left, right, top, bottom, near, far)
Create an orthographic projection matrix
| left | number. The left clipping plane |
| right | number. The right clipping plane |
| top | number. The top clipping plane |
| bottom | number. The bottom clipping plane |
| near | number, optional. The near clipping plane (optional) |
| far | number, optional. The far clipping plane (optional) |
mat4 |
An orthographic projection matrix |
mat4.perspective(fovy, aspect, near, far)
Create a perspective projection matrix
| fovy | number. The vertical field of view in degrees |
| aspect | number. The aspect ratio (width / height) |
| near | number. The near clipping plane distance |
| far | number. The far clipping plane distance |
mat4 |
A perspective projection matrix |
mat4.rotate(angle, axis)
Create a rotation matrix
| angle | number. The rotation angle in degrees |
| axis | vec3. The axis of rotation |
mat4 |
A rotation matrix |
mat4.rotate(matrix, angle, axis)
Apply a rotation transform to an existing matrix
| matrix | mat4. The matrix to rotate |
| angle | number. The rotation angle in degrees |
| axis | vec3. The axis of rotation |
mat4 |
The rotated matrix |
mat4:inverse()
Return the inverse of this matrix
mat4 |
The inverse of this matrix |
mat4:transpose()
Return the transpose of this matrix
mat4 |
The transpose of this matrix |
mat4:determinant()
Return the determinant of this matrix
number |
The determinant |
mat4:row(index)
Return the row at a given index
| index | number. The 1-based row index |
vec4 |
The row at the given index |
mat4:column(index)
Return the column at a given index
| index | number. The 1-based column index |
vec4 |
The column at the given index |
b = bounds.aabb(vec3(-1, -1, -1), vec3(1, 1, 1))
An axis-aligned bounding box defined by minimum and maximum corner points
| min | vec3. The minimum corner of the bounding box |
| max | vec3. The maximum corner of the bounding box |
aabb.min
The minimum corner of this bounding box
aabb.max
The maximum corner of this bounding box
aabb.size
The size (width, height, depth) of this bounding box
aabb.center
The center point of this bounding box
aabb:set(min, max)
Set the minimum and maximum corners of this bounding box
| min | vec3. The new minimum corner |
| max | vec3. The new maximum corner |
aabb:translate(offset)
Translate this bounding box by an offset
| offset | vec3. The translation offset |
Move, rotate, and scale drawings, or change the camera view and projection. Use matrix.push() to save the current matrices and matrix.pop() to restore them.
Note
Codea 4.x uses a left-handed, +Z-forward coordinate system for 3D rendering. When matrix.perspective() is active, the camera is at the origin looking toward +Z. Objects must be translated to positive Z to appear in front of the camera. This is the opposite of the -Z-forward convention used in OpenGL and Codea 3.x Craft.
matrix.push()
Push the current matrix onto the stack, saving the current transform
matrix.pop()
Pop the matrix from the stack, restoring the previous transform
matrix.reset()
Reset the current matrix to the identity matrix
matrix.model()
Gets the model matrix used to transform from local to world space
matrix.model(matrix)
Sets the model matrix used to transform from local to world space
| matrix | mat4. Matrix to install as the current transform. |
matrix.view()
Gets the view matrix used to transform from world to view space
matrix.view(matrix)
Sets the view matrix used to transform from world to view space (generally controlled by cameras)
| matrix | mat4. Matrix to install as the current transform. |
matrix.projection()
Gets the projection matrix used for final projection
matrix.projection(matrix)
Sets the projection matrix, used for final projection (i.e. ortho and perspective projection)
| matrix | mat4. Matrix to install as the current transform. |
matrix.transform2d(x, y, sx, sy, r)
Combine translation, scale, and rotation relative to the current matrix. Save it before entering a child orbit and restore it afterwards so sibling objects remain independent.
Apply a generic 2D transform to the model matrix
| x | number. Translation or scale component along the x axis, according to the operation. |
| y | number. Translation or scale component along the y axis, according to the operation. |
| sx | number, optional, default 1. Scale factor along the corresponding axis; 1 leaves that axis unchanged. |
| sy | number, optional, default 1. Scale factor along the corresponding axis; 1 leaves that axis unchanged. |
| r | number, optional, default 0. Rotation in degrees. |
Download project Open in Codea to run this example.
-- Learn to Codea
-- The Matrix
function setup()
end
function draw()
background(25, 25, 25)
local r = time.elapsed * 15
-- The matrix module gives you control over positioning of drawing commands
-- By changing the current matrix, this changes where drawing occurs
-- The easiest way to think of this is that the current matrix represents
-- the origin of the screen
-- matrix.translate(WIDTH/2, HEIGHT/2) - move drawing to the middle of the screen
-- You can also rotate and scale drawing
-- Transforming the matrix combines with any previous transformation
-- i.e. matrix.translate(WIDTH/2, HEIGHT/2).translate(100, 100)
-- Drawing will now originate 100 pixels up and to the right of the middle of the screen
-- You can also use matrix.push()/pop() to save and load the current matrix transform
-- similar to how style.push()/pop() is used
-- matrix.transform2d()/transform3d() allows you to apply full transformations in one
-- command for convenience
-- If you need to clear all current transformations you can use matrix.reset()
-- You can also create a mat4 (4x4 matrix) type and use this with matrix.get()/set()
-- There are additional commands for adjusting view and projection matrices
-- matrix.ortho() - use orthographic (2D) projection
-- matrix.perspective() - use perspective (3D) projection
-- matrix.projection(m) - use a custom projection matrix
-- matrix.view(m) - use a custom view matrix
-- Move the origin to the center of the screen and rotate over time
matrix.transform2d(WIDTH/2, HEIGHT/2, 1, 1, r)
ellipse(0, 0, 50)
-- Draw 6 satellites that orbit and rotate the center
for i = 1, 6 do
-- Accumulate rotations
matrix.rotate(360/6)
-- Use additional push and transform to create a recursive hierarchy
matrix.push().transform2d(math.min(WIDTH, HEIGHT) * 0.28, 0, 1, 1, r * 1.25)
ellipse(0, 0, 25)
-- Additional mini satellites that orbit the current origin
for i = 1, 6 do
matrix.rotate(360/6)
matrix.push().transform2d(math.min(WIDTH, HEIGHT) * 0.075, 0)
ellipse(0, 0, 15)
matrix.pop()
end
-- Pop here is crucial to let the next satellite transform relative to its parent
matrix.pop()
end
end
function touched(touch)
end
matrix.transform3d(x, y, z, sx, sy, sz, rx, ry, rz)
Apply a generic 3D transform to the model matrix
| x | number. Translation or scale component along the x axis, according to the operation. |
| y | number. Translation or scale component along the y axis, according to the operation. |
| z | number. Translation or scale component along the z axis, according to the operation. |
| sx | number. Scale factor along the corresponding axis; 1 leaves that axis unchanged. |
| sy | number. Scale factor along the corresponding axis; 1 leaves that axis unchanged. |
| sz | number. Scale factor along the corresponding axis; 1 leaves that axis unchanged. |
| rx | number. Rotation in degrees. |
| ry | number. Rotation in degrees. |
| rz | number. Rotation in degrees. |
matrix.translate(x, y, z)
Translate the current model matrix
| x | number. Translation or scale component along the x axis, according to the operation. |
| y | number. Translation or scale component along the y axis, according to the operation. |
| z | number, optional. Translation or scale component along the z axis, according to the operation. |
matrix.rotate(quat)
| quat | quat. Quaternion describing the rotation. |
matrix.rotate(angle, x, y, z)
Rotate the current model matrix
| angle | number. Rotation in degrees. |
| x | number. Component of the axis to rotate around. |
| y | number. Component of the axis to rotate around. |
| z | number. Component of the axis to rotate around. |
matrix.scale(x, y, z)
Scale the current model matrix
| x | number. Translation or scale component along the x axis, according to the operation. |
| y | number. Translation or scale component along the y axis, according to the operation. |
| z | number, optional. Translation or scale component along the z axis, according to the operation. |
matrix.ortho()
Set the projection matrix to ortho using the device screen settings (i.e. coordinates range [0, 0] to [WIDTH, HEIGHT])
matrix.ortho(height)
Sets an orthographic projection matrix height units high, using the aspect ratio of the screen to set the width
| height | number. The height of the orthographic projection |
matrix.ortho(left, right, bottom, top, near, far)
Sets an orthographic projection matrix using the supplied edge values
| left | number. Position of the left clipping plane. |
| right | number. Position of the right clipping plane. |
| bottom | number. Position of the bottom clipping plane. |
| top | number. Position of the top clipping plane. |
| near | number, optional. Position of the near clipping plane. |
| far | number, optional. Position of the far clipping plane. |
matrix.perspective(fov, aspect, near, far)
Sets a perspective projection matrix
| fov | number. Vertical field of view in degrees. |
| aspect | number. Viewport width divided by height. |
| near | number. Position of the near clipping plane. |
| far | number. Position of the far clipping plane. |