Rotating 4D Cube

Explained by title. Achieved by rotation matrices and stereographic projection.

----------------Vector4 Class

local Vector4 = {}
Vector4.__index = Vector4

function Vector4.new(x,y,z,w)
	local self = setmetatable({}, Vector4)

	self.X = x
	self.Y = y
	self.Z = z
	self.W = w

	return self
end

function Vector4:__add(toAdd)
	return Vector4.new(self.X + toAdd.X, self.Y + toAdd.Y, self.Z + toAdd.Z, self.W + toAdd.W)
end

function Vector4:__sub(toAdd)
	return Vector4.new(self.X - toAdd.X, self.Y - toAdd.Y, self.Z - toAdd.Z, self.W - toAdd.W)
end

function Vector4:__eq(toEq)
	return (self.X == toEq.X) and (self.Y == toEq.Y) and (self.Z == toEq.Z) and (self.W == toEq.W)
end

function Vector4:Rotate_XW_YZ(Angle)
	local newX = math.cos(Angle) * self.X - math.sin(Angle) * self.W
	local newY = math.sin(Angle) * self.Z + math.cos(Angle) * self.Y
	local newZ = math.cos(Angle) * self.Z - math.sin(Angle) * self.Y
	local newW = math.sin(Angle) * self.X + math.cos(Angle) * self.W

	return Vector4.new(newX, newY, newZ, newW)
end

function Vector4:Magnitude()
	return math.sqrt(self.X * self.X + self.Y * self.Y + self.Z * self.Z + self.W * self.W)
end

function Vector4:Project()
	local distance = 5 -- This is arbitrary
	local coefficient = 1 / (distance - self.W)
	return Vector3.new(self.X * coefficient, self.Y * coefficient, self.Z * coefficient)
end

----------------Physical Representation

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

local function normalizeMagnitude(number)
	if number == 1 then return 1 end
	if number == 2 then return -1 end
end

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

				Object[Vector4.new(normalizeMagnitude(x),normalizeMagnitude(y),normalizeMagnitude(z),normalizeMagnitude(w))] = Instance.new("Attachment", workspace.Base)

			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.X *= xSize
	Vector.Y *= ySize
	Vector.Z *= zSize
	Vector.W *= wSize
end

while true do
	for i = 1, 360 / Speed do
		wait()
		for Vector, Attachment in pairs(Object) do
			local RotatedVector = Vector:Rotate_XW_YZ(i * Speed)
			Attachment.WorldPosition = RotatedVector:Project() + Offset3d
		end
	end
end

18 Likes

Yooooo, Sick! That’s pretty good.

That’s actually pretty nice, it gives me a little bit of an headache. Its really nice, good job!