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