Генератор некрасивых деревьев.

Пусть у нас есть черепашка художник. Она понимает следующие команды:

F — пройти вперёд и нарисовать линию

+ — повернуться направо

− — повернуться налево

[ — запомни, где я стою и куда смотрю

] — вернись туда, где была

! - установить толщину линий.

Если она встретит неизвестный символ она его просто игнорирует.

Теперь скажем черепашке:

F[+F][-F]

Что она сделает:

F - нарисует линию (ствол)

[+F] - запомнит место, повернётся вправо, нарисует линию (веточку), вернётся назад

[-F] - запомнит место, повернётся влево и нарисует вторую веточку, вернётся назад

Как сделать более сложное дерево? Применим к нашей команде:

F[+F][-F]

правило роста:

F -> F[+F][-F]

Это значит что каждая ветка превращается в новую ветку с двумя ответвлениями. Если применить это правило один раз, получим следующую строчку:

F[+F][-F][+F[+F][-F]][-F[+F][-F]]

Если применить правило роста еще раз то получим:

F[+F][-F][+F[+F][-F]][-F[+F][-F]][+F[+F][-F][+F[+F][-F]][-F[+F][-F]]][-F[+F][-F][+F[+F][-F]][-F[+F][-F]]]

Теперь перейдем в 3D и добавим пару команд черепахи для тангажа (&), крена (/), выровнять плоскость ветви по горизонту ($) и чуть сложнее начальную команду A(1,10).

Что значит A(1,10)? Это значит что теперь мы можем записать например следующее правило:

A(x, y) -> F(x * y)

и применив его к A(1,10) получим F(10). Короче параметры в скобках добавляют в наши правила роста немного математики.

Добавим к нашей команде A(1,10) следующие правила роста:

A(l,w) → !(w)F(l)[&(a0)B(l*r2, w*wr)]/(d)A(l*r1, w*wr)

B(l,w) → !(w)F(l)[-(a2)$C(l*r2, w*wr)]C(l*r1, w*wr)

C(l,w) → !(w)F(l)[+(a2)$B(l*r2, w*wr)]B(l*r1, w*wr)

где r1, r2, wr, a0, a2, d - это просто произвольно выбранные константы.

В результате применив эти правила роста к нашей начальной команде A(1,10) мы получим описание уродливого дерева. Меняя r1, r2, wr, a0, a2, d получим разные вариации.

Подробная теория тут https://algorithmicbotany.org/

Мне это показалось интересным, может кому то для своего прожекта пригодится.

5
5 комментариев