簡體   English   中英

分形樹 - 未繪制的分支

[英]Fractal Tree - branches not drawn

目前,我正在嘗試通過IFS(迭代函數系統)繪制對稱二叉樹:

但結果總是只有分支提示:

我無法弄清楚我做錯了什么或我錯過了什么。

這是IFS:

這里

這是我的代碼:

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;
}

是我用於我的代碼的網站。

如果有人能幫助我或有任何想法我會非常感激,謝謝。

我贊同@beyond意見,我認為你太復雜了。 使用不同的方法會更容易。 讓我們更輕松。

使用遞歸函數,我們可以輕松了解每一步應該做什么。 考慮我們從一個初始點開始,然后在一個給定長度角度上追蹤一條 ,所以我們需要一個像下面這樣的函數:

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

tree將成為我們的行集,它組成了樹本身。

我們能做的第一件事就是設置第一點,這是已知的:

// 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

所以我們添加第二個點,然后將樹分成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);

我們需要一個基本情況來處理遞歸函數,在這種情況下,我選擇3作為最小長度:

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

這必須首先檢查。

所以我們完成了,我們只需要初始調用:

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;
}

結果是:

在此輸入圖像描述

完整代碼

#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;
}

我建議你使用一個函數遞歸,1)繪制當前分支(作為一行),然后2)從當前分支創建兩個新的分支。 使用全局變量也無濟於事。 看起來你應該重新考慮你的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM