From 7549b0eaea7ec01b3e1c9985db8fda9ace1d9743 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Sat, 26 Jun 2021 15:15:32 +0100
Subject: [PATCH] Vector3: add length, length_squared, sqrt

---
 .tests/Vector3/length.test.lua         | 38 ++++++++++++++++++++++++++
 .tests/Vector3/length_squared.test.lua | 34 +++++++++++++++++++++++
 .tests/Vector3/sqrt.test.lua           | 37 +++++++++++++++++++++++++
 worldeditadditions/utils/vector3.lua   | 21 ++++++++++++++
 4 files changed, 130 insertions(+)
 create mode 100644 .tests/Vector3/length.test.lua
 create mode 100644 .tests/Vector3/length_squared.test.lua
 create mode 100644 .tests/Vector3/sqrt.test.lua

diff --git a/.tests/Vector3/length.test.lua b/.tests/Vector3/length.test.lua
new file mode 100644
index 0000000..3d225b9
--- /dev/null
+++ b/.tests/Vector3/length.test.lua
@@ -0,0 +1,38 @@
+local Vector3 = require("worldeditadditions.utils.vector3")
+
+local function format_map(map)
+	local result = {}
+	for key, value in pairs(map) do
+		table.insert(result, key.."\t"..tostring(value))
+	end
+	return table.concat(result, "\n")
+end
+
+-- To find these numbers, in Javascript:
+-- function t(x) { return Math.sqrt((x*x)*3); }
+-- for(let i = 0; i < 1000000000; i++) { let r = t(i); if(Math.floor(r) === r) console.log(`i ${i}, r ${r}`); }
+
+
+describe("Vector3.length", function()
+	it("should work with a positive vector", function()
+		local a = Vector3.new(80198051, 80198051, 80198051)
+		assert.are.equal(
+			138907099,
+			a:length()
+		)
+	end)
+	it("should work with a negative vector", function()
+		local a = Vector3.new(-189750626, -189750626, -189750626)
+		assert.are.equal(
+			328657725,
+			a:length()
+		)
+	end)
+	it("should work with a mixed vector", function()
+		local a = Vector3.new(-371635731, 371635731, -371635731)
+		assert.are.equal(
+			643691968,
+			a:length()
+		)
+	end)
+end)
diff --git a/.tests/Vector3/length_squared.test.lua b/.tests/Vector3/length_squared.test.lua
new file mode 100644
index 0000000..d3bb2a4
--- /dev/null
+++ b/.tests/Vector3/length_squared.test.lua
@@ -0,0 +1,34 @@
+local Vector3 = require("worldeditadditions.utils.vector3")
+
+local function format_map(map)
+	local result = {}
+	for key, value in pairs(map) do
+		table.insert(result, key.."\t"..tostring(value))
+	end
+	return table.concat(result, "\n")
+end
+
+
+describe("Vector3.length_squared", function()
+	it("should work with a positive vector", function()
+		local a = Vector3.new(3, 3, 3)
+		assert.are.equal(
+			27,
+			a:length_squared()
+		)
+	end)
+	it("should work with a negative vector", function()
+		local a = Vector3.new(-4, -4, -4)
+		assert.are.equal(
+			48,
+			a:length_squared()
+		)
+	end)
+	it("should work with a mixed vector", function()
+		local a = Vector3.new(-3, 3, -3)
+		assert.are.equal(
+			27,
+			a:length_squared()
+		)
+	end)
+end)
diff --git a/.tests/Vector3/sqrt.test.lua b/.tests/Vector3/sqrt.test.lua
new file mode 100644
index 0000000..6726a64
--- /dev/null
+++ b/.tests/Vector3/sqrt.test.lua
@@ -0,0 +1,37 @@
+local Vector3 = require("worldeditadditions.utils.vector3")
+
+local function format_map(map)
+	local result = {}
+	for key, value in pairs(map) do
+		table.insert(result, key.."\t"..tostring(value))
+	end
+	return table.concat(result, "\n")
+end
+
+
+describe("Vector3.sqrt", function()
+	it("should sqrt a positive vector", function()
+		local a = Vector3.new(16, 64, 16)
+		assert.are.same(
+			Vector3.new(4, 8, 4),
+			a:sqrt()
+		)
+	end)
+	it("should sqrt another positive vector", function()
+		local a = Vector3.new(9, 16, 25)
+		assert.are.same(
+			Vector3.new(3, 4, 5),
+			a:sqrt()
+		)
+	end)
+	it("should return a new Vector3 instance", function()
+		local a = Vector3.new(9, 16, 25)
+		
+		local result = a:sqrt()
+		assert.are.same(
+			Vector3.new(3, 4, 5),
+			result
+		)
+		assert.are_not.equal(result, a)
+	end)
+end)
diff --git a/worldeditadditions/utils/vector3.lua b/worldeditadditions/utils/vector3.lua
index 8d08af2..85a9019 100644
--- a/worldeditadditions/utils/vector3.lua
+++ b/worldeditadditions/utils/vector3.lua
@@ -134,6 +134,27 @@ function Vector3.area(a)
 	return a.x * a.y * a.z
 end
 
+--- Returns the scalar length of this vector squared.
+-- @param	a		Vector3		The vector to operate on.
+-- @returns	number	The length squared of this vector as a scalar value.
+function Vector3.length_squared(a)
+	return a.x * a.x + a.y * a.y + a.z * a.z
+end
+
+--- Square roots each component of this vector.
+-- @param	a		Vector3		The vector to operate on.
+-- @returns	number	A new vector with each component square rooted.
+function Vector3.sqrt(a)
+	return Vector3.new(math.sqrt(a.x), math.sqrt(a.y), math.sqrt(a.z))
+end
+
+--- Calculates the scalar length of this vector.
+-- @param	a		Vector3		The vector to operate on.
+-- @returns	number	The length of this vector as a scalar value.
+function Vector3.length(a)
+	return math.sqrt(a:length_squared())
+end
+
 --  ██████  ██████  ███████ ██████   █████  ████████  ██████  ██████
 -- ██    ██ ██   ██ ██      ██   ██ ██   ██    ██    ██    ██ ██   ██
 -- ██    ██ ██████  █████   ██████  ███████    ██    ██    ██ ██████
