当前,我正在尝试通过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;
}
This是我用于代码的网站。
如果有人可以帮助我或有任何想法,我将非常感谢,谢谢。
答案 0 :(得分:4)
我分享@令人惊讶的观点,我认为您使事情变得过于复杂。使用其他方法会更容易。让我们变得更容易。
使用递归函数,我们可以轻松地理解每个步骤应该执行的操作。 考虑我们从一个初始点开始,然后在给定长度的一个角度上跟踪一条线,因此我们需要像这样的功能:
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 :(得分:0)
我建议您将递归与以下功能一起使用:1)绘制当前分支(作为一行),然后2)从当前分支创建两个新分支。使用全局变量也无济于事。看来您应该重新考虑自己的方法。
答案 2 :(得分:0)
对于 Linux 是:
<%= form.submit %>