Wiki

Clone wiki

Core / vec2

Back to Beyond the Codea in-app reference


FunctionIconType-Small.png vec2() function

Introduction

Codea's in-app reference documents most of the vec2() function. The function returns a userdata value that is a vector in two dimensions.

Returning a two dimensional vector

The vec2() function is used to return a new two-dimensional vector value as in the following example:

v1 = vec2(x1, y1)  -- x1, y1 contain numbers for the respective co-ordinates

If any co-ordinates are omitted, then they are assumed to be 0. For example:

print(vec2())     -- Outputs: (0.000000, 0.000000)
print(vec2(1))    -- Outputs: (1.000000, 0.000000)

Setting and getting individual coordinates

Indexing can be used to set and get individual coordinates, either by ordinal number or by letter (x, y), as summarised in the table below:

Co-ordinateIndex schemeIndex scheme
Firstv1[1]v1.x or v1["x"]
Secondv1[2]v1.y or v1["y"]

Operators

The result of the vec2() function supports the - (uniary), *, /, +, -, and == operators, where the second operand is a number value in the case of * (multiplication by a scalar) and / (division by a scalar).

Functions

The result also supports tostring() to produce nicely-formatted output. Consequently, print() also generates nicely-formatted output.

The result of the vec2() function supports the indexed functions dot(), cross(), len(), lenSqr(), dist(), distSqr(), normalize(), rotate(), rotate90() and angleBetween(). For example:

v1 = vec2(1, -1)
v2 = vec2(-2, 5)

-- Calculate the dot (scalar) product of two vectors
d = v1.dot(v1, v2)       -- This syntax is equivalent ...
d = v1:dot(v2)           -- ... to this syntax, using Lua's colon notation.

-- Calculate the length (magnitude) of first vector
l = v1.len(v1)           -- This syntax is equivalent ...
l = v1:len()             -- ... to this syntax, using Lua's colon notation.

v1:cross(v2)

The function v1:cross(v2) returns a number. Rewritten in Lua, the function is the equivalent of:

function cross(v1, v2)
    return v1.x * v2.y - v1.y * v2.x
end

v1:dist(v2)

The function v1:dist(v2) returns the length (magnitude) of the 'distance' vector v1 - v2. The following have equivalent results, but the former will execute more quickly:

distance = v1:dist(v2)
distance = (v1 - v2):len()

v1:angleBetween(v2)

The function v1:angleBetween(v2) calculates the smallest angle in radians turning from vector v1 to vector v2. A counterclockwise turn is a positive angle and a clockwise turn is a negative angle.

Rewritten in Lua, the function is the equivalent of:

function angleBetween(v1, v2)
    local angle = math.atan2(v2.y, v2.x) - math.atan2(v1.y, v1.x)
    if angle > math.pi then
        angle = angle - 2 * math.pi
    elseif angle < -math.pi then
        angle = angle + 2 * math.pi
    end
    return angle
end

Optimisation

Where speed of execution is at a premium, the performance of the functions built into the vec2 userdata can be improved by caching the functions in a local variable. For example:

--
-- Codea's vec2 userdata
--

function setup()
    local n = 500000      -- Number of tests
    local v1 = vec2(1, 2)
    local v2 = vec2(4, 5)
    
    print("v1:dist(v2)")
    local t = os.clock()
    for i = 1, n do
       local d = v1:dist(v2)       -- With no caching
    end
    local dt1 = os.clock() - t
    
    t = os.clock()
    local distCache = v1.dist      -- Cache the vec2().dist function
    for i = 1, n do
       local d = distCache(v1, v2) -- Use the cached function
    end
    local dt2 = os.clock() - t
     
    print("Improvement:"..tostring((1 - dt2/dt1) * 100).."%")
end    

function draw()
    background(0)
end

On an iPad 2, the caching example above results in an improvement in execution of about 54%.

Updated