diff --git a/.tests/Vector3/set_to.test.lua b/.tests/Vector3/set_to.test.lua new file mode 100644 index 0000000..99eedab --- /dev/null +++ b/.tests/Vector3/set_to.test.lua @@ -0,0 +1,52 @@ +local Vector3 = require("worldeditadditions.utils.vector3") + +describe("Vector3.set_to", function() + it("should set_to a positive vector", function() + local a = Vector3.new(801980510, 801980510, 801980510) + assert.are.same( + Vector3.new(80198051, 80198051, 80198051), + a:set_to(138907099) + ) + end) + it("should set_to a negative vector", function() + local a = Vector3.new(-1897506260, -1897506260, -1897506260) + assert.are.same( + Vector3.new(-189750626, -189750626, -189750626), + a:set_to(328657725) + ) + end) + it("should work if the length is borderline", function() + local a = Vector3.new(80198051, 80198051, 80198051) + assert.are.same( + Vector3.new(80198051, 80198051, 80198051), + a:set_to(138907099) + ) + end) + it("should work if the length is smaller", function() + local a = Vector3.new(80198051, 80198051, 80198051) + assert.are.same( + Vector3.new(109552575, 109552575, 109552575), + a:set_to(189750626):floor() -- Hack to ignore flating-point errors. In theory we should really use epsilon here instead + ) + end) + it("should return a new Vector3 instance", function() + local a = Vector3.new(801980510, 801980510, 801980510) + + local result = a:set_to(138907099) + assert.are.same( + Vector3.new(80198051, 80198051, 80198051), + result + ) + assert.are_not.equal(result, a) + end) + it("should return a new Vector3 instance if the length is smaller", function() + local a = Vector3.new(80198051, 80198051, 80198051) + + local result = a:set_to(189750626):floor() + assert.are.same( + Vector3.new(109552575, 109552575, 109552575), + result + ) + assert.are_not.equal(result, a) + end) +end) diff --git a/worldeditadditions/utils/vector3.lua b/worldeditadditions/utils/vector3.lua index 17d3152..7fa33df 100644 --- a/worldeditadditions/utils/vector3.lua +++ b/worldeditadditions/utils/vector3.lua @@ -175,6 +175,17 @@ function Vector3.limit_to(a, length) return a:clone() end +--- Returns a new vector whose length clamped to the given length. +-- The direction in which the vector is pointing is not changed. +-- @param a Vector3 The vector to operate on. +-- @returns Vector3 A new Vector3 instance limited to the specified length. +function Vector3.set_to(a, length) + if type(length) ~= "number" then error("Error: Expected number, but found "..type(length)..".") end + + return (a / a:length()) * length +end + + --- Return a vector that is amount distance towards b from a. -- @param a Vector3 The vector to move from. -- @param b Vector3 The vector to move towards.