# Vector Math

Vector, matrix and mathematical types

[Reference](index.md)

<a id="section-Guides"></a>

## Guides

<a id="Using-Vectors"></a>

### Using Vectors

Vectors describe positions, directions, and velocities. Use them to move objects, aim at a target, or measure the distance between points.

## Moving Along a Vector

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**

```lua
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
end
```

Subtracting 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.

## Rotating Vectors

`: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**

```lua
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
end
```

Each moon stores only its offset from the center. Rotating that offset by `speed * DeltaTime` radians per frame moves it around the orbit automatically.

## Dot Product — Field of View

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**

```lua
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)
end
```

Move your finger around the screen. The guard rotates slowly — watch for the moment the dot product crosses the threshold and the target is detected.

## Smooth Following with Lerp

`: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**

```lua
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)
end
```

The 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.

## Reflecting Vectors — Bouncing Ball

`: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**

```lua
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)
end
```

The same pattern works for angled surfaces — just use the surface’s perpendicular as the normal. A 45° ramp has normal `vec2(1, 1):normalized()`.

## Proximity Detection

`: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**

```lua
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
end
```

For performance with many objects, compare `:distance2()` against the squared radius instead — it skips the square root entirely.

## Vector Swizzling

`vec2`, `vec3` and `vec4` support swizzling, which lets you read or write multiple components in any order using `xyzw` (or equivalently `rgba`) notation.

```lua
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:

```lua
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)
```

<a id="section-2D-Vectors"></a>

## 2D Vectors

<a id="vec2"></a>

### vec2

```lua
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.

get or set the x component

#### Parameters

- **x** (number): Initial x value of the vector
- **y** (number): Initial y value of the vector

<a id="vec2.x"></a>

### vec2.x

```lua
vec2.x
```

The x component of this vector

get or set the x component

<a id="vec2.y"></a>

### vec2.y

```lua
vec2.y
```

The y component of this vector

get or set the y component

<a id="vec2.min"></a>

### vec2.min(v1, v2)

```lua
vec2.min(v1, v2)
```

Return a `vec2` containing the component-wise minimum of two vectors

return the component-wise minimum of two vectors

#### Parameters

- **v1** (vec2): The first vector
- **v2** (vec2): The second vector

#### Returns

- **vec2**: A new vec2 with the minimum of each component

<a id="vec2.max"></a>

### vec2.max(v1, v2)

```lua
vec2.max(v1, v2)
```

Return a `vec2` containing the component-wise maximum of two vectors

return the component-wise maximum of two vectors

#### Parameters

- **v1** (vec2): The first vector
- **v2** (vec2): The second vector

#### Returns

- **vec2**: A new vec2 with the maximum of each component

<a id="vec2.length"></a>

### vec2.length

```lua
vec2.length
```

The length of this vector

get the length of this vector

<a id="vec2.length2"></a>

### vec2.length2

```lua
vec2.length2
```

The squared length of this vector

get the squared length of this vector

<a id="vec2:normalize"></a>

### vec2:normalize()

```lua
vec2:normalize()
```

Normalize this vector in-place

normalize this vector

<a id="vec2:normalized"></a>

### vec2:normalized()

```lua
vec2:normalized()
```

Return a normalized copy of this vector

return a normalized copy of this vector

#### Returns

- **vec2**: A normalized copy of this vector

<a id="vec2:dot"></a>

### vec2:dot(v)

```lua
vec2:dot(v)
```

Perform a scalar dot product with another vector and return the result

calculate the dot product with another vector

#### Parameters

- **v** (vec2): The other vector

#### Returns

- **number**: The scalar dot product

<a id="vec2:distance"></a>

### vec2:distance(v)

```lua
vec2:distance(v)
```

Calculate the Euclidean distance to another vector

calculate the distance to another vector

#### Parameters

- **v** (vec2): The other vector

#### Returns

- **number**: The distance between the two vectors

<a id="vec2:distance2"></a>

### vec2:distance2(v)

```lua
vec2:distance2(v)
```

Calculate the squared Euclidean distance to another vector

calculate the squared distance to another vector

#### Parameters

- **v** (vec2): The other vector

#### Returns

- **number**: The squared distance between the two vectors

<a id="vec2:reflect"></a>

### vec2:reflect(normal)

```lua
vec2:reflect(normal)
```

Reflect this vector about a normal

reflect this vector about a normal

#### Parameters

- **normal** (vec2): The normal vector to reflect about

#### Returns

- **vec2**: The reflected vector

<a id="vec2:refract"></a>

### vec2:refract(normal, ior)

```lua
vec2:refract(normal, ior)
```

Refract this vector through a surface with a given index of refraction

refract this vector through a normal

#### Parameters

- **normal** (vec2): The surface normal
- **ior** (number): The index of refraction

#### Returns

- **vec2**: The refracted vector

<a id="vec2:lerp"></a>

### vec2:lerp(v, t)

```lua
vec2:lerp(v, t)
```

Interpolate this vector with another by a given factor

linearly interpolate this vector with another

#### Parameters

- **v** (vec2): The target vector
- **t** (number): The interpolation factor (typically between 0 and 1)

#### Returns

- **vec2**: The interpolated vector

<a id="vec2:abs"></a>

### vec2:abs()

```lua
vec2:abs()
```

Return a copy of this vector with component-wise absolute values

return a copy with component-wise absolute values

#### Returns

- **vec2**: A copy with all components made positive

<a id="vec2:unpack"></a>

### vec2:unpack()

```lua
vec2:unpack()
```

Unpack this vector as individual number values

unpack this vector as multiple numbers

#### Returns

- **value**: The x and y components as separate values

<a id="vec2:cross"></a>

### vec2:cross(v)

```lua
vec2:cross(v)
```

Compute the 2D cross product (perp dot product) with another vector

calculate the cross product with another vector

#### Parameters

- **v** (vec2): The other vector

#### Returns

- **number**: The scalar cross product result

<a id="vec2:rotate"></a>

### vec2:rotate(angleRadians)

```lua
vec2:rotate(angleRadians)
```

Rotate this vector by a given angle in radians

rotate this vector by an angle in radians

#### Parameters

- **angleRadians** (number): The angle of rotation in radians

#### Returns

- **vec2**: The rotated vector

<a id="vec2:rotate90"></a>

### vec2:rotate90()

```lua
vec2:rotate90()
```

Rotate this vector by 90 degrees

rotate this vector by 90 degrees

#### Returns

- **vec2**: The rotated vector

<a id="vec2:angleBetween"></a>

### vec2:angleBetween(v)

```lua
vec2:angleBetween(v)
```

Calculate the oriented angle between this vector and another, between -pi and pi

calculate the oriented angle between this vector and another

#### Parameters

- **v** (vec2): The other vector

#### Returns

- **number**: The oriented angle in radians between -pi and pi

<a id="section-3D-Vectors"></a>

## 3D Vectors

<a id="vec3"></a>

### vec3

```lua
vec3
```

create a new vec3

<a id="vec3-2"></a>

### vec3(x, y, z)

```lua
vec3(x, y, z)
```

Create a new `vec3` by setting each component individually

create a new vec3

#### Parameters

- **x** (number): The x component
- **y** (number): The y component
- **z** (number): The z component

#### Returns

- **vec3**: 

<a id="vec3-3"></a>

### vec3()

```lua
vec3()
```

Create a new `vec3` by setting all components to zero

#### Returns

- **vec3**: 

<a id="vec3-4"></a>

### vec3(v)

```lua
vec3(v)
```

Create a new `vec3` by setting all components to the same value

#### Parameters

- **v** (number): The x, y and z values

#### Returns

- **vec3**: 

<a id="vec3.min"></a>

### vec3.min(v1, v2)

```lua
vec3.min(v1, v2)
```

Return a `vec3` containing the component-wise minimum of two vectors

return the component-wise minimum of two vectors

#### Parameters

- **v1** (vec3): The first vector
- **v2** (vec3): The second vector

#### Returns

- **vec3**: A new vec3 with the minimum of each component

<a id="vec3.max"></a>

### vec3.max(v1, v2)

```lua
vec3.max(v1, v2)
```

Return a `vec3` containing the component-wise maximum of two vectors

return the component-wise maximum of two vectors

#### Parameters

- **v1** (vec3): The first vector
- **v2** (vec3): The second vector

#### Returns

- **vec3**: A new vec3 with the maximum of each component

<a id="vec3.x"></a>

### vec3.x

```lua
vec3.x
```

The x component of this vector

get or set the x component

<a id="vec3.y"></a>

### vec3.y

```lua
vec3.y
```

The y component of this vector

get or set the y component

<a id="vec3.z"></a>

### vec3.z

```lua
vec3.z
```

The z component of this vector

get or set the z component

<a id="vec3.length"></a>

### vec3.length

```lua
vec3.length
```

The length of this vector

get the length of this vector

<a id="vec3.length2"></a>

### vec3.length2

```lua
vec3.length2
```

The squared length of this vector

get the squared length of this vector

<a id="vec3:normalize"></a>

### vec3:normalize()

```lua
vec3:normalize()
```

Normalize this vector in-place

normalize this vector

<a id="vec3:normalized"></a>

### vec3:normalized()

```lua
vec3:normalized()
```

Return a normalized copy of this vector

return a normalized copy of this vector

#### Returns

- **vec3**: A normalized copy of this vector

<a id="vec3:dot"></a>

### vec3:dot(v)

```lua
vec3:dot(v)
```

Perform a scalar dot product with another vector and return the result

calculate the dot product with another vector

#### Parameters

- **v** (vec3): The other vector

#### Returns

- **number**: The scalar dot product

<a id="vec3:cross"></a>

### vec3:cross(v)

```lua
vec3:cross(v)
```

Perform a cross product with another `vec3` and return the result

calculate the cross product with another vector

#### Parameters

- **v** (vec3): The other vector

#### Returns

- **vec3**: A vector perpendicular to both input vectors

<a id="vec3:distance"></a>

### vec3:distance(v)

```lua
vec3:distance(v)
```

Calculate the Euclidean distance to another vector

calculate the distance to another vector

#### Parameters

- **v** (vec3): The other vector

#### Returns

- **number**: The distance between the two vectors

<a id="vec3:distance2"></a>

### vec3:distance2(v)

```lua
vec3:distance2(v)
```

Calculate the squared Euclidean distance to another vector

calculate the squared distance to another vector

#### Parameters

- **v** (vec3): The other vector

#### Returns

- **number**: The squared distance between the two vectors

<a id="vec3:reflect"></a>

### vec3:reflect(normal)

```lua
vec3:reflect(normal)
```

Reflect this vector about a normal

reflect this vector about a normal

#### Parameters

- **normal** (vec3): The normal vector to reflect about

#### Returns

- **vec3**: The reflected vector

<a id="vec3:refract"></a>

### vec3:refract(normal, ior)

```lua
vec3:refract(normal, ior)
```

Refract this vector through a surface with a given index of refraction

refract this vector through a normal

#### Parameters

- **normal** (vec3): The surface normal
- **ior** (number): The index of refraction

#### Returns

- **vec3**: The refracted vector

<a id="vec3:lerp"></a>

### vec3:lerp(v, t)

```lua
vec3:lerp(v, t)
```

Interpolate this vector with another by a given factor

linearly interpolate this vector with another

#### Parameters

- **v** (vec3): The target vector
- **t** (number): The interpolation factor (typically between 0 and 1)

#### Returns

- **vec3**: The interpolated vector

<a id="vec3:abs"></a>

### vec3:abs()

```lua
vec3:abs()
```

Return a copy of this vector with component-wise absolute values

return a copy with component-wise absolute values

#### Returns

- **vec3**: A copy with all components made positive

<a id="vec3:unpack"></a>

### vec3:unpack()

```lua
vec3:unpack()
```

Unpack this vector as individual number values

unpack this vector as multiple numbers

#### Returns

- **value**: The x, y and z components as separate values

<a id="section-4D-Vectors"></a>

## 4D Vectors

<a id="vec4"></a>

### vec4

```lua
vec4
```

create a new vec4

<a id="vec4-2"></a>

### vec4(x)

```lua
vec4(x)
```

Create a new `vec4` by setting all components to the same value, or each one individually

create a new vec4

#### Parameters

- **x** (number): The x component (also used for y, z and w when called with a single argument)

#### Returns

- **vec4**: 

<a id="vec4.min"></a>

### vec4.min(v1, v2)

```lua
vec4.min(v1, v2)
```

Return a `vec4` containing the component-wise minimum of two vectors

return the component-wise minimum of two vectors

#### Parameters

- **v1** (vec4): The first vector
- **v2** (vec4): The second vector

#### Returns

- **vec4**: A new vec4 with the minimum of each component

<a id="vec4.max"></a>

### vec4.max(v1, v2)

```lua
vec4.max(v1, v2)
```

Return a `vec4` containing the component-wise maximum of two vectors

return the component-wise maximum of two vectors

#### Parameters

- **v1** (vec4): The first vector
- **v2** (vec4): The second vector

#### Returns

- **vec4**: A new vec4 with the maximum of each component

<a id="vec4.x"></a>

### vec4.x

```lua
vec4.x
```

The x component of this vector

get or set the x component

<a id="vec4.y"></a>

### vec4.y

```lua
vec4.y
```

The y component of this vector

get or set the y component

<a id="vec4.z"></a>

### vec4.z

```lua
vec4.z
```

The z component of this vector

get or set the z component

<a id="vec4.w"></a>

### vec4.w

```lua
vec4.w
```

The w component of this vector

get or set the w component

<a id="vec4.length"></a>

### vec4.length

```lua
vec4.length
```

The length of this vector

get the length of this vector

<a id="vec4.length2"></a>

### vec4.length2

```lua
vec4.length2
```

The squared length of this vector

get the squared length of this vector

<a id="vec4:normalize"></a>

### vec4:normalize()

```lua
vec4:normalize()
```

Normalize this vector in-place

normalize this vector

<a id="vec4:normalized"></a>

### vec4:normalized()

```lua
vec4:normalized()
```

Return a normalized copy of this vector

return a normalized copy of this vector

#### Returns

- **vec4**: A normalized copy of this vector

<a id="vec4:dot"></a>

### vec4:dot(v)

```lua
vec4:dot(v)
```

Perform a scalar dot product with another vector and return the result

calculate the dot product with another vector

#### Parameters

- **v** (vec4): The other vector

#### Returns

- **number**: The scalar dot product

<a id="vec4:distance"></a>

### vec4:distance(v)

```lua
vec4:distance(v)
```

Calculate the Euclidean distance to another vector

calculate the distance to another vector

#### Parameters

- **v** (vec4): The other vector

#### Returns

- **number**: The distance between the two vectors

<a id="vec4:distance2"></a>

### vec4:distance2(v)

```lua
vec4:distance2(v)
```

Calculate the squared Euclidean distance to another vector

calculate the squared distance to another vector

#### Parameters

- **v** (vec4): The other vector

#### Returns

- **number**: The squared distance between the two vectors

<a id="vec4:reflect"></a>

### vec4:reflect(normal)

```lua
vec4:reflect(normal)
```

Reflect this vector about a normal

reflect this vector about a normal

#### Parameters

- **normal** (vec4): The normal vector to reflect about

#### Returns

- **vec4**: The reflected vector

<a id="vec4:refract"></a>

### vec4:refract(normal, ior)

```lua
vec4:refract(normal, ior)
```

Refract this vector through a surface with a given index of refraction

refract this vector through a normal

#### Parameters

- **normal** (vec4): The surface normal
- **ior** (number): The index of refraction

#### Returns

- **vec4**: The refracted vector

<a id="vec4:lerp"></a>

### vec4:lerp(v, t)

```lua
vec4:lerp(v, t)
```

Interpolate this vector with another by a given factor

linearly interpolate this vector with another

#### Parameters

- **v** (vec4): The target vector
- **t** (number): The interpolation factor (typically between 0 and 1)

#### Returns

- **vec4**: The interpolated vector

<a id="vec4:abs"></a>

### vec4:abs()

```lua
vec4:abs()
```

Return a copy of this vector with component-wise absolute values

return a copy with component-wise absolute values

#### Returns

- **vec4**: A copy with all components made positive

<a id="vec4:unpack"></a>

### vec4:unpack()

```lua
vec4:unpack()
```

Unpack this vector as individual number values

unpack this vector as multiple numbers

#### Returns

- **value**: The x, y, z and w components as separate values

<a id="section-Quaternions"></a>

## Quaternions

<a id="quat"></a>

### quat

```lua
quat
```

create a new quaternion

<a id="quat-2"></a>

### quat()

```lua
quat()
```

Create a new `quat`

create a new quaternion

#### Returns

- **quat**: 

<a id="quat.lookRotation"></a>

### quat.lookRotation(forward, up)

```lua
quat.lookRotation(forward, up)
```

Create a rotation that points in the `forward` direction, oriented using `up`

create a rotation looking in a forward direction

#### Parameters

- **forward** (vec3): The forward direction
- **up** (vec3): The up direction used for orientation

#### Returns

- **quat**: A quat that points in the forward direction

<a id="quat.fromToRotation"></a>

### quat.fromToRotation(from, to)

```lua
quat.fromToRotation(from, to)
```

Create a rotation that rotates from one direction to another

create a rotation from one direction to another

#### Parameters

- **from** (vec3): The direction to rotate from
- **to** (vec3): The direction to rotate to

#### Returns

- **quat**: A quat containing the relative rotation from from to to

<a id="quat.angleAxis"></a>

### quat.angleAxis(angle, axis)

```lua
quat.angleAxis(angle, axis)
```

Create a rotation of `angle` degrees around an `axis`

create a rotation from an angle and axis

#### Parameters

- **angle** (number): The amount of rotation in degrees
- **axis** (vec3): The axis of rotation

#### Returns

- **quat**: A new quat representing the rotation

<a id="quat.eulerAngles"></a>

### quat.eulerAngles(x, y, z)

```lua
quat.eulerAngles(x, y, z)
```

Create a rotation from euler angles (yaw, pitch, roll) in degrees

create a rotation from euler angles

#### Parameters

- **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

#### Returns

- **quat**: A new quat representing the combined rotation

<a id="quat.x"></a>

### quat.x

```lua
quat.x
```

The x imaginary component

get or set the x component

<a id="quat.y"></a>

### quat.y

```lua
quat.y
```

The y imaginary component

get or set the y component

<a id="quat.z"></a>

### quat.z

```lua
quat.z
```

The z imaginary component

get or set the z component

<a id="quat.w"></a>

### quat.w

```lua
quat.w
```

The scalar (real) component

get or set the w component

<a id="quat.angles"></a>

### quat.angles

```lua
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*

get the euler angles of this quaternion

<a id="quat:slerp"></a>

### quat:slerp(q, t)

```lua
quat:slerp(q, t)
```

Spherically interpolate between this quaternion and another

spherically interpolate this quaternion with another

#### Parameters

- **q** (quat): The target quaternion
- **t** (number): The interpolation amount (between 0 and 1)

#### Returns

- **quat**: A new quat spherically interpolated from this to q by t

<a id="quat:conjugate"></a>

### quat:conjugate()

```lua
quat:conjugate()
```

Return the conjugate of this quaternion

return the conjugate of this quaternion

#### Returns

- **quat**: A new quat containing the conjugate (inverse rotation)

<a id="quat:normalize"></a>

### quat:normalize()

```lua
quat:normalize()
```

Normalize this quaternion in-place

normalize this quaternion

<a id="quat:normalized"></a>

### quat:normalized()

```lua
quat:normalized()
```

Return a normalized copy of this quaternion

return a normalized copy of this quaternion

#### Returns

- **quat**: A normalized copy of this quaternion

<a id="section-2x2-Matrix"></a>

## 2x2 Matrix

<a id="mat2"></a>

### mat2

```lua
mat2
```

A simple 2x2 matrix. Individual entries can be accessed via a 1-based index

create a new 2x2 matrix

#### Example

```lua
m = mat2(1) -- init with diagonals set to 1
print(m[1]) -- prints '1.0'
```

<a id="mat2-2"></a>

### mat2()

```lua
mat2()
```

Create a new `mat2`: default (identity), diagonal scalar, two `vec2` columns, or all 4 entries

create a new 2x2 matrix

#### Returns

- **mat2**: 

<a id="mat2:inverse"></a>

### mat2:inverse()

```lua
mat2:inverse()
```

Return the inverse of this matrix

return the inverse of this matrix

#### Returns

- **mat2**: The inverse of this matrix

<a id="mat2:transpose"></a>

### mat2:transpose()

```lua
mat2:transpose()
```

Return the transpose of this matrix

return the transpose of this matrix

#### Returns

- **mat2**: The transpose of this matrix

<a id="mat2:determinant"></a>

### mat2:determinant()

```lua
mat2:determinant()
```

Return the determinant of this matrix

return the determinant of this matrix

#### Returns

- **number**: The determinant

<a id="mat2:row"></a>

### mat2:row(index)

```lua
mat2:row(index)
```

Return the row at a given index

return the row at the given index

#### Parameters

- **index** (number): The 1-based row index

#### Returns

- **vec2**: The row at the given index

<a id="mat2:column"></a>

### mat2:column(index)

```lua
mat2:column(index)
```

Return the column at a given index

return the column at the given index

#### Parameters

- **index** (number): The 1-based column index

#### Returns

- **vec2**: The column at the given index

<a id="section-3x3-Matrix"></a>

## 3x3 Matrix

<a id="mat3"></a>

### mat3

```lua
mat3
```

A simple 3x3 matrix. Individual entries can be accessed via a 1-based index

create a new 3x3 matrix

#### Example

```lua
m = mat3(1) -- init with diagonals set to 1
print(m[1]) -- prints '1.0'
```

<a id="mat3-2"></a>

### mat3()

```lua
mat3()
```

Create a new `mat3`: default (identity), diagonal scalar, three `vec3` columns, or all 9 entries

create a new 3x3 matrix

#### Returns

- **mat3**: 

<a id="mat3:inverse"></a>

### mat3:inverse()

```lua
mat3:inverse()
```

Return the inverse of this matrix

return the inverse of this matrix

#### Returns

- **mat3**: The inverse of this matrix

<a id="mat3:transpose"></a>

### mat3:transpose()

```lua
mat3:transpose()
```

Return the transpose of this matrix

return the transpose of this matrix

#### Returns

- **mat3**: The transpose of this matrix

<a id="mat3:determinant"></a>

### mat3:determinant()

```lua
mat3:determinant()
```

Return the determinant of this matrix

return the determinant of this matrix

#### Returns

- **number**: The determinant

<a id="mat3:row"></a>

### mat3:row(index)

```lua
mat3:row(index)
```

Return the row at a given index

return the row at the given index

#### Parameters

- **index** (number): The 1-based row index

#### Returns

- **vec3**: The row at the given index

<a id="mat3:column"></a>

### mat3:column(index)

```lua
mat3:column(index)
```

Return the column at a given index

return the column at the given index

#### Parameters

- **index** (number): The 1-based column index

#### Returns

- **vec3**: The column at the given index

<a id="section-4x4-Matrix"></a>

## 4x4 Matrix

<a id="mat4"></a>

### mat4

```lua
mat4
```

A 4x4 matrix typically used for 3D homogeneous transformations. Individual entries can be accessed via a 1-based index

create a new 4x4 matrix

#### Example

```lua
m = mat4(1) -- init with diagonals set to 1
print(m[1]) -- prints '1.0'
```

<a id="mat4-2"></a>

### mat4()

```lua
mat4()
```

Create a new `mat4`: default (identity), diagonal scalar, four `vec4` columns, or all 16 entries

create a new 4x4 matrix

#### Returns

- **mat4**: 

<a id="mat4.lookAt"></a>

### mat4.lookAt(eye, center, up)

```lua
mat4.lookAt(eye, center, up)
```

Create a look-at view matrix

build a look-at view transform

#### Parameters

- **eye** (vec3): The position of the camera
- **center** (vec3): The point to look at
- **up** (vec3): The up direction

#### Returns

- **mat4**: A view matrix looking from eye toward center

<a id="mat4.lookAt-2"></a>

### mat4.lookAt(matrix, eye, center, up)

```lua
mat4.lookAt(matrix, eye, center, up)
```

Apply a look-at transform to an existing matrix

build a look-at view transform

#### Parameters

- **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

#### Returns

- **mat4**: The transformed matrix

<a id="mat4.orbit"></a>

### mat4.orbit(origin, distance, x, y)

```lua
mat4.orbit(origin, distance, x, y)
```

Create an orbit view matrix centered on a point

build an orbit view transform

#### Parameters

- **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

#### Returns

- **mat4**: An orbit view matrix

<a id="mat4.orbit-2"></a>

### mat4.orbit(matrix, origin, distance, x, y)

```lua
mat4.orbit(matrix, origin, distance, x, y)
```

Apply an orbit transform to an existing matrix

build an orbit view transform

#### Parameters

- **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

#### Returns

- **mat4**: The transformed matrix

<a id="mat4.ortho"></a>

### mat4.ortho(left, right, top, bottom, near, far)

```lua
mat4.ortho(left, right, top, bottom, near, far)
```

Create an orthographic projection matrix

setup an orthographic view

#### Parameters

- **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)

#### Returns

- **mat4**: An orthographic projection matrix

<a id="mat4.perspective"></a>

### mat4.perspective(fovy, aspect, near, far)

```lua
mat4.perspective(fovy, aspect, near, far)
```

Create a perspective projection matrix

setup a perspective view

#### Parameters

- **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

#### Returns

- **mat4**: A perspective projection matrix

<a id="mat4.rotate"></a>

### mat4.rotate(angle, axis)

```lua
mat4.rotate(angle, axis)
```

Create a rotation matrix

rotate a matrix by an angle and axis

#### Parameters

- **angle** (number): The rotation angle in degrees
- **axis** (vec3): The axis of rotation

#### Returns

- **mat4**: A rotation matrix

<a id="mat4.rotate-2"></a>

### mat4.rotate(matrix, angle, axis)

```lua
mat4.rotate(matrix, angle, axis)
```

Apply a rotation transform to an existing matrix

rotate a matrix by an angle and axis

#### Parameters

- **matrix** (mat4): The matrix to rotate
- **angle** (number): The rotation angle in degrees
- **axis** (vec3): The axis of rotation

#### Returns

- **mat4**: The rotated matrix

<a id="mat4:inverse"></a>

### mat4:inverse()

```lua
mat4:inverse()
```

Return the inverse of this matrix

return the inverse of this matrix

#### Returns

- **mat4**: The inverse of this matrix

<a id="mat4:transpose"></a>

### mat4:transpose()

```lua
mat4:transpose()
```

Return the transpose of this matrix

return the transpose of this matrix

#### Returns

- **mat4**: The transpose of this matrix

<a id="mat4:determinant"></a>

### mat4:determinant()

```lua
mat4:determinant()
```

Return the determinant of this matrix

return the determinant of this matrix

#### Returns

- **number**: The determinant

<a id="mat4:row"></a>

### mat4:row(index)

```lua
mat4:row(index)
```

Return the row at a given index

return the row at the given index

#### Parameters

- **index** (number): The 1-based row index

#### Returns

- **vec4**: The row at the given index

<a id="mat4:column"></a>

### mat4:column(index)

```lua
mat4:column(index)
```

Return the column at a given index

return the column at the given index

#### Parameters

- **index** (number): The 1-based column index

#### Returns

- **vec4**: The column at the given index

<a id="section-Axis-Aligned-Bounding-Box-AABB"></a>

## Axis-Aligned Bounding Box (AABB)

<a id="bounds.aabb"></a>

### aabb

```lua
b = bounds.aabb(vec3(-1, -1, -1), vec3(1, 1, 1))
```

An axis-aligned bounding box defined by minimum and maximum corner points

get or set the minimum corner

#### Parameters

- **min** (vec3): The minimum corner of the bounding box
- **max** (vec3): The maximum corner of the bounding box

<a id="aabb.min"></a>

### aabb.min

```lua
aabb.min
```

The minimum corner of this bounding box

get or set the minimum corner

<a id="aabb.max"></a>

### aabb.max

```lua
aabb.max
```

The maximum corner of this bounding box

get or set the maximum corner

<a id="aabb.size"></a>

### aabb.size

```lua
aabb.size
```

The size (width, height, depth) of this bounding box

get the size of this bounding box

<a id="aabb.center"></a>

### aabb.center

```lua
aabb.center
```

The center point of this bounding box

get the center of this bounding box

<a id="aabb:set"></a>

### aabb:set(min, max)

```lua
aabb:set(min, max)
```

Set the minimum and maximum corners of this bounding box

set the min and max corners of this bounding box

#### Parameters

- **min** (vec3): The new minimum corner
- **max** (vec3): The new maximum corner

<a id="aabb:translate"></a>

### aabb:translate(offset)

```lua
aabb:translate(offset)
```

Translate this bounding box by an offset

translate this bounding box by an offset

#### Parameters

- **offset** (vec3): The translation offset

<a id="section-Matrix"></a>

## Matrix

<a id="Transforming-Drawings"></a>

### Transforming Drawings

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.

<a id="Projection"></a>

### Projection

**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.

<a id="section-General"></a>

## General

<a id="matrix.push"></a>

### matrix.push()

```lua
matrix.push()
```

Push the current matrix onto the stack, saving the current transform

push the current matrix onto the stack

<a id="matrix.pop"></a>

### matrix.pop()

```lua
matrix.pop()
```

Pop the matrix from the stack, restoring the previous transform

pop the current matrix from the stack

<a id="matrix.reset"></a>

### matrix.reset()

```lua
matrix.reset()
```

Reset the current matrix to the identity matrix

reset the matrix stack

<a id="matrix.model"></a>

### matrix.model()

```lua
matrix.model()
```

Gets the model matrix used to transform from local to world space

get the model matrix

<a id="matrix.model-2"></a>

### matrix.model(matrix)

```lua
matrix.model(matrix)
```

Sets the model matrix used to transform from local to world space

set the model matrix

#### Parameters

- **matrix** (mat4): Matrix to install as the current transform.

<a id="matrix.view"></a>

### matrix.view()

```lua
matrix.view()
```

Gets the view matrix used to transform from world to view space

get the view matrix

<a id="matrix.view-2"></a>

### matrix.view(matrix)

```lua
matrix.view(matrix)
```

Sets the view matrix used to transform from world to view space (generally controlled by cameras)

set the view matrix

#### Parameters

- **matrix** (mat4): Matrix to install as the current transform.

<a id="matrix.projection"></a>

### matrix.projection()

```lua
matrix.projection()
```

Gets the projection matrix used for final projection

get the projection matrix

<a id="matrix.projection-2"></a>

### matrix.projection(matrix)

```lua
matrix.projection(matrix)
```

Sets the projection matrix, used for final projection (i.e. ortho and perspective projection)

set the projection matrix

#### Parameters

- **matrix** (mat4): Matrix to install as the current transform.

<a id="section-Transform"></a>

## Transform

<a id="matrix.transform2d"></a>

### matrix.transform2d(x, y, sx, sy, r)

```lua
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

apply a 2D transform to the model matrix

#### Parameters

- **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.

#### Nested orbits

[Download project](data/downloads/Nested-orbits-128628168884.zip) — Open in Codea to run this example.

```lua
-- 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

```

<a id="matrix.transform3d"></a>

### matrix.transform3d(x, y, z, sx, sy, sz, rx, ry, rz)

```lua
matrix.transform3d(x, y, z, sx, sy, sz, rx, ry, rz)
```

Apply a generic 3D transform to the model matrix

apply a 3D transform to the model matrix

#### Parameters

- **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.

<a id="matrix.translate"></a>

### matrix.translate(x, y, z)

```lua
matrix.translate(x, y, z)
```

Translate the current model matrix

translate the current transform

#### Parameters

- **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.

<a id="matrix.rotate"></a>

### matrix.rotate(quat)

```lua
matrix.rotate(quat)
```

rotate the current transform

#### Parameters

- **quat** (quat): Quaternion describing the rotation.

<a id="matrix.rotate-2"></a>

### matrix.rotate(angle, x, y, z)

```lua
matrix.rotate(angle, x, y, z)
```

Rotate the current model matrix

rotate the current transform

#### Parameters

- **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.

<a id="matrix.scale"></a>

### matrix.scale(x, y, z)

```lua
matrix.scale(x, y, z)
```

Scale the current model matrix

scale the current transform

#### Parameters

- **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.

<a id="section-Projection"></a>

## Projection

<a id="matrix.ortho"></a>

### matrix.ortho()

```lua
matrix.ortho()
```

Set the projection matrix to ortho using the device screen settings (i.e. coordinates range `[0, 0]` to `[WIDTH, HEIGHT]`)

setup an orthographic view

<a id="matrix.ortho-2"></a>

### matrix.ortho(height)

```lua
matrix.ortho(height)
```

Sets an orthographic projection matrix `height` units high, using the aspect ratio of the screen to set the width

setup an orthographic view

#### Parameters

- **height** (number): The height of the orthographic projection

<a id="matrix.ortho-3"></a>

### matrix.ortho(left, right, bottom, top, near, far)

```lua
matrix.ortho(left, right, bottom, top, near, far)
```

Sets an orthographic projection matrix using the supplied edge values

setup an orthographic view

#### Parameters

- **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.

<a id="matrix.perspective"></a>

### matrix.perspective(fov, aspect, near, far)

```lua
matrix.perspective(fov, aspect, near, far)
```

Sets a perspective projection matrix

setup a perspective view

#### Parameters

- **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.
