简体   繁体   English

分形树 - 未绘制的分支

[英]Fractal Tree - branches not drawn

Currently, I'm trying to draw a symmetric binary tree through IFS (Iterated Function Systems): 目前,我正在尝试通过IFS(迭代函数系统)绘制对称二叉树:

but the result is always only the branch tips: 但结果总是只有分支提示:

.

I can't figure out what I'm doing wrong or what I'm missing. 我无法弄清楚我做错了什么或我错过了什么。

This is the IFS: 这是IFS:

这里

This is my code: 这是我的代码:

RenderWindow window(VideoMode(480, 640), "fractals everywhere");
CircleShape point(1);
int chance;
float x, y, w, h, nx, ny, px, py;

void SymmetricBinaryTrees()
{
    float r = 0.57f;
    float o = 0.785f;

    chance = rand() % 3;

    switch (chance)
    {
    case 0:
        nx = r * cos(o) * x + (-1 * r * sin(o) * y);
        ny = r * sin(o) * x + r * cos(o) * y + 1;
        break;
    case 1:
        nx = r * cos(o) * x + r * sin(o) * y;
        ny = -1 * r * sin(o) * x + r * cos(o) * y + 1;
        break;
    case 2:
        nx = x;
        ny = y;
        break;
    }
}

void nextPoint()
{
    SymmetricBinaryTrees();

    x = nx; y = ny;
}

void drawPoint()
{
    px = _map(x, -1.078, 1.078f, 0, w); py = _map(y, 0.f, 2.078f, h, 0); // maps the position accordingly
    point.setPosition(px, py);

    window.draw(point);
}

int main()
{
    srand(time(NULL));

    w = window.getSize().x * 1.f;
    h = window.getSize().y * 1.f;

    x = 0.f; y = 0.f;

    window.setFramerateLimit(60);

    while (window.isOpen())
    {
        Event e;

        while (window.pollEvent(e))
            if (e.type == Event::Closed) window.close();

        for (int i = 1; i <= 500; i++)
        {
            drawPoint();
            nextPoint();
        }

        window.display();
    }
    return 0;
}

This is the website that I'm using for my code. 是我用于我的代码的网站。

If anyone could help me or has any idea I'd be very grateful, thank you. 如果有人能帮助我或有任何想法我会非常感激,谢谢。

I share @beyond opinion, I think you're complicating things too much. 我赞同@beyond意见,我认为你太复杂了。 It will be easier with a different approach. 使用不同的方法会更容易。 Let's make things easier. 让我们更轻松。

With a recursive function, we can easily understand what should be done each step. 使用递归函数,我们可以轻松了解每一步应该做什么。 Consider we start from a initial point , then trace a line on an angle of a given lenght , so we need a function like: 考虑我们从一个初始点开始,然后在一个给定长度角度上追踪一条线 ,所以我们需要一个像下面这样的函数:

void createTreeRecursive(sf::VertexArray &tree, sf::Vector2f point, float angle, float lenght)

Where tree will be our line set, which compose the tree itself. tree将成为我们的行集,它组成了树本身。

First thing we can do, is to set the first point, which is already known: 我们能做的第一件事就是设置第一点,这是已知的:

// Add first point
tree.append(sf::Vertex(point, treeColor));

Now we need to calculate our next point, to form a line. 现在我们需要计算下一个点,形成一条线。 With simple trigonometric functions we can determine that point: 使用简单的三角函数,我们可以确定这一点:

float newX = point.x + (cos((2.f * PI / 360.f) * angle) * lenght);
float newY = point.y - (sin((2.f * PI / 360.f) * angle) * lenght);  // Caution here! Minus(-) sign because we're drawing upwards

So we add this second point, and then split the tree into 2 new branches, each one rotated some certain degrees: 所以我们添加第二个点,然后将树分成2个新的分支,每个分支旋转一定程度:

// Add second point
tree.append(sf::Vertex(nextPoint, treeColor));

// Create sub-tree from 2nd point, rotating +45 degrees (i.e. counterclockwise), reducing lenght of the new branch by 0.6 factor
createTreeRecursive(tree, nextPoint, angle + O, lenght * R);

// Same with the other sub-tree, but rotating -45 (i.e. clockwise)
createTreeRecursive(tree, nextPoint, angle - O, lenght * R);

We need a base case for our recursive function, in this case, I choose 3 as minimum lenght: 我们需要一个基本情况来处理递归函数,在这种情况下,我选择3作为最小长度:

if (lenght < 3)
    // End condition, can be modified
    return;

this must be out first check. 这必须首先检查。

So we're done, we only need the initial call: 所以我们完成了,我们只需要初始调用:

sf::VertexArray createTree(){
    // Our tree will be made out of lines
    sf::VertexArray ret(sf::PrimitiveType::Lines);
    // Initial point at botton-center(250, 450), with a 90 degrees rotation, first branch lenght 200 
    createTreeRecursive(ret, sf::Vector2f(250, 450), 90, 200);
    return ret;
}

And the result is: 结果是:

在此输入图像描述

Full code 完整代码

#include <SFML/Graphics.hpp>

const double PI = 3.141592;
const double R = 0.57;  // Reduction factor
const double O = 45;    // Degree rotation each time
sf::Color treeColor = sf::Color::Blue;

void createTreeRecursive(sf::VertexArray &tree, sf::Vector2f point, float angle, float lenght){
    if (lenght < 3)
        // End condition, can be modified
        return;

    // Add first point
    tree.append(sf::Vertex(point, treeColor));
    float newX = point.x + (cos((2.f * PI / 360.f) * angle) * lenght);
    float newY = point.y - (sin((2.f * PI / 360.f) * angle) * lenght);  // Caution here! Minus(-) sign because we're drawing upwards
    sf::Vector2f nextPoint(newX, newY);
    // Add second point
    tree.append(sf::Vertex(nextPoint, treeColor));

    // Create sub-tree from 2nd point, rotating +45 degrees (i.e. counterclockwise), reducing lenght of the new branch by 0.6 factor
    createTreeRecursive(tree, nextPoint, angle + O, lenght * R);

    // Same with the other sub-tree, but rotating -45 (i.e. clockwise)
    createTreeRecursive(tree, nextPoint, angle - O, lenght * R);
}

sf::VertexArray createTree(){
    // Our tree will be made out of lines
    sf::VertexArray ret(sf::PrimitiveType::Lines);
    // Initial point at botton-center(250, 450), with a 90 degrees rotation, first branch lenght 200 
    createTreeRecursive(ret, sf::Vector2f(250, 450), 90, 200);
    return ret;
}

int main()
{
    RenderWindow window({ 500, 500 }, "SFML Tree", Style::Close);

    auto tree = createTree();

    while (window.isOpen())
    {
        for (Event event; window.pollEvent(event);){
            if (event.type == Event::Closed)
                window.close();
        }

        window.clear();
        window.draw(tree);
        window.display();
    }
    return EXIT_SUCCESS;
}

I would advice you to use recursion with a function that 1) draws the current branch (as a line), and then 2) creates two new branches from the current branch. 我建议你使用一个函数递归,1)绘制当前分支(作为一行),然后2)从当前分支创建两个新的分支。 Using global variables doesn't help you either. 使用全局变量也无济于事。 Looks like you should rethink your approach. 看起来你应该重新考虑你的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM