Я пытаюсь рисовать дерево с помощью рекурсии. Дерево должно выглядеть следующим образом:Рисование дерева с использованием рекурсии
Краткое резюме о том, как я должен это сделать:
- ствол дерева имеет длину
length
и ширинаwidth
- Тунец разделяется на две ветви
- Левый имеет 3/4 длины ствола и правый 2/3 длины ствола
- левой ширина ветвь 3/4 ширины ствола и правая ширина ветвь 1/2 ширины ствола
- Параметры, которые мы получаем: длина, min_length, ширину, альфа (все парное)
- ветви растет до тех пор, пока ветви не будут длиннее min_length
Вот как я решил проблему. Я хотел просто нарисовать сундук, левую ветвь и правую ветвь. Мне удалось это сделать с помощью следующей функции:
public void drawTree(double length, double min_length, double width, double alpha) {
//Draws the trunk of the tree
StdDraw.setPenRadius(width);
StdDraw.line(250, 150, 250, 150+length);
//Left branch
double hypotenuse = (3.0/4.0)*length;
double opposite = Math.sin(alpha) * hypotenuse;
double adjacent = Math.sqrt(Math.pow(hypotenuse, 2)-Math.pow(opposite, 2));
StdDraw.setPenRadius(width*3.0/4.0);
StdDraw.line(250,150+length,250-adjacent,150+length+opposite);
//Right branch
double hypotenuse2 = (2.0/3.0)*length;
double opposite2 = Math.sin(alpha) * hypotenuse2;
double adjacent2 = Math.sqrt(Math.pow(hypotenuse2, 2)-Math.pow(opposite2, 2));
StdDraw.setPenRadius(width*1.0/2.0);
StdDraw.line(250,150+length,250+adjacent2,150+length+opposite2);
}
Это выход, и это так же, как я хотел, чтобы это было:
Я думал, остальное будет легко, но за последние 3 часа я ничего не добился: /. Я включил оператор if для условия остановки. Но я не имею представления об рекурсивной части. Я попытался это:
if (length > min_length) {
//Left branch
double hypotenuse = (3.0/4.0)*length;
double opposite = Math.sin(alpha) * hypotenuse;
double adjacent = Math.sqrt(Math.pow(hypotenuse, 2)-Math.pow(opposite, 2));
StdDraw.setPenRadius(width*3.0/4.0);
StdDraw.line(250,150+length,250-adjacent,150+length+opposite);
//Right branch
double hypotenuse2 = (2.0/3.0)*length;
double opposite2 = Math.sin(alpha) * hypotenuse2;
double adjacent2 = Math.sqrt(Math.pow(hypotenuse2, 2)-Math.pow(opposite2, 2));
StdDraw.setPenRadius(width*1.0/2.0);
StdDraw.line(250,150+length,250+adjacent2,150+length+opposite2);
//My first attempt
drawTree(hypotenuse*hypotenuse, min_length, width, alpha);
drawTree(hypotenuse2*hypotenuse2, min_length, width, alpha);
//My second attempt
drawTree(hypotenuse, min_length, width, alpha);
drawTree(hypotenuse2, min_length, width, alpha);
}
Я понимаю простую рекурсию, как факториалы, палиндром, и т.д., но я застрял на этом, и я был бы признателен за любую помощь.
Вы кажетесь жесткого кодирования точек чертежа, то, что вы не можете сделать, так как их расположение будет относительным к начальной точке, текущей длине ветви и начальному углу. Вместо этого сосредоточьтесь на том, что потребуется для рисования произвольной ветви дерева. Сначала проведите это на бумаге, а не в коде. –
@HovercraftFullOfEels Теперь это делается на бумаге. Я думал о создании переменных x0, y0, x1 и y1. Сначала я задаю им те же значения, с которых я начинаю, а затем обновляю их соответственно. x0 - x1 после того, как мы проведем линию, y0 - y1 ... Я иду в правильном направлении? В настоящий момент x0 вообще не изменяет значение, поэтому это (часть) проблемы? – mythic
Я бы начал с того, что нужно передать в метод 'createBranch (...)'. Возможно, int generationNumber (чтобы вы могли остановить рекурсию при достижении MAX_GENERATION), double angle и double branchLength. Вам также понадобится двойная константа SCALE, которая используется для уменьшения размера следующей ветви. –