Красавин Компютерныы практикум в среде МатЛаб 2015
.pdfПример 21.3. function menger(n)
switch nargin % при отсутствии входных аргументов case 0
n = 2; % порядок губки будет выбран по умолчанию 2
end
figure % рис. 21.2
%расчет матрицы, состоящей из нулей и единиц, которые обозначают присутствие или отсутствие кубов размера, соответствующего текущей итерации
%M - конечная матрица
M = 0; % единичный куб
for k = 1 : n
%создание куба А, в 3 раза превосходящего куб М по каждому
измерению
A = zeros([3^k, 3^k, 3^k]);
%на нижней грани куба А вырезается куб размера М
A(:,:,1:3^(k-1)) = [M,M,M; M,ones(size(M)),M; M,M,M];
%в кубе A вырезается крест из пяти кубов M
A(:,:,3^(k-1)+1:2*3^(k-1)) = ...
[M,ones(size(M)),M; ...
ones(size(M)),ones(size(M)),ones(size(M));...
M,ones(size(M)), M];
% на верхней грани куба А вырезается куб размера М
A(:,:,2*3^(k-1)+1:3^k) = [M,M,M; M,ones(size(M)),M; M,M,M];
M=A; % получившейся фигуре присваивается имя M для следующей итерации
end
% преобразование матрицы (куба) M в 3D–изображение
hold on d = 1;
241
Рис. 21.2. Губки Менгера первого, второго и третьего порядков
242
% цикл по всем ячейкам матрицы (куба) М for i = 1:3^n
for j = 1:3^n
for k = 1:3^n
% проверка наличия куба if M(i,j,k) == 0
cube(i,j,k,d,n); % вызывается функция прорисовки куба
end
end
end
end
axis equal; axis off; hold off;
view(3); hold off;
function cube(i,j,k,d,n)
%Функция прорисовки малого куба
%d – отношение размера малого куба к размеру губки;
%значение d = 1 эквивалентно всей губке Менгера
%i,j,k – координаты куба
%n – номер итерации
%координаты граней куба (полигоны):
X = [0 0 0 0 0 1; ... |
% каждый столбец массива задает координаты |
||||||
1 |
|
0 |
1 |
|
1 1 |
1; ... |
% в трехмерном пространстве, |
соответствующие |
1; ... |
% координатам вершин граней куба |
|||||
1 |
0 |
1 |
1 |
1 |
|||
0 |
0 |
0 |
0 |
0 |
1]; |
% 6 граней у куба == 6 столбцов у массива |
|
Y = [0 0 0 0 1 0; ... |
|
|
|||||
0 |
1 |
0 |
0 |
1 |
1; ... |
|
|
0 |
1 |
1 |
1 |
1 |
1; ... |
|
|
0 |
0 |
1 |
1 |
1 |
0]; |
|
|
Z = [0 0 1 0 0 0; ... |
|
|
|||||
0 |
0 |
1 |
0 |
0 |
0; ... |
|
|
1 |
1 |
1 |
0 |
1 |
1; ... |
|
|
1 |
1 |
1 |
0 |
1 |
1]; |
|
|
243
%задание градиента для граней куба
%каждый столбец массива задает значения цвета в вершине грани куба; между вершинами происходит плавный цветовой переход, тем
самым моделируется градиент; |
в данной реализации задняя грань |
губки не будет видна, однако |
она становится видна при изменении |
угла обзора при помощи функции |
view |
C = [0.1 0.84 1.1 1.1 0.1 0.84 |
; ... |
0.20.86 1.2 1.2 0.2 0.86 ; ...
0.30.88 1.3 1.3 0.3 0.88 ; ...
0.40.90 1.4 1.4 0.4 0.90 ];
%создание куба размера d с центральной точкой (i,j,k)
%и сокращение его размеров до 3^(-n)
X= (d*(X-0.5) + i)/3^n;
Y= (d*(Y-0.5) + j)/3^n;
Z= (d*(Z-0.5) + k)/3^n;
% прорисовка куба fill3(X,Y,Z,C);
Задания
21.1.Модифицировать код из примера 21.2 и построить квадратный ковер Серпинского.
21.2.Модифицировать код из примера 21.3 и построить пирамидальную губку Менгера.
244
22
L-Системы
Понятие L-систем было введено в 1968 г. А. Линденмайером; первоначально они использовались при изучении формальных языков, а также в биологических моделях [5].
L-Системой называется набор, состоящий из алфавита, аксиомы и нескольких правил.
Алфавитом называется конечное множество, а его элементы – символами. Природа символов не важна, их единственная функция – отличаться друг от друга. Строкой алфавита называется конечная последовательность символов алфавита.
Аксиома – некоторая строка алфавита.
Каждое правило – пара, состоящая из предшественника и последователя. Предшественник – символ алфавита, а последователь – строка алфавита, например A → FA + A (стрелка отделяет предшественника от последователя). В списке правил символы-предшественники должны быть уникальными.
Как только L-система определена, она начинает развиваться в соответствии со своими правилами. Начальным состоянием L- системы является ее аксиома. При дальнейшем развитии эта строка, описывающая состояние, будет меняться. Развитие L- системы происходит циклически. В каждом цикле развития строка просматривается от начала к концу, символ за символом. Для каждого символа ищется правило, для которого этот символ служит предшественником. Если такого правила нет, символ оставляется без изменений. Если же соответствующее правило найдено, символ-предшественник заменяется на строкупоследователь из этого правила.
L-Системы находят применение при моделировании процессов роста как живых организмов, так и неживых объектов (например, кристаллов, раковин моллюсков или пчелиных сот). Для иллюстрации рассмотрим следующую L-систему (она называется
245
Algæ – водоросль, поскольку ее развитие моделирует рост одного из видов водорослей):
Аксиома Правила
Ниже приведены состояния этой системы после шести циклов развития.
Цикл
0
1
2
3
4
5
Можно заметить, что каждая следующая строка получается конкатенацией двух предыдущих строк.
Для моделирования L-системы требуется придать смысл символам ее алфавита. Для графического представления L-систем символы алфавита интерпретируются на «черепашьем» языке, который состоит из следующих команд:
–продвинуться на один шаг вперед, рисуя за собой след;
–продвинуться на один шаг вперед, не рисуя за собой след; [ – открыть ветвь; ] – закрыть ветвь;
+– увеличить угол на величину θ;
– – уменьшить угол на величину . |
|
||
В начале моделирования |
черепаха находится в некоторой точке |
||
θ |
|
||
плоскости |
и смотрит в направлении начального угла . |
На |
|
первом цикле, |
черепаха прописывает на плоскости аксиомуα. |
На |
каждом следующем шаге цикла символы в текущей строке заменяются в соответствии с правилами.
Иногда используют вспомогательные переменные |
|
, |
которые не предусматривают изменения состояния черепахи, |
, |
,но |
позволяют ввести несколько порождающих правил в L-систему.
246
Псевдокод для порождающих правил |
символ в строке |
|
выглядит следующим образом (здесь |
– -йnew ; |
new |
;– строка , к которой присоединен знак +):
Вход:
axiom (слово инициализации) newF (порождающее правило) newX (порождающее правило) level (число итераций)
Выход:
word (строка-результат)
Инициализация: W = axiom
n = length(W)
T = {} (пустое множество)
Шаги:
while level > 0 for j = 1 to n
if W(j) = +, T = {T +}, end if if W(j) = –, T = {T –}, end if if W(j) = [, T = {T [}, end if if W(j) = ], T = {T ]}, end if if W(j) = F, T = {T newF}, end if if W(j) = X, T = {T newX}, end if
end for W = T
level = level – 1 end while
word = W
Пример 22.1 иллюстрирует реализацию приведенного кода на языке MatLab для построения Дракона Хартера–Хейтуэя [4]. Дракон задается следующими правилами:
Аксиома: Порождающие правила:
New
New
New – –
Соответственно, для первых нескольких шагов L-система будет иметь следующий вид:
247
Первый шаг: |
– |
– |
– |
– – – |
|
Второй шаг: |
|||||
Третий шаг: |
|||||
– |
– |
|
|
Пример 22.1.
function [X,Y]=dragon(Lmax)
%функция, возвращающая изображение дракона
%Lmax – порядок максимальной итерации
%порождающие правила
Axiom='FX';
Newf='F';
Newx='X+YF+'; Newy='-FX-Y'; teta=pi/2; alpha=0;
p=[0;0]; % координата стартовой точки
%обращение к функции, возвращающей координаты вершин дракона p=Coord(p,Lmax,Axiom,Newf,Newx,Newy,alpha,teta);
%визуализация
M=size(p,2); % число точек
X=p(1:1,1:M); % вектор, содержащий x-координаты вершин дракона Y=p(2:2,1:M); % вектор, содержащий y-координаты вершин дракона
figure;
plot(X,Y,'Color','r','LineWidth',2); set(gca,'XTick',[]) % отключение отметок по оси x
set(gca,'XTickLabel',[]) % отключение обозначений координат по оси x
set(gca,'YTick',[])
set(gca,'YTickLabel',[])
% функция, возвращающая координаты вершин дракона function z=Coord(p,Lmax,Axiom,Newf,Newx,Newy,alpha,teta)
Rule=DraconString(Lmax,Axiom,Newf,Newx,Newy,1,''); % задание L-
системы
M=length(Rule); for i=1:M
tmp=p(1:2,size(p,2):size(p,2));
if Rule(i)=='F' % шаг вперед R=[cos(alpha);sin(alpha)];
R=R/(2^Lmax); % масштабирование рисунка в зависимости от числа итераций
248
tmp=tmp+R;
p=cat(2,p,tmp); end
if Rule(i)=='+' % увеличение угла alpha=alpha+teta;
end
if Rule(i)=='-' % уменьшение угла alpha=alpha-teta;
end end z=p;
% функция, возвращающая L-систему
function z=DraconString(Lmax,Axiom,Newf,Newx,Newy,n,tmp_str)
if n <= Lmax if n==1
tmp_str=Axiom; end
M=length(tmp_str);
tmp=''; % создание пустой строки
for i=1:M
if tmp_str(i)=='F' tmp=strcat(tmp,Newf);
end
if tmp_str(i)=='X' tmp=strcat(tmp,Newx);
end
if tmp_str(i)=='Y' tmp=strcat(tmp,Newy);
end
if not(tmp_str(i)=='F') && not(tmp_str(i)=='X') && not(tmp_str(i)=='Y')
tmp=strcat(tmp,tmp_str(i)); end
end
tmp_str=tmp; n=n+1;
tmp_str=DraconString(Lmax,Axiom,Newf,Newx,Newy,n,tmp_str); %
рекурсия end z=tmp_str;
249
На рис. 22.1 показан Дракон Хартера–Хейтуэя для различного числа итераций. Время расчета L-системы очень быстро увеличивается с ростом числа итераций.
Рис. 22.1. Дракон Хартера–Хейтуэя для различного числа итераций
250