From 06896404479ce2bba839eac8e18299896c4a885f Mon Sep 17 00:00:00 2001 From: David Briscoe Date: Fri, 27 May 2022 14:31:41 -0700 Subject: [PATCH] vec: Rework vec2.to_vec3; add vec3.to_xz * Replace vec2.to_vec3 with vec3.from_table. * Add vec3.to_xz, vec3.to_xy, vec3.to_table. * Add vec2.to_table for completeness. Simplify converting into flat plane math. Often I want to do math on the ground plane, so it's helpful to easily convert vec3 into vec2 (like for angle_to). Remove vec2.to_vec3 so vec3 can depend on vec2 instead and we can do to_xz and to_xy, which seem far more useful. vec3.from_table(a) is mostly equivalent to to_vec3, but doesn't accept a value for z. Add to_table as a pair for from_table and for converting into a serializable. No vec2.from_table because it's the same as vec2.new. --- modules/vec2.lua | 17 ++++++++++------- modules/vec3.lua | 30 ++++++++++++++++++++++++++++++ spec/vec2_spec.lua | 17 +++++++++++++---- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/modules/vec2.lua b/modules/vec2.lua index c392444..352443d 100644 --- a/modules/vec2.lua +++ b/modules/vec2.lua @@ -2,7 +2,6 @@ -- @module vec2 local modules = (...):gsub('%.[^%.]+$', '') .. "." -local vec3 = require(modules .. "vec3") local precond = require(modules .. "_private_precond") local private = require(modules .. "_private_utils") local acos = math.acos @@ -368,14 +367,18 @@ function vec2.flip_y(a) return vec2.new(a.x, -a.y) end --- Convert vec2 to vec3. --- @tparam vec2 a Vector to convert. --- @tparam number the new z component, or nil for 0 --- @treturn vec3 Converted vector -function vec2.to_vec3(a, z) - return vec3(a.x, a.y, z or 0) +-- No to_vec3 to avoid circular dependency. Use +-- vec3.from_table(a) instead. + +--- Return a simple table representation of vector. +-- @tparam vec2 a Vector to be turned into a table +-- @treturn table +function vec2.to_table(a) + return {x = a.x, y = a.y} end +-- No from_table -- it's the same as vec2.new(a). + --- Return a formatted string. -- @tparam vec2 a Vector to be turned into a string -- @treturn string formatted diff --git a/modules/vec3.lua b/modules/vec3.lua index b653506..ab1637e 100644 --- a/modules/vec3.lua +++ b/modules/vec3.lua @@ -4,6 +4,7 @@ local modules = (...):gsub('%.[^%.]+$', '') .. "." local precond = require(modules .. "_private_precond") local private = require(modules .. "_private_utils") +local vec2 = require(modules .. "vec2") local sqrt = math.sqrt local cos = math.cos local sin = math.sin @@ -373,6 +374,35 @@ function vec3.to_string(a) return string.format("(%+0.3f,%+0.3f,%+0.3f)", a.x, a.y, a.z) end +--- Return the x and y components as a vec2 +-- @tparam vec3 a Vector to be reduced to a vec2 +-- @treturn vec2 +function vec3.to_xy(a) + return vec2.new(a.x, a.y) +end + +--- Return the x and z components as a vec2 +-- @tparam vec3 a Vector to be reduced to a vec2 +-- @treturn vec2 +function vec3.to_xz(a) + return vec2.new(a.x, a.z) +end + +--- Return a simple table representation of vector. +-- @tparam vec3 a Vector to be turned into a table +-- @treturn table +function vec3.to_table(a) + return {x = a.x, y = a.y, z = a.z} +end + +--- Create a vec3 from a table. +-- @tparam table a table to supply the values +-- @treturn vec3 +function vec3.from_table(a) + assert(a.x and a.y, "from_table: Wrong argument type for right hand operand.") + return new(a.x, a.y, a.z or 0) +end + vec3_mt.__index = vec3 vec3_mt.__tostring = vec3.to_string diff --git a/spec/vec2_spec.lua b/spec/vec2_spec.lua index 4375f4c..dd82b0c 100644 --- a/spec/vec2_spec.lua +++ b/spec/vec2_spec.lua @@ -264,15 +264,24 @@ describe("vec2:", function() assert.is.equal(math.deg(d.up:angle_between(d.up)), 0.0) end) - -- Do this last, to insulate tests from accidental state contamination -- Do vec3 tests last, to insulate tests from accidental state contamination it("converts a 2-vector to a 3-vector", function() local vec3 = require "modules.vec3" local a = vec2(1,2) - local b = a:to_vec3() - local c = a:to_vec3(3) + local b = vec3.from_table(a) + local c = vec3.from_table(vec2(3,4)) assert.is.equal(b, vec3(1,2,0)) - assert.is.equal(c, vec3(1,2,3)) + assert.is.equal(c, vec3(3,4,0)) + assert.is.equal(c:len(), 5) + end) + + it("converts a 3-vector to a 2-vector", function() + local vec3 = require "modules.vec3" + local a = vec3(1,2,3) + local b = vec3.to_xy(a) + local c = vec3.to_xz(a) + assert.is.equal(b, vec2(1,2)) + assert.is.equal(c, vec2(1,3)) end) it("converts a vec3 to vec2 using the constructor", function()