Fix quaternion (THIS IS WHY WE NEED TESTS). Also gave vec3 a table constructor.

This commit is contained in:
Colby Klein 2014-11-11 03:46:25 -08:00
parent 38dda4a265
commit 2b41e8debb
2 changed files with 22 additions and 15 deletions

View File

@ -8,9 +8,11 @@ This is a class for handling quaternion numbers. It was originally
designed as a way of encoding rotations of 3 dimensional space.
--]]
local current_folder = (...):gsub('%.[^%.]+$', '') .. "."
local constants = require(current_folder .. "constants")
local quaternion = {}
quaternion.__index = quaternion
local FLT_EPSILON = 1.19209290e-07
--[[
A quaternion can either be specified by giving the four coordinates as
@ -53,7 +55,7 @@ function quaternion:to_axis_angle()
local angle = 2 * math.acos(tmp.a)
local s = math.sqrt(1-tmp.a*tmp.a)
local x, y, z
if s < FLT_EPSILON then
if s < constants.FLT_EPSILON then
x = tmp.b
y = tmp.c
z = tmp.d
@ -172,7 +174,7 @@ Scale the quaternion.
--]]
function quaternion:scale(l)
return quaternion(self.a * l,self.b * l,self.c * l, self.d * l)
return new(self.a * l,self.b * l,self.c * l, self.d * l)
end
--[[
@ -181,9 +183,9 @@ Add two quaternions. Or add a real number to a quaternion.
function quaternion:add(q)
if type(q) == "number" then
return quaternion(self.a + q, self.b, self.c, self.d)
return new(self.a + q, self.b, self.c, self.d)
else
return quaternion(self.a + q.a, self.b + q.b, self.c + q.c, self.d + q.d)
return new(self.a + q.a, self.b + q.b, self.c + q.c, self.d + q.d)
end
end
@ -200,7 +202,7 @@ Subtraction
--]]
function quaternion:subtract(q)
return quaternion(self.a - q.a, self.b - q.b, self.c - q.c, self.d - q.d)
return new(self.a - q.a, self.b - q.b, self.c - q.c, self.d - q.d)
end
--[[
@ -239,7 +241,7 @@ function quaternion:multiplyRight(q)
b = self.a * q.b + self.b * q.a + self.c * q.d - self.d * q.c
c = self.a * q.c - self.b * q.d + self.c * q.a + self.d * q.b
d = self.a * q.d + self.b * q.c - self.c * q.b + self.d * q.a
return quaternion(a,b,c,d)
return new(a,b,c,d)
end
--[[
@ -269,7 +271,7 @@ Conjugation (corresponds to inverting a rotation).
--]]
function quaternion:conjugate()
return quaternion(self.a, - self.b, - self.c, - self.d)
return new(self.a, - self.b, - self.c, - self.d)
end
function quaternion:co()
@ -301,7 +303,7 @@ function quaternion:power(n)
return false
end
if n == 0 then
return quaternion(1,0,0,0)
return new(1,0,0,0)
elseif n > 0 then
return self:multiplyRight(self:power(n-1))
elseif n < 0 then
@ -412,7 +414,7 @@ When we have access to the compass, the x-axis behaviour might change.
function quaternion.gravity()
local gxy, gy, gygxy, a, b, c, d
if Gravity.x == 0 and Gravity.y == 0 then
return quaternion(1,0,0,0)
return new(1,0,0,0)
else
gy = - Gravity.y
gxy = math.sqrt(math.pow(Gravity.x,2) + math.pow(Gravity.y,2))
@ -433,7 +435,7 @@ function quaternion.gravity()
c = - c
d = - d
end
return quaternion(a,b,c,d)
return new(a,b,c,d)
end
end
--]]
@ -446,7 +448,7 @@ as three numbers.
function quaternion.rotation(a,...)
local q,c,s
q = quaternion(0,...)
q = new(0,...)
q = q:normalize()
c = math.cos(a/2)
s = math.sin(a/2)
@ -494,7 +496,7 @@ The unit quaternion.
--]]
function quaternion.unit()
return quaternion(1,0,0,0)
return new(1,0,0,0)
end
--return quaternion

View File

@ -34,6 +34,10 @@ local vector = {}
vector.__index = vector
local function new(x,y,z)
if type(x) == "table" then
return setmetatable({x = x.x or x[1] or 0, y = x.y or x[2] or 0, z = x.z or x[3] or 0}, vector)
end
return setmetatable({x = x or 0, y = y or 0, z = z or 0}, vector)
end
local zero = new(0,0,0)
@ -221,8 +225,9 @@ function vector:trimmed(maxLen)
return self:clone():trim_inplace(maxLen)
end
function vector:orientation_to_direction()
return new(0, 1, 0)
function vector:orientation_to_direction(orientation)
orientation = orientation or new(0, 1, 0)
return orientation
:rotated(self.z, new(0, 0, 1))
:rotated(self.y, new(0, 1, 0))
:rotated(self.x, new(1, 0, 0))