This is a part of my Audiosurf 2 scripting library.
Various helpers for working with 3D coordinates
vec3 = {} do function vec3.add(a, b) return {a[1] + b[1], a[2] + b[2], a[3] + b[3]} end function vec3.sub(a, b) return {a[1] - b[1], a[2] - b[2], a[3] - b[3]} end function vec3.mulSingle(a, b) return {a[1] * b, a[2] * b, a[3] * b} end function vec3.divSingle(a, b) return {a[1] / b, a[2] / b, a[3] / b} end function vec3.assign(a, dest) dest[1], dest[2], dest[3] = a[1], a[2], a[3] end function vec3.copy(a) return { a[1], a[2], a[3] } end function vec3.fromApi(a) return { a.x, a.y, a.z } end local min, max = math.min, math.max function vec3.min(a, b) return { min(a[1], b[1]), min(a[2], b[2]), min(a[3], b[3]) } end function vec3.max(a, b) return { max(a[1], b[1]), max(a[2], b[2]), max(a[3], b[3]) } end -- returns 3 arrays of numbers: x, y, and z function vec3.transposeArray(vec3_array) local x, y, z = {}, {}, {} local v for i=1,#vec3_array do v = vec3_array[i] x[i], y[i], z[i] = v[1], v[2], v[3] end return x, y, z end function vec3.avg(a, b) return {(a[1] + b[1]) / 2, (a[2] + b[2]) / 2, (a[3] + b[3]) / 2} end local sqrt = math.sqrt function vec3.len(a) return sqrt(a[1]^2 + a[2]^2 + a[3]^2) end function vec3.lenSquared(a) return a[1]^2 + a[2]^2 + a[3]^2 end function vec3.dist(a, b) return sqrt((a[1] - b[1])^2 + (a[2] - b[2])^2 + (a[3] - b[3])^2) end local divSingle, len = vec3.divSingle, vec3.len function vec3.norm(a) return divSingle(a, len(a)) end function vec3.setLen(a, b) return divSingle(a, len(a) / b) end function vec3.neg(a) return {-a[1], -a[2], -a[3]} end end
Various helpers for working with 2D coordinates
vec2 = {} do function vec2.add(a, b) return {a[1] + b[1], a[2] + b[2]} end function vec2.sub(a, b) return {a[1] - b[1], a[2] - b[2]} end function vec2.mulSingle(a, b) return {a[1] * b, a[2] * b} end function vec2.divSingle(a, b) return {a[1] / b, a[2] / b} end function vec2.assign(a, dest) dest[1], dest[2] = a[1], a[2] end function vec2.copy(a) return { a[1], a[2] } end function vec2.fromApi(a) return { a.x, a.y } end local min, max = math.min, math.max function vec2.min(a, b) return { min(a[1], b[1]), min(a[2], b[2]) } end function vec2.max(a, b) return { max(a[1], b[1]), max(a[2], b[2]) } end -- returns 2 arrays of numbers: x and y function vec2.transposeArray(vec2_array) local x, y = {}, {} local v for i=1,#vec2_array do v = vec2_array[i] x[i], y[i] = v[1], v[2] end return x, y end function vec2.avg(a, b) return {(a[1] + b[1]) / 2, (a[2] + b[2]) / 2} end local sqrt = math.sqrt function vec2.len(a) return sqrt(a[1]^2 + a[2]^2) end function vec2.lenSquared(a) return a[1]^2 + a[2]^2 end function vec2.dist(a, b) return sqrt((a[1] - b[1])^2 + (a[2] - b[2])^2) end local divSingle, len = vec2.divSingle, vec2.len function vec2.norm(a) return divSingle(a, len(a)) end function vec2.setLen(a, b) return divSingle(a, len(a) / b) end function vec2.right(a) return {a[2], -a[1]} end function vec2.left(a) return {-a[2], a[1]} end function vec2.neg(a) return {-a[1], -a[2]} end local sin, cos = math.sin, math.cos function vec2.getRotMatrix(angle, dest) local s, c = sin(angle), cos(angle) dest[1], dest[2], dest[3], dest[4] = c, -s, s, c end function vec2.mulMatrix(a, m) return { a[1]*m[1] + a[2]*m[2], a[1]*m[3] + a[2]*m[4], } end local getRotMatrix, mulMatrix = vec2.getRotMatrix, vec2.mulMatrix function vec2.rot(a, angle) local m = {} getRotMatrix(angle, m) return mulMatrix(a, m) end end