VectorN: Easy + Fast 4D-1000D+ Vectors

Introduction:

Model:

VectorN vs Vector3:

VectorN supports any amount of dimensions without losing on functionality. Vector3 merges all XYZ to a single binary value, VectorN stores data to a buffer and is more optimized for extremely large vectors.

VectorN also includes 10+ different formats to store data with differing pricision and new functions such as Project for projecting across dimensions and Rotate.

Is this a drop in replacement?

This would work very well as a drop in replacement as it extends Vector3s existing abilities. But because support N dimensions is a priority functions like :Cross have been dropped.

VectorN is slower than native Vector3 because it is running in a Luau container unlike Vector3s which are in C++. Vector3 also uses less memory because it does not package information such as dimensions and byte style. This does not mean VectorN is slow, VectorN is extremely performant especially for large databases.

Documentation

.new functions

new: (...number|{number}) -> VectorN
Create a normal multidimensional vector stored in i8’s. Divides & Multiplies by 10 for decimals.

newInt16: (...number|{number}) -> VectorN
Uses i16 instead of i8s.

newInt32: (...number|{number}) -> VectorN
Uses i32 instead of i8s or i16.

newUint16: (...number|{number}) -> VectorN
Like newInt16 but does not support negatives in exchange for more range.

newUint32: (...number|{number}) -> VectorN
Like newInt32 but does not support negatives in exchange for more range.

newF32: (...number|{number}) -> VectorN
Like i32 but supports decimals similar to normal .new but instead it does not use division + multiplication.

newF64: (...number|{number}) -> VectorN
Like f32 but more range.

newInt16d10: (...number|{number}) -> VectorN
Like Int16 but also supports decimals by dividing and multiplying. Has less range.

newInt32d10: (...number|{number}) -> VectorN
Like Int32 but also supports decimals by dividing and multiplying. Has less range.

newUint16d10: (...number|{number}) -> VectorN
Like Uint16 but also supports decimals by dividing and multiplying. Has less range.

newUint32d10: (...number|{number}) -> VectorN
Like Uint32 but also supports decimals by dividing and multiplying. Has less range.

Functions

Abs: (VectorN) -> VectorN
Returns absolute value for each axis in a new vector.

Floor: (VectorN) -> VectorN
Returns floored value for each axis in a new vector.

Ceil: (VectorN) -> VectorN
Returns value ran on math.ceil for each axis in a new vector.

Sign: (VectorN) -> VectorN
Returns 1,0, or -1 for each axis depending on if it is negative, zero, or positive.

NormalizeMagnitude: (VectorN) -> VectorN
Returns the same vector but with if x == 1 then 1 elseif x == 2 then -1.

Lerp: (VectorN, VectorN, number) -> VectorN
Linear lerping from the first vector to the second vector with the number (alpha) being the time 0-1.

Max: (VectorN, VectorN) -> VectorN
Return a vector with the largest of each axis

Min: (VectorN, VectorN) -> VectorN
Return a vector with the smallest of each axis

Dot: (VectorN, VectorN) -> number
Calculates dot product of 2 vectors

FuzzyEq: (VectorN, VectorN, number) -> boolean
Calculates if the vectors are within a tolerance

Rotate: (VectorN, number, number, number) -> VectorN
Rotates ‘vector’ by angle on dim1 and dim2

Interpret: (VectorN) -> VectorN
Returns the vector projected with one less dimension (ex: 4D → 3D)

Project: (VectorN, number) -> VectorN
Returns the vector projected from any dimension to a lesser dimension (ex: 5D → 3D)

Examples:

-- magnitude.luau
local VectorN

local V1 = VectorN.new(1,2,3.2,4)
local V2 = VectorN.new(5,4,1.7,2)

print(V1, V2, (V1-V2).Magnitude)

Screenshot 2024-06-17 at 4.06.07 PM


NOTE: This example is ported from @GrimDarkLord7’s version here

-- 4d.luau
-- includes code from: https://devforum.roblox.com/t/rotating-4d-cube/1576197

local VectorN

local Object = {}
local xSize, ySize, zSize, wSize = 3,3,3,3
local Offset3d = Vector3.new(0,5,0)
local Speed = 1/24


for x = 1, 2 do
	for y = 1, 2 do
		for z = 1, 2 do
			for w = 1, 2 do
				for f = 1, 2 do

					Object[VectorN.newF64(x,y,z,w):NormalizeMagnitude()] = Instance.new("Attachment", workspace.Base)

				end
			end
		end
	end
end


for Vector, Attachment0 in pairs(Object) do
	for secondVector, Attachment1 in pairs(Object) do
		if Vector ~= secondVector then
			if (Vector - secondVector).Magnitude == 2 then
				local Rod = Instance.new("RodConstraint", workspace.Base)
				Rod.Attachment0 = Attachment0
				Rod.Attachment1 = Attachment1
				Rod.Visible = true
				Rod.Color = BrickColor.new("Cyan")
				Rod.Thickness = 0.2
			end
		end
	end
end

for Vector, _ in pairs(Object) do
	Vector[1] *= xSize
	Vector[2] *= ySize
	Vector[3] *= zSize
	Vector[4] *= wSize
end

local rotatingDim1 = 4
local rotatingDim2 = 1

while true do
	for i = 1, 360 / Speed do
		task.wait()
		for Vector, Attachment in pairs(Object) do
			local RotatedVector = Vector:Rotate(i * Speed, rotatingDim1, rotatingDim2)
			Attachment.WorldPosition = RotatedVector:Project(3):To("Vector3") + Offset3d
			--print(RotatedVector)
		end
	end
end

20 Likes

THIS IS AMAZING!

I was thinking of making a story game with a twist of 4D.
You would traverse 3D slices of 4D worlds.

Will see what I can do with this as it’s super cool’

3 Likes

cool module, i will probably you use it in my next 4D game.
Good job :+1:

Very cool! Games with dimensions greater than 3 aren’t very common so this is quite niche, but still interesting.

True, but from doing test runs it is definitely possible to improve the speed of some calculations, albeit we would have to ditch the buffer and maybe slightly lose performance in some tasks. I know this kind of performance probably isn’t what you’re going after, but I hacked together a quick prototype anyway that from what I’ve seen in the worst case (4D) has 3x faster addition and 2x faster multiplication and at large dimensions the difference can be > x10 faster. It doesn’t have all the same features and is missing quite a lot but it was fun to make!

vectornf.lua (4.2 KB)

1 Like

This is true, but internally using multiple dimensions is common in many places from rendering (raytracing), and Transformer Neural Networks. I made this just for fun and for learning.

I used the buffer library because it reduces memory usage, For lower dimensions it isn’t needed but I may make a pure double mode which drops usage for buffers.

Can someone please explain what exactly 4D is and how it works as if i was 12 years old?

1 Like

pretty much this library isn’t made to visualize it but more over just be able to operate on it.

A 4d vector can hold 4 numbers which can be anything from xyz&time or statistics.

This library allows you to easily operate on a 4d vector and multiply, add, calculate distance, rotate, etc.

1 Like

Is there any useful case for 4D vectors in game development?

representing a tuple of number and easily operate. this supports more then 4 dimensions so this could be used with Googles Word2Vec which is really cool.