local ffi = require( "ffi" ) local new = ffi.typeof( "double[3]" ) local sqrt = math.sqrt local function mag(a) return a[0]*a[0] + a[1]*a[1] + a[2]*a[2] end local function len(a) return sqrt(mag(a)) end local function dot(a, b) return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] end ---- NEG ---- local function neg(r, a) r[0], r[1], r[2] = -a[0], -a[1], -a[2] return r end local function negself(a) a[0], a[1], a[2] = -a[0], -a[1], -a[2] return a end local function negnew(a) return neg(new(), a) end ---- ADD ---- local function add(r, a, b) r[0], r[1], r[2] = a[0]+b[0], a[1]+b[1], a[2]+b[2] return r end local function addself(a, b) a[0], a[1], a[2] = a[0]+b[0], a[1]+b[1], a[2]+b[2] return a end local function addnew(a, b) return add(new(), a, b) end ---- SUB ---- local function sub(r, a, b) r[0], r[1], r[2] = a[0]-b[0], a[1]-b[1], a[2]-b[2] return r end local function subself(a, b) a[0], a[1], a[2] = a[0]-b[0], a[1]-b[1], a[2]-b[2] return a end local function subnew(a, b) return sub(new(), a, b) end ---- MUL ---- local function mul(r, a, b) r[0], r[1], r[2] = a[0]*b[0], a[1]*b[1], a[2]*b[2] return r end local function mulself(a, b) a[0], a[1], a[2] = a[0]*b[0], a[1]*b[1], a[2]*b[2] return a end local function mulnew(a, b) return mul(new(), a, b) end ---- SCALE ---- local function scale(r, a, k) r[0], r[1], r[2] = a[0]*k, a[1]*k, a[2]*k return r end local function scaleself(a, k) a[0], a[1], a[2] = a[0]*k, a[1]*k, a[2]*k return a end local function scalenew(a, k) return scale(new(), a, k) end --- NORM ---- local function norm(r, a) local im = 1 / len(a) r[0], r[1], r[2] = a[0]*im, a[1]*im, a[2]*im return r end local function normself(a) local im = 1 / len(a) a[0], a[1], a[2] = a[0]*im, a[1]*im, a[2]*im return a end local function normnew(a) return norm(new(),a) end ---- CROSS ---- local function cross(r, a, b) r[0], r[1], r[2] = a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0] return r end local function crossself(a, b) a[0], a[1], a[2] = a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0] return a end local function crossnew(a, b) return cross(new(), a, b) end ---- DIR ---- local function dir(r, a, b) return norm(sub(r, a, b)) end local function dirself(a, b) return normself(subself(a, b)) end local function dirnew(a, b) return dir(new(), a, b) end local function str(v) return tostring(v[0])..", "..tostring(v[1])..", "..tostring(v[2]) end if not ... then local v = new(1,2,3) local n = negself(v) end return { new = new, mag = mag, len = len, dot = dot, neg = neg, negself = negself, negnew = negnew, add = add, addself = addself, addnew = addnew, sub = sub, subself = subself, subnew = subnew, scale = scale, scaleself = scaleself, scalenew = scalenew, norm = norm, normself = normself, normnew = normnew, cross = cross, crossself = crossself, crossnew = crossnew, dir = dir, dirself = dirself, dirnew = dirnew, str = str, -- Should probably make this tostring, or make double[3] a structure and use metatables }