osci-render/Resources/lua/hypercube.lua

85 wiersze
2.4 KiB
Lua

local SCALE = 1.0
local ANIMATION_SPEED = 1.0
local function rotate4D_XY(x, y, z, w, angle)
return x * math.cos(angle) - y * math.sin(angle),
x * math.sin(angle) + y * math.cos(angle),
z,
w
end
local function rotate4D_XZ(x, y, z, w, angle)
return x * math.cos(angle) - z * math.sin(angle),
y,
x * math.sin(angle) + z * math.cos(angle),
w
end
local function rotate4D_XW(x, y, z, w, angle)
return x * math.cos(angle) - w * math.sin(angle),
y,
z,
x * math.sin(angle) + w * math.cos(angle)
end
local function project4Dto3D(x, y, z, w)
local w_factor = 1 / (3 - w)
return x * w_factor, y * w_factor, z * w_factor
end
local vertices = {
-- Inner cube
{-1, -1, -1, -1}, {1, -1, -1, -1}, {1, 1, -1, -1}, {-1, 1, -1, -1},
{-1, -1, 1, -1}, {1, -1, 1, -1}, {1, 1, 1, -1}, {-1, 1, 1, -1},
-- Outer cube
{-1, -1, -1, 1}, {1, -1, -1, 1}, {1, 1, -1, 1}, {-1, 1, -1, 1},
{-1, -1, 1, 1}, {1, -1, 1, 1}, {1, 1, 1, 1}, {-1, 1, 1, 1}
}
local edges = {
-- Inner cube edges
{1, 2}, {2, 3}, {3, 4}, {4, 1},
{5, 6}, {6, 7}, {7, 8}, {8, 5},
{1, 5}, {2, 6}, {3, 7}, {4, 8},
-- Outer cube edges
{9, 10}, {10, 11}, {11, 12}, {12, 9},
{13, 14}, {14, 15}, {15, 16}, {16, 13},
{9, 13}, {10, 14}, {11, 15}, {12, 16},
-- Connections between cubes
{1, 9}, {2, 10}, {3, 11}, {4, 12},
{5, 13}, {6, 14}, {7, 15}, {8, 16}
}
local NUM_EDGES = #edges
local railroad_switch = NUM_EDGES * phase / (2 * math.pi)
local current_edge = math.floor(railroad_switch) + 1
local edge_phase = railroad_switch % 1
local time = step/sample_rate * ANIMATION_SPEED
if current_edge <= NUM_EDGES then
local v1 = vertices[edges[current_edge][1]]
local v2 = vertices[edges[current_edge][2]]
local x = v1[1] + (v2[1] - v1[1]) * edge_phase
local y = v1[2] + (v2[2] - v1[2]) * edge_phase
local z = v1[3] + (v2[3] - v1[3]) * edge_phase
local w = v1[4] + (v2[4] - v1[4]) * edge_phase
local fold_angle = math.sin(time) * math.pi / 2
x, y, z, w = rotate4D_XY(x, y, z, w, time)
x, y, z, w = rotate4D_XZ(x, y, z, w, time * 0.7)
x, y, z, w = rotate4D_XW(x, y, z, w, fold_angle)
x, y, z = project4Dto3D(x, y, z, w)
x = x * SCALE
y = y * SCALE
z = z * SCALE
return {x, y, z}
end
return {0, 0}