Задание 3. Фрактальное дерево
Задача - нарисовать такое дерево-фрактал:
Функция отрисовки такого дерева - рекурсивная, она должна делать следующее:
Функция рисует корневую ветку длины N. В точке где кончается эта ветка функция рекурсивно вызывает отрисовку двух других деревьев:
- Одно повернуто на 45 градусов по часовой стрелке с длиной первой ветки N/2
- Второе повернуто на 45 градусов против часовой стрелки с длиной первой ветки N/2
1) Правые ветки фрактала
Давайте сначала нарисуем более простую вещь - загогулину-веточку:
Функция отрисовки такой веточки рекурсивна. Она должна делать следующее: отрисовывает веточку длины N, двигает систему координат в конец этой ветки, поворачивает систему координат на 45 градусов и вновь вызвает себя для отрисовки на этот раз в два раза более короткой веточки.
Напоминания:
- объявите функцию
setup
чтобы настроить размер холста черезcreateCanvas
и цвет фона черезbackground
- создайте функцию отрисовки ветки (используя
translate
,rotate
иline
) - объявите функцию
draw
чтобы вызвать функцию отрисовки ветки
2) Интерактивная ветка фрактала
Давайте сделаем интерактивным изменение угла наклона каждой очередной ветки и то, во сколько раз она уменьшается:
Сначала надо открыть текстовым редактором index.html
и заменить эту строчку:
<!--<script language="javascript" src="libraries/p5.dom.js"></script>-->
На такую:
<script language="javascript" src="libraries/p5.dom.js"></script>
Теперь мы сможем создать слайдер (ползунок), который сможет интерактивно указывать значение градуса, на который каждый раз делается поворот.
Для этого достаточно доделать код следующим образом:
var slider; // Переменная в которой хранится интерактивный объект-ползунок
function setup() {
...
slider = createSlider(..., ..., ..., ...); // Создаем ползунок с аргументами: минимальное возможное значение, максимальное возможное значение, значение по умолчанию, и шаг изменения значения
}
function draw() {
// Вместо того чтобы всегда поворачивать на 45 градусов - поворачивайте на значение, которое в данный момент выбрано ползунком:
// выбранное в данный момент на ползунке значение можно узнать вызовом функции slider.value()
...
angleOfRotation = slider.value();
...
}
Теперь у нас есть ползунок, который указывает градус поворота от ветки к ветке.
Но есть проблема - старое положение всех веток оставляет след, который хотелось бы очистить - как и ранее очистка фона осуществляется вызовом background
.
3) Сам фрактал
Заметьте, что сам фрактал отличается от этой ветки лишь тем, что каждый очередной раз порождается не одна ветка - а две.
Это значит что нам надо вызвать рекурсивную функцию не один раз после поворота по часовой стрелке на сколько-то градусов, но два раза - один после поворота по часовой стрелке, второй - после поворота против часовой стрелки.
Обратите внимание, что после поворота системы координат вам ее может быть нужно восстанавливать обратно - вспомните про push()
и pop()
.
4) Развитие фрактала
Теперь можно поиграть со следующими вещами:
- Добавьте ползунок для определения значения коэффициент изменения длины ветки
- Сделайте дерево несимметричным
- Сделайте вместо двух ответвлений - N ответвлений, где N - целое число определяемое еще одним ползунком