c++ - 分形树 - 未绘制分支
问题描述
目前,我正在尝试通过 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 bottom-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;
}
推荐阅读
- javascript - 如何在Javascript中组合多个字典?
- python - python更好的方法来翻转键和值
- observablehq - 可观察的编辑器功能
- python - 在 Seaborn 散点图上标准化对象
- javascript - 使用 webrtc scaledrone 不显示远程视频
- python - 如何在时间序列分类中结合 LSTM 和 CNN
- python - 使用python在给定的相对路径创建文件
- progressive-web-apps - PWA 和 FCM 订阅群组
- c - 如何通过输入避免负数,或者如果用户输入负数程序给出错误结果?
- javascript - reactjs中如何更新挂载状态