Added tests for vec2 and vec3

This commit is contained in:
karai17 2016-07-15 22:07:48 -03:00
parent 7f7ff0077a
commit add0a71c05
5 changed files with 476 additions and 82 deletions

View File

@ -101,7 +101,7 @@ end
function utils.is_pot(value)
-- found here: https://love2d.org/forums/viewtopic.php?p=182219#p182219
-- check if a number is a power-of-two
return (frexp(value)) == 0.5
return (frexp(value)) == 0.5
end
return utils

View File

@ -1,13 +1,11 @@
--- A 2 component vector.
-- @module vec2
local atan2, sqrt, pi = math.atan2, math.sqrt, math.pi
local cos, sin = math.cos, math.sin
local atan2, sqrt,cos, sin, pi = math.atan2, math.sqrt, math.cos, math,sin, math.pi
local vec2 = {}
-- Private constructor.
local function new(x, y, z)
local function new(x, y)
local v = {}
v.x, v.y = x, y
return setmetatable(v, vec2_mt)
@ -30,7 +28,7 @@ end
-- scalar to fill the vector eg. {x, x}
-- @tparam number y y component
function vec2.new(x, y)
-- number, number, number
-- number, number
if x and y then
assert(type(x) == "number", "new: Wrong argument type for x (<number> expected)")
assert(type(y) == "number", "new: Wrong argument type for y (<number> expected)")
@ -45,7 +43,7 @@ function vec2.new(x, y)
return new(x, y)
-- {x, x, x} eh. {0, 0, 0}, {3, 3, 3}
-- {x, x} eh. {0, 0}, {3, 3}
elseif type(x) == "number" then
return new(x, x)
else
@ -57,7 +55,7 @@ end
-- @tparam vec2 a vector to be cloned
-- @treturn vec2
function vec2.clone(a)
return new(a.x, a.y, a.z)
return new(a.x, a.y)
end
--- Add two vectors.
@ -117,7 +115,7 @@ end
function vec2.trim(out, a, len)
len = math.min(vec2.len(a), len)
vec2.normalize(out, a)
vec2.mul(out, len)
vec2.mul(out, out, len)
return out
end
@ -184,6 +182,34 @@ function vec2.lerp(out, a, b, s)
return out
end
--- Unpack a vector into form x,y
-- @tparam vec2 a first vector
-- @treturn number x component
-- @treturn number y component
function vec2.unpack(a)
return a.x, a.y
end
--- Return a string formatted "{x, y}"
-- @tparam vec2 a the vector to be turned into a string
-- @treturn string
function vec2.tostring(a)
return string.format("(%+0.3f,%+0.3f)", a.x, a.y)
end
--- Return a boolean showing if a table is or is not a vec2
-- @param v the object to be tested
-- @treturn boolean
function vec2.isvec2(v)
return
(
type(v) == "table" or
type(v) == "cdata"
) and
type(v.x) == "number" and
type(v.y) == "number"
end
--- Convert point from polar to cartesian.
-- @tparam vec2 out vector for result to be stored in
-- @tparam number radius radius of the point
@ -206,38 +232,13 @@ function vec2.to_polar(a)
return radius, theta
end
--- Unpack a vector into form x,y
-- @tparam vec2 a first vector
-- @treturn number x component
-- @treturn number y component
function vec2.unpack(a)
return a.x, a.y
end
--- Return a string formatted "{x, y}"
-- @tparam vec2 a the vector to be turned into a string
-- @treturn string
function vec2.tostring(a)
return string.format("(%+0.3f,%+0.3f)", a.x, a.y)
end
--- Return a boolean showing if a table is or is not a vec2
-- @param v the object to be tested
-- @treturn boolean
function vec2.isvec2(v)
return
type(v) == "table" and
type(v.x) == "number" and
type(v.y) == "number"
end
local vec2_mt = {}
vec2_mt.__index = vec2
vec2_mt.__tostring = vec2.tostring
function vec2_mt.__call(self, x, y, z)
return vec2.new(x, y, z)
function vec2_mt.__call(self, x, y)
return vec2.new(x, y)
end
function vec2_mt.__unm(a)
@ -260,6 +261,15 @@ function vec2_mt.__add(a, b)
return temp
end
function vec2_mt.__sub(a, b)
assert(vec2.isvec2(a), "__add: Wrong argument type for left hand operant. (<cpml.vec2> expected)")
assert(vec2.isvec2(b), "__add: Wrong argument type for right hand operant. (<cpml.vec2> expected)")
local temp = vec2.new()
vec2.sub(temp, a, b)
return temp
end
function vec2_mt.__mul(a, b)
local isvecb = vec2.isvec2(b)
a, b = isvecb and b or a, isvecb and a or b
@ -284,6 +294,9 @@ function vec2_mt.__div(a, b)
return temp
end
vec2.unit_x = vec2.new(1, 0)
vec2.unit_y = vec2.new(0, 1)
if status then
ffi.metatype(new, vec2_mt)
end

View File

@ -1,7 +1,7 @@
--- A 3 component vector.
-- @module vec3
local sqrt= math.sqrt
local sqrt = math.sqrt
local vec3 = {}
-- Private constructor.
@ -57,7 +57,6 @@ function vec3.new(x, y, z)
end
end
--- Clone a vector.
-- @tparam vec3 a vector to be cloned
-- @treturn vec3
@ -65,7 +64,6 @@ function vec3.clone(a)
return new(a.x, a.y, a.z)
end
--- Add two vectors.
-- @tparam vec3 out vector to store the result
-- @tparam vec3 a Left hand operant
@ -110,17 +108,6 @@ function vec3.div(out, a, b)
return out
end
--- Get the cross product of two vectors.
-- @tparam vec3 out vector to store the result
-- @tparam vec3 a Left hand operant
-- @tparam vec3 b Right hand operant
function vec3.cross(out, a, b)
out.x = a.y * b.z - a.z * b.y
out.y = a.z * b.x - a.x * b.z
out.z = a.x * b.y - a.y * b.x
return out
end
--- Get the normal of a vector.
-- @tparam vec3 out vector to store the result
-- @tparam vec3 a vector to normalize
@ -139,38 +126,18 @@ end
function vec3.trim(out, a, len)
len = math.min(vec3.len(a), len)
vec3.normalize(out, a)
vec3.mul(out, len)
vec3.mul(out, out, len)
return out
end
function vec3.reflect(out, i, n)
vec3.mul(out, n, 2.0 * vec3.dot(n, i))
vec3.sub(out, i, out)
return out
end
function vec3.refract(out, i, n, ior)
local d = vec3.dot(n, i)
local k = 1.0 - ior * ior * (1.0 - d * d)
if k >= 0.0 then
vec3.mul(out, i, ior)
vec3.mul(tmp, n, ior * d + sqrt(k))
vec3.sub(out, out, tmp)
end
return out
end
--- Lerp between two vectors.
-- @tparam vec3 out vector for result to be stored in
-- @tparam vec3 a first vector
-- @tparam vec3 b second vector
-- @tparam number s step value
-- @treturn vec3
function vec3.lerp(out, a, b, s)
vec3.sub(out, b, a)
vec3.mul(out, out, s)
vec3.add(out, out, a)
--- Get the cross product of two vectors.
-- @tparam vec3 out vector to store the result
-- @tparam vec3 a Left hand operant
-- @tparam vec3 b Right hand operant
function vec3.cross(out, a, b)
out.x = a.y * b.z - a.z * b.y
out.y = a.z * b.x - a.x * b.z
out.z = a.x * b.y - a.y * b.x
return out
end
@ -218,6 +185,19 @@ function vec3.dist2(a, b)
return dx * dx + dy * dy + dz * dz
end
--- Lerp between two vectors.
-- @tparam vec3 out vector for result to be stored in
-- @tparam vec3 a first vector
-- @tparam vec3 b second vector
-- @tparam number s step value
-- @treturn vec3
function vec3.lerp(out, a, b, s)
vec3.sub(out, b, a)
vec3.mul(out, out, s)
vec3.add(out, out, a)
return out
end
--- Unpack a vector into form x,y,z
-- @tparam vec3 a first vector
-- @treturn number x component
@ -239,12 +219,34 @@ end
-- @treturn boolean
function vec3.isvec3(v)
return
type(v) == "table" and
(
type(v) == "table" or
type(v) == "cdata"
) and
type(v.x) == "number" and
type(v.y) == "number" and
type(v.z) == "number"
end
function vec3.reflect(out, i, n)
vec3.mul(out, n, 2.0 * vec3.dot(n, i))
vec3.sub(out, i, out)
return out
end
function vec3.refract(out, i, n, ior)
local d = vec3.dot(n, i)
local k = 1.0 - ior * ior * (1.0 - d * d)
if k >= 0.0 then
vec3.mul(out, i, ior)
vec3.mul(tmp, n, ior * d + sqrt(k))
vec3.sub(out, out, tmp)
end
return out
end
local vec3_mt = {}
vec3_mt.__index = vec3

View File

@ -1,4 +1,188 @@
local vec2 = require "modules.vec2"
local vec2 = require "modules.vec2"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
local abs, sqrt = math.abs, math.sqrt
describe("vec2:", function()
it("Test creating vectors", function()
-- new empty vector
local a = vec2()
assert.is.equal(a.x, 0)
assert.is.equal(a.y, 0)
assert.is_true(vec2.isvec2(a))
-- new vector from table
local b = vec2 { 0, 0 }
assert.is.equal(b.x, 0)
assert.is.equal(b.y, 0)
local c = vec2 { x=0, y=0 }
assert.is.equal(c.x, 0)
assert.is.equal(c.y, 0)
-- new vector from numbers
local d = vec2(3.14159, -2.808)
assert.is.equal(d.x, 3.14159)
assert.is.equal(d.y, -2.808)
-- new vector from other vector
local e = vec2.clone(d)
assert.is.equal(d, e)
local f = d:clone()
assert.is.equal(d, f)
end)
it("Test basic operators", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local s = 2
-- Add
do
local c = vec2.add(vec2(), a, b)
assert.is.equal(c.x, 10)
assert.is.equal(c.y, 9)
local d = a + b
assert.is.equal(c, d)
end
-- Subtract
do
local c = vec2.sub(vec2(), a, b)
assert.is.equal(c.x, -4)
assert.is.equal(c.y, 1)
local d = a - b
assert.is.equal(c, d)
end
-- Multiply
do
local c = vec2.mul(vec2(), a, s)
assert.is.equal(c.x, 6)
assert.is.equal(c.y, 10)
local d = a * s
assert.is.equal(c, d)
end
-- Divide
do
local c = vec2.div(vec2(), a, s)
assert.is.equal(c.x, 1.5)
assert.is.equal(c.y, 2.5)
local d = a / s
assert.is.equal(c, d)
end
-- Sign flip
do
local c = -a
assert.is.equal(c.x, -3)
assert.is.equal(c.y, -5)
end
end)
it("Test normal, trim, length", function()
local a = vec2(3, 5)
local b = vec2.normalize(vec2(), a)
assert.is_true(abs(b:len() - 1) < DBL_EPSILON)
assert.is_true(abs(b:len() - 1) < DBL_EPSILON)
assert.is_true(abs(b:len2() - 1) < DBL_EPSILON * 2)
local c = vec2.trim(vec2(), a, 0.5)
assert.is_true(abs(c:len() - 0.5) < DBL_EPSILON)
end)
it("Test distance", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
-- Distance
do
local c = vec2.dist(a, b)
assert.is.equal(c, sqrt(17))
local d = a:dist(b)
assert.is.equal(c, d)
end
-- Distance Squared
do
local c = vec2.dist2(a, b)
assert.is.equal(c, 17)
local d = a:dist2(b)
assert.is.equal(c, d)
end
end)
it("Test cross product", function()
do
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = vec2.cross(a, b)
assert.is.equal(c, -23)
local d = a:cross(b)
assert.is.equal(c, d)
end
end)
it("Test dot product", function()
do
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = vec2.dot(a, b)
assert.is.equal(c, 41)
local d = a:dot(b)
assert.is.equal(c, d)
end
end)
it("Test lerp", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local s = 0.1
local c = vec2.lerp(vec2(), a, b, s)
assert.is.equal(c.x, 3.4)
assert.is.equal(c.y, 4.9)
end)
it("Test unpack", function()
local a = vec2(3, 5)
do
local x, y = vec2.unpack(a)
assert.is.equal(x, 3)
assert.is.equal(y, 5)
end
do
local x, y = a:unpack()
assert.is.equal(x, 3)
assert.is.equal(y, 5)
end
end)
end)
--[[
-- TODO: To Cartesian
do
local a = vec2(3, 5)
end
-- TODO: To Polar
do
local a = vec2(3, 5)
end
--]]

View File

@ -1,4 +1,199 @@
local vec3 = require "modules.vec3"
local vec3 = require "modules.vec3"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
local abs, sqrt = math.abs, math.sqrt
describe("vec3:", function()
it("Test creating vectors", function()
-- new empty vector
local a = vec3()
assert.is.equal(a.x, 0)
assert.is.equal(a.y, 0)
assert.is.equal(a.z, 0)
assert.is_true(vec3.isvec3(a))
-- new vector from table
local b = vec3 { 0, 0, 0 }
assert.is.equal(b.x, 0)
assert.is.equal(b.y, 0)
assert.is.equal(b.z, 0)
local c = vec3 { x=0, y=0, z=0 }
assert.is.equal(c.x, 0)
assert.is.equal(c.y, 0)
assert.is.equal(c.z, 0)
-- new vector from numbers
local d = vec3(3.14159, -2.808, 1.337)
assert.is.equal(d.x, 3.14159)
assert.is.equal(d.y, -2.808)
assert.is.equal(d.z, 1.337)
-- new vector from other vector
local e = vec3.clone(d)
assert.is.equal(d, e)
local f = d:clone()
assert.is.equal(d, f)
end)
it("Test basic operators", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local s = 2
-- Add
do
local c = vec3.add(vec3(), a, b)
assert.is.equal(c.x, 10)
assert.is.equal(c.y, 9)
assert.is.equal(c.z, 8)
local d = a + b
assert.is.equal(c, d)
end
-- Subtract
do
local c = vec3.sub(vec3(), a, b)
assert.is.equal(c.x, -4)
assert.is.equal(c.y, 1)
assert.is.equal(c.z, 6)
local d = a - b
assert.is.equal(c, d)
end
-- Multiply
do
local c = vec3.mul(vec3(), a, s)
assert.is.equal(c.x, 6)
assert.is.equal(c.y, 10)
assert.is.equal(c.z, 14)
local d = a * s
assert.is.equal(c, d)
end
-- Divide
do
local c = vec3.div(vec3(), a, s)
assert.is.equal(c.x, 1.5)
assert.is.equal(c.y, 2.5)
assert.is.equal(c.z, 3.5)
local d = a / s
assert.is.equal(c, d)
end
-- Sign flip
do
local c = -a
assert.is.equal(c.x, -3)
assert.is.equal(c.y, -5)
assert.is.equal(c.z, -7)
end
end)
it("Test normal, trim, length", function()
local a = vec3(3, 5, 7)
local b = vec3.normalize(vec3(), a)
assert.is_true(abs(b:len() - 1) < DBL_EPSILON)
assert.is_true(abs(b:len() - 1) < DBL_EPSILON)
assert.is_true(abs(b:len2() - 1) < DBL_EPSILON * 2)
local c = vec3.trim(vec3(), a, 0.5)
assert.is_true(abs(c:len() - 0.5) < DBL_EPSILON)
end)
it("Test distance", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
-- Distance
do
local c = vec3.dist(a, b)
assert.is.equal(c, sqrt(53))
local d = a:dist(b)
assert.is.equal(c, d)
end
-- Distance Squared
do
local c = vec3.dist2(a, b)
assert.is.equal(c, 53)
local d = a:dist2(b)
assert.is.equal(c, d)
end
end)
it("Test cross product", function()
do
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = vec3.cross(vec3(), a, b)
assert.is.equal(c.x, -23)
assert.is.equal(c.y, 46)
assert.is.equal(c.z, -23)
end
end)
it("Test dot product", function()
do
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = vec3.dot(a, b)
assert.is.equal(c, 48)
local d = a:dot(b)
assert.is.equal(c, d)
end
end)
it("Test lerp", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local s = 0.1
local c = vec3.lerp(vec3(), a, b, s)
assert.is.equal(c.x, 3.4)
assert.is.equal(c.y, 4.9)
assert.is.equal(c.z, 6.4)
end)
it("Test unpack", function()
local a = vec3(3, 5, 7)
do
local x, y, z = vec3.unpack(a)
assert.is.equal(x, 3)
assert.is.equal(y, 5)
assert.is.equal(z, 7)
end
do
local x, y, z = a:unpack()
assert.is.equal(x, 3)
assert.is.equal(y, 5)
assert.is.equal(z, 7)
end
end)
end)
--[[
-- TODO: Reflect
do
local a = vec3(3, 5, 7)
end
-- TODO: Refract
do
local a = vec3(3, 5, 7)
end
--]]