Загрузка данных


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);