Рисование фрактальных деревьев только с использованием функции линии - PullRequest
1 голос
/ 16 мая 2019

Я пытаюсь понять, как рисовать фрактальные деревья без каких-либо геометрических преобразований.

Я придумал этот код, но он не вращается должным образом для дальнейших веток.

void setup() {
  size(1000,1000);
  background(50);
  stroke(255);
}

void draw() {
  branch(100, width/2, height, 10, PI/2);
}

float angle = PI/6;
void branch(float size, float cx, float cy, int noi, float alpha) {

  if(noi != 0) { //Number of increments - noi
    float rx = cx + (cos(alpha) * size);
    float lx = cx - (cos(alpha) * size);
    float y = cy - (sin(alpha) * size);

    line(cx, cy, rx, y);
    line(cx, cy, lx, y);

    branch(size/2, rx, y, noi-1, alpha - angle);
    branch(size/2, lx, y, noi-1, alpha - angle);

  } else {
    return;

  }

}

Я использовал основные тригонометрические преобразования для нахождения следующей правой и левой точки. Я думаю, что я не использую правильные значения альфа для конверсий.

Прямо сейчас я получаю это

Попытка нарисовать это

Ответы [ 2 ]

1 голос
/ 16 мая 2019

Я считаю, что ваша проблема связана с управлением углами, и вы предполагаете, что rx и lx могут иметь общее y.Вот моя переделка в Python turtle:

from turtle import Screen, Turtle
from math import pi as PI, sin as sine, cos as cosine

THETA = PI / 10  # spread between branches

def branch(size, cx, cy, noi, alpha):

    rx = cx + cosine(alpha - THETA) * size
    ry = cy - sine(alpha - THETA) * size

    line(cx, cy, rx, ry)

    lx = cx + cosine(alpha + THETA) * size
    ly = cy - sine(alpha + THETA) * size

    line(cx, cy, lx, ly)

    if noi != 0:  # Number of increments - noi

        branch(size * 0.9, rx, ry, noi - 1, alpha - THETA)
        branch(size * 0.9, lx, ly, noi - 1, alpha + THETA)

def line(x0, y0, x1, y1):

    turtle.penup()
    turtle.goto(x0, y0)
    turtle.pendown()
    turtle.goto(x1, y1)

screen = Screen()
screen.setup(1000, 1000)
screen.setworldcoordinates(-500, 500, 500, -500)  # invert Y axis

turtle = Turtle(visible=False)

line(0, 400, 0, 200)  # trunk

branch(100, 0, 200, 8, PI/2)

screen.exitonclick()

В этом примере разброс ветвей является постоянной величиной, но нам все еще нужно управлять углом, под которым изгибается каждая ветвь:

enter image description here

1 голос
/ 16 мая 2019

Я решил проблему.

void setup() {
  size(1000,1000);
  background(50);
  stroke(255);
}

void draw() {
  branch(100, width/2, height/2, 10, PI/2);
}

float angle = PI/6;
void branch(float size, float cx, float cy, int noi, float alpha) {

  if(noi != 0) { //Number of increments - noi
    float rx = cx + (cos(alpha) * size);
    //float lx = cx - (cos(alpha) * size);
    float y = cy - (sin(alpha) * size);

    line(cx, cy, rx, y);
    //line(cx, cy, rx, y);

    branch(size*0.66, rx, y, noi-1, alpha - angle);
    branch(size*0.66, rx, y, noi-1, alpha + angle);

  } else {
    return;

  }

}
...