I was writing some code that builds some meshes from rotated 3D vectors and was curious how to best express that in Lua/Codea (most of my programming is with compiled languages, where the costs must be evaluated differently). Anyway, after benchmarking a handful alternatives, I found (somewhat unsurprisingly) that the fastest options are to rely as much as possible on Codea’s composite library functions. In my case, the speed of the rotations proper is more important than the determination of the rotation matrix/vectors, but it did benchmark both parts of the problem.
Here is the code I settled upon:
function applyMatrixRowsToVec3(v, r1, r2, r3)
-- Let M be a matrix with rows r1, r2, and r3. Return M*v.
return vec3(v:dot(r1), v:dot(r2), v:dot(r3))
end
function rotationVectors(u, angle)
-- Returns three 3D vectors corresponding to the rows of a matrix
-- implementing a rotation of the given angle around the given axis.
local m = matrix()
m = m:rotate(angle, u.x, u.y, u.z)
return vec3(m[1], m[2], m[3]),
vec3(m[5], m[6], m[7]),
vec3(m[9], m[10], m[11])
--[[
-- The following is pretty efficient, but using whole-matrix operations as is
-- done above is faster still. Also, this expanded form requires a unit vector u.
local c = math.cos(angle)
local s = math.sin(angle)
local d = 1-c
local su = s*u
local du = d*u
local r1 = du.x*u + vec3(c, su.z, -su.y)
local r2 = du.y*u + vec3(-su.z, c, su.x)
local r3 = du.z*u + vec3(su.y, -su.x, c)
return r1, r2, r3
]]--
end
function rotateVec3(v, u, angle)
-- Return vector v rotated angle degrees around vector u.
return applyMatrixRowsToVec3(v, rotationVectors(u, angle))
end
I hope this is helpful. I suspect if Codea implemented a native matrix-vector multiply, we’d get another 2x or so speedup for the actual rotation. Also, you gain 10% or so by expanding these expressions inline.