with(plots):
with(plottools):
# ═══════════════════════════════════════════════════════════════
# 3D МЕНГЕРОВА ГУБКА (ФРАКТАЛ)
# ═══════════════════════════════════════════════════════════════
# Функция для создания куба из 6 квадратных граней
make_cube := proc(s, c::list)
local pts, i;
pts := [
# Нижняя грань (z = 0)
[c[1]-s/2, c[2]-s/2, c[3]-s/2],
[c[1]+s/2, c[2]-s/2, c[3]-s/2],
[c[1]+s/2, c[2]+s/2, c[3]-s/2],
[c[1]-s/2, c[2]+s/2, c[3]-s/2],
# Верхняя грань (z = s)
[c[1]-s/2, c[2]-s/2, c[3]+s/2],
[c[1]+s/2, c[2]-s/2, c[3]+s/2],
[c[1]+s/2, c[2]+s/2, c[3]+s/2],
[c[1]-s/2, c[2]+s/2, c[3]+s/2]
];
return display([
polygon([pts[1],pts[2],pts[3],pts[4]]),
polygon([pts[5],pts[6],pts[7],pts[8]]),
polygon([pts[1],pts[2],pts[6],pts[5]]),
polygon([pts[2],pts[3],pts[7],pts[6]]),
polygon([pts[3],pts[4],pts[8],pts[7]]),
polygon([pts[4],pts[1],pts[5],pts[8]])
]);
end proc:
# Рекурсивная функция Менгеровой губки
menger_sponge := proc(level, size, center)
local cubes, i, j, k, new_center, sub_size, all_cubes;
if level = 0 then
return make_cube(size, center);
end if;
cubes := [];
sub_size := size / 3;
for i from -1 to 1 do
for j from -1 to 1 do
for k from -1 to 1 do
# Пропускаем центр (срединный куб)
if (i = 0 and j = 0) or (i = 0 and k = 0) or (j = 0 and k = 0) then
next;
end if;
new_center := [
center[1] + i * sub_size,
center[2] + j * sub_size,
center[3] + k * sub_size
];
cubes := [op(cubes),
menger_sponge(level - 1, sub_size, new_center)];
end do;
end do;
end do;
return display(cubes);
end proc:
# Уровень рекурсии (1-3, больше = красивее но медленнее)
level := 2:
size := 3:
center := [0, 0, 0]:
# Создаем фрактал
fractal := menger_sponge(level, size, center):
# Раскрашиваем
colored_fractal := display(fractal, style=patch, color=cyan):
# Анимация вращения
frames := []:
for frame from 0 to 29 do
angle := frame * 2 * Pi / 29;
scene := display(colored_fractal,
orientation=[45 + frame * 3, 60 + 15 * sin(angle)],
scaling=constrained, axes=none):
frames := [op(frames), scene]:
end do:
display(frames, insequence=true);