Построение многогранника Силаши (Силаэдра)¶
В этом демонстрационном примере рассмотрено построение многогранника Силаши (Силаэдра) при помощи функции mesh3d()
из библиотеки Plots.jl
.
Введение¶
Силаэдр - это невыпуклый тороидальный многогранник, для которого выполняется следующее из характеристики Эйлера-Пуанкаре равенство
$$h = \frac{(f-4)(f-3)}{12},$$
где $f = 7$ - число граней многогранника, а $h=1$ - число дыр поверхности, в которую он вложен.
Это равенство следует из условия, что в таком многограннике каждая грань имеет общее ребро с любой другой гранью.
Силаэдр имеет 7 шестиугольных граней, 14 вершин и 21 ребро. В примере мы построим этот многогранник в декартовой системе координат по имеющимся координатам вершин.
Координаты вершин¶
Для начала введём обозначения для граней и вершин. Вершины имеют последовательные численные обозначения от 0 до 13, попарно-конгруэнтные грани имеют последовательные буквенно-численные обозначения: А1, А2, Б1, Б2, В1, В2, а непарная грань - буквенное обозначение Г.
На развертке многогранника, представленной ниже, указаны соответствующие обозначения и введена цветовая палитра, которая будет использована далее при построении силаэдра.
Добавим в рабочую область Engee переменные, характеризующие декартовы координаты вершин Силаэдра. Эти координаты определены из условий, что в начале координат располагается геометрический центр многогранника, а длина наименьшей его грани равна единице.
# Координаты вершин:
# координаты [x, y, z] № вершины
Вершины = [
[12, 0, 12], # 0
[-12, 0, 12], # 1
[0, 12.6, -12], # 2
[0, -12.6, -12], # 3
[2, -5, -8], # 4
[-2, 5, -8], # 5
[3.75, 3.75, -3], # 6
[-3.75, -3.75, -3], # 7
[4.5, -2.5, 2], # 8
[-4.5, 2.5, 2], # 9
[7, 0, 2], # 10
[-7, 0, 2], # 11
[7, 2.5, 2], # 12
[-7, -2.5, 2] # 13
];
# извлечение векторов координат вершин по осям
Вершины_матрица = Base.stack(Вершины, dims = 1);
Вершины_x = Вершины_матрица[:, 1];
Вершины_y = Вершины_матрица[:, 2];
Вершины_z = Вершины_матрица[:, 3];
В векторе Вершины
приведены вектора координат для вершин с указанными в комментариях порядковыми номерами. Для удобства их построения координаты по осям извлечены в отдельные вектора.
Соединение вершин¶
Для построения граней при помощи функции Plots.mesh3d()
необходимо определить три вектора (I, J, K) соответствующие индексы которых являются вершинами треугольника, принадлежащего грани многогранника. Так, например, в грани А1 существует 4 непересекающихся треугольника, образованных вершинами 0-10-12, 0-4-10, 4-2-10 и 4-3-2.
Таким образом разобьём каждую грань силаэдра на непересекающиеся треугольники, а образующие их вершины запишем в соответствующие индексы векторов I, J, K. Для корректного отображения цветовой заливки граней при построении, вершины треугольников следует вносить в вектора не меняя направления обхода вершин для одной грани.
# разбиение граней на треугольники:
# грань А1 (состоит из треугольников 0-10-12, 0-4-10, 4-2-10, 4-3-2)
А1_i = [0, 0, 4, 4];
А1_j = [10, 4, 2, 3];
A1_k = [12, 10, 10, 2];
Соединения_А1 = (А1_i, А1_j, A1_k);
# грань А2
А2_i = [1, 1, 5, 5];
А2_j = [11, 5, 3, 2];
A2_k = [13, 11, 11, 3];
Соединения_А2 = (А2_i, А2_j, A2_k);
# грань Б1
Б1_i = [0, 0, 0, 4];
Б1_j = [8, 1, 13, 8];
Б1_k = [4, 13, 8, 7];
Соединения_Б1 = (Б1_i, Б1_j, Б1_k);
# грань Б2
Б2_i = [1, 1, 1, 5];
Б2_j = [9, 0, 12, 9];
Б2_k = [5, 12, 9, 6];
Соединения_Б2 = (Б2_i, Б2_j, Б2_k);
# грань В1
В1_i = [10, 10, 10, 5];
В1_j = [8, 7, 6, 2];
В1_k = [7, 6, 2, 6];
Соединения_В1 = (В1_i, В1_j, В1_k);
# грань В2
В2_i = [11, 11, 11, 7];
В2_j = [9, 6, 7, 4];
В2_k = [6, 7, 3, 3];
Соединения_В2 = (В2_i, В2_j, В2_k);
# грань Г
Г_i = [11, 10, 8, 8];
Г_j = [8, 9, 11, 9];
Г_k = [13, 12, 9, 10];
Соединения_Г = (Г_i, Г_j, Г_k);
# вектора значений для построения граней
Соединения = [Соединения_А1, Соединения_А2, Соединения_Б1,
Соединения_Б2, Соединения_В1, Соединения_В2, Соединения_Г];
Радуга = [:red, :orange, :yellow, :green, :cyan, :blue, :purple];
Подпись = ["A1", "A2", "Б1", "Б2", "В1", "В2", "Г" ];
Полученные вектора объединены в кортежи для передачи в функцию mesh3d()
, определены переменные цветовой палитры и обозначения граней многогранника.
Построение силаэдра¶
Подключаем библиотеку Plots.jl
и бэкэнд для построения:
# подключение библиотеки и бэкенда
using Plots;
plotly();
Введём функцию Грань()
для построения вершин и граней по индексу:
# функция для построения вершин и граней
function Грань(номер)
if номер == 0
Plots.scatter3d(Вершины_x, Вершины_y, Вершины_z;
label="вершины", color = :black, markersize = 1,
xlabel = "x", ylabel = "y", zlabel = "z",
camera = (130, 20))
else
Plots.mesh3d!(Вершины_x, Вершины_y, Вершины_z;
connections = Соединения[номер],
color = Радуга[номер], label = Подпись[номер])
end
end;
Построим вершины и полученные грани в цикле:
# построение вершин
Plots.scatter3d(Вершины_x, Вершины_y, Вершины_z;
label="вершины", color = :black, markersize = 1)
# построение граней в цикле
for N in 1:7
Грань(N)
end
# оформление сцены
plot!(xlabel = "x", ylabel = "y", zlabel = "z", camera = (130, 20))
Подключенный бэкэнд обеспечивает построение многогранника с высокой интерактивностью. Силаэдр можно масштабировать, вращать, включать и отключать отображение элементов (граней и вершин).
В заключение создадим анимацию последовательного построения граней силаэдра:
# анимация последовательного построения граней
анимация = @animate for N in [0, 7, 6, 5, 2, 1, 3, 4]
Грань(N)
end;
gif(анимация, "Силаэдр.gif", fps = 1)
Заключение¶
В этом примере мы рассмотрели построение многогранника Силаши по координатам при помощи функции mesh3d()
из библиотеки Plots.jl
.