[笔记]使用SFML来生成分形图片

article/2025/9/30 13:27:47

前言

最近在上《优秀科普纪录片》时,看了一部有关 分形 的纪录片,在观看的过程中,想着自己也来生成一些分形图片,正好偶然了解到了SFML这个简单的图形库,所以天时地利人和,正好查一些资料来学习一下。

以下代码都是使用到SFML库的C++代码,所以如果要尝试使用的话,首先要配置好环境(我上一篇有介绍Cmake的配置方式,可以参考)

三分线段


看图就明白了吧。。


#include <iostream>
#include <cmath>
#include <SFML/Graphics.hpp>using namespace std;sf::RenderWindow window(sf::VideoMode(1920,1080), "Tree");
float base = 100;
void getNextLine(float ax, float ay, float bx, float by, float len){if(len < 0.1f)return;float cx, cy, dx, dy, newLen;newLen = len / 3.0;cx = ax + newLen; cy = ay + base;dx = bx - newLen; dy = by + base;getNextLine(ax, ay + base, cx, cy, newLen);getNextLine(dx, dy, bx, by + base, newLen);sf::Vertex line[] = {sf::Vertex(sf::Vector2f(ax, ay), sf::Color::Cyan),sf::Vertex(sf::Vector2f(bx, by), sf::Color::Cyan)};window.draw(line, 2, sf::Lines);return;
}int main(){window.clear();getNextLine(300, 300, 1600, 300, 1300);window.display();sf::Event event;while (window.isOpen()){while (window.pollEvent(event)){if (event.type == sf::Event::Closed) window.close();}}return 0;
}

分形树 FractralTree


这个生成的方式很简单,就是每次对一条线段取 2 3 \frac{2}{3} 32 然后对角度 + 60 和 − 30 +60和-30 +6030 来的到下一个线段的位置,不断地递归下去即可。


#include <iostream>
#include <cmath>
#include <SFML/Graphics.hpp>using namespace std;sf::RenderWindow window(sf::VideoMode(1920,1080), "Tree");void start(float inix, float iniy, float degree, float length)
{if (length < 1.0f) return;else{float newlength=0.67f * length;float finx = inix + (newlength * (float)cos(degree * (3.14 / 180.0f)));float finy = iniy + (newlength * (float)sin(degree * (3.14 / 180.0f)));sf::Vertex line[]= {sf::Vertex(sf::Vector2f(inix, iniy)),sf::Vertex(sf::Vector2f(finx, finy))};start(finx, finy, degree+60.0f, newlength);start(finx, finy, degree-30.0f, newlength);window.draw(line, 2, sf::Lines);//line.setFillColor(sf::Color::Blue);//window.display(); // Uncomment for animation}
}int main()
{window.clear();start(1000, 799, -90, 350);window.display();sf::Event event;while (window.isOpen()){while (window.pollEvent(event)){if (event.type == sf::Event::Closed) window.close();}}return 0;
}

Koch雪花


#include <iostream>
#include <cmath>
#include <SFML/Graphics.hpp>
const double pi = 3.1415926;
using namespace std;sf::RenderWindow window(sf::VideoMode(1920,1080), "Tree");
float base = 100;
void getNextLine(float ax, float ay, float bx, float by){float len = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));if(len < 1.0f){sf::Vertex line[] = {sf::Vertex(sf::Vector2f(ax, 1200 - ay), sf::Color::Cyan),sf::Vertex(sf::Vector2f(bx, 1200 - by), sf::Color::Cyan)};window.draw(line, 2, sf::Lines);return;	}float cx, cy, dx, dy, ex, ey, newLen;newLen = len / 3.0;cx = ax + (bx - ax) / 3; cy = ay + (by - ay) / 3;dx = bx - (bx - ax) / 3; dy = by - (by - ay) / 3;// float x = dx - cx, y = dy - cy;// ex = x * cos(pi / 3) - y * sin(pi / 3) + cx;// ey = x * sin(pi / 3) + y * cos(pi / 3) + cy;float a = atan((dy - cy)/(dx - cx));if(dx - cx < 0)a += pi;ex = cx + cos(a + pi/3) * newLen;ey = cy + sin(a + pi/3) * newLen; getNextLine(ax, ay, cx, cy);getNextLine(cx, cy, ex, ey);getNextLine(ex, ey, dx, dy);getNextLine(dx, dy, bx, by);return;
}int main(){window.clear();getNextLine(300, 600, 1600, 600);window.display();sf::Event event;while (window.isOpen()){while (window.pollEvent(event)){if (event.type == sf::Event::Closed) window.close();}}return 0;
}

当然计算ex, ey可以通过向量来搞

float x = dx - cx, y = dy - cy;
ex = x * cos(pi / 3) - y * sin(pi / 3) + cx;
ey = x * sin(pi / 3) + y * cos(pi / 3) + cy;

H树


关于H树的简介看这里


#include <iostream>
#include <cmath>
#include <SFML/Graphics.hpp>
const double pi = 3.1415926;
using namespace std;sf::RenderWindow window(sf::VideoMode(1920,1080), "Tree");const float s2 = sqrt(2);
int num = 100;
void getNextLine(float x, float y, float len, bool v){if(len < 5.0f)return;// if(num-- < 0)return;float ax, ay, bx, by, newLen;newLen = len / s2;if(v){ax = x; ay = y - newLen;bx = x; by = y + newLen;}else{ax = x - newLen; ay = y;bx = x + newLen; by = y;}getNextLine(ax, ay, newLen, !v);getNextLine(bx, by, newLen, !v);sf::Vertex line1[] = {sf::Vertex(sf::Vector2f(ax, ay), sf::Color::Cyan),sf::Vertex(sf::Vector2f(bx, by), sf::Color::Cyan)};window.draw(line1, 2, sf::Lines);return;
}int main(){window.clear();getNextLine(1000, 600, 300, 0);window.display();sf::Event event;while (window.isOpen()){while (window.pollEvent(event)){if (event.type == sf::Event::Closed) window.close();}}return 0;
}

当然你愿意搞得花里胡哨的话也不是不行


#include <iostream>
#include <cmath>
#include <SFML/Graphics.hpp>
#include<windows.h>
const double pi = 3.1415926;
using namespace std;sf::RenderWindow window(sf::VideoMode(1920,1080), "Tree");const float s2 = sqrt(2);
float minLen = 500.0f;
const int maxn = 1e5 + 5;
struct lines{sf::Vertex line[2];
}lines[maxn];
int num = 0;
sf::Color colors[] = {sf::Color::Cyan, sf::Color::Red, sf::Color::Green, sf::Color::Yellow, sf::Color::White};
int c = 0;
void getNextLine(float x, float y, float len, bool v){if(len < minLen)return;// if(num-- < 0)return;float ax, ay, bx, by, newLen;newLen = len / s2;if(v){ax = x; ay = y - newLen;bx = x; by = y + newLen;}else{ax = x - newLen; ay = y;bx = x + newLen; by = y;}getNextLine(ax, ay, newLen, !v);++c; c %= 5;getNextLine(bx, by, newLen, !v);++c; c %= 5;// sf::Vertex line1[] = {// 	sf::Vertex(sf::Vector2f(ax, ay), sf::Color::Cyan),// 	sf::Vertex(sf::Vector2f(bx, by), sf::Color::Cyan)// };// lines[num].line[0] = sf::Vertex(sf::Vector2f(ax, ay), sf::Color::Cyan);// lines[num].line[1] = sf::Vertex(sf::Vector2f(bx, by), sf::Color::Cyan);lines[num].line[0] = sf::Vertex(sf::Vector2f(ax, ay), colors[c]);lines[num].line[1] = sf::Vertex(sf::Vector2f(bx, by), colors[c]);++num;// ++c; c %= 5;// window.draw(line1, 2, sf::Lines);return;
}
// int lnum = 0;
void dispaly(){// lnum = num;num = 0;getNextLine(1000, 600, 300, 0);minLen -= 5.0f;if(minLen < 5)minLen = 500;// if(num >= lnum * 2){// 	++c; c %= 5;// }
}
int main(){// window.clear();// getNextLine(1000, 600, 300, 0);// window.display();dispaly();sf::Clock clock;float timer = 0, delay = 0.1, time;sf::Event event;while (window.isOpen()){time = clock.getElapsedTime().asSeconds();timer += time;clock.restart();while (window.pollEvent(event)){if (event.type == sf::Event::Closed) window.close();}if(timer > delay){dispaly();timer = 0;}window.clear();for(int i = 0; i < num; ++i){window.draw(lines[i].line, 2, sf::Lines, sf::RenderStates::Default);}window.display();}return 0;
}

Julia集合

下面这份代码没有很好的调参,,所以,生成的图片也不怎么好看,等有时间修改一下在说吧。。


#include <iostream>
#include <cmath>
#include <SFML/Graphics.hpp>
#include<windows.h>
#include<complex>
const double pi = 3.1415926;
using namespace std;sf::RenderWindow window(sf::VideoMode(1920,1080), "Tree");sf::Color colors[10];
int col = 0;
void init(){for(int i = 0; i < 10; ++i){// colors[i] = sf::Color((128 - rand() % 128) + rand() % 128, (128 + rand() % 128) - rand() % 64, (100 + rand() % 120) - rand() % 100);// colors[i] = sf::Color((255 - rand() % 10 * i), (255 - rand() % 15 * i), (128 + rand() % 10 * i) % 255);colors[i] = sf::Color(i * 13, i * rand() % 255, i * 17);}
}
int getColor(double z){for(int i = 9; i >= 0; --i){// cout << i << endl;if(z <= 1.0 / (1 << i))return i;}return 0;
}
complex<double> c(-0.77097, -0.08545);
const int iter_max = 20;
complex<double> iter(complex<double> z){// cout << z << endl;for(int i = 1; i <= iter_max; ++i){z = z * z + c;if(std::abs(z) * std::abs(z) > 2)return z;}return z;
}void drawText(string s){// Declare and load a fontsf::Font font;cout << s << endl;font.loadFromFile("./res/consola.ttf");// Create a textsf::Text text(s, font);// text.setOrigin(sf::Vector2f(120, 100));text.setCharacterSize(30);text.setStyle(sf::Text::Bold);text.setFillColor(sf::Color::Red);// Draw itwindow.draw(text);
}// int lnum = 0;
int num;
void dispaly(){// window.clear(sf::Color::Black);window.clear(sf::Color::White);// window.clear();c = complex<double>(rand() % 10000 / 23333.0f, rand() % 10000 / 10007.f);drawText("c: " + to_string(c.real()) + " " + to_string(c.imag()));num = 0;double x, y;int max_x = 800, max_y = 600;double base_x = 500, base_y = 300;complex<double> z;sf::VertexArray points;points.resize(0);int step = 1;for(int i = 0; i < max_x; i += step){if(i % 100 == 0)cout << i << endl;for(int j = 0; j < max_y; j += step){// 坐标变换x = 2 *(i - double(max_x) / 2.0) / (double(max_x) / 2.0);y = 1.33 * (j - double(max_y) / 2.0) / (double(max_y) / 2.0);z = iter(complex<double>(x, y));// points.append(sf::Vertex(sf::Vector2f(x, y), sf::Color::Cyan));// sf::Vertex p(sf::Vector2f(i + base_x, j + base_y), colors[getColor(std::abs(z))]);// points.append(p);// continue;if(std::abs(z) * std::abs(z) <= 2){// if(z.imag() * z.imag() + z.real() * z.real() < 2){// sf::Vertex p(sf::Vector2f(i + base_x, j + base_y), sf::Color::Cyan);sf::Vertex p(sf::Vector2f(i + base_x, j + base_y), colors[getColor(std::abs(z))]);points.append(p);// if(points.getVertexCount() > 100){// 	points.setPrimitiveType(sf::Points);// 	window.draw(points);// 	points.resize(0);// 	window.display();// }// cout << i << " " << j << endl;}}}points.setPrimitiveType(sf::Points);cout << points.getVertexCount() << endl;window.draw(points);points.resize(0);window.display();
}
int main(){init();dispaly();sf::Clock clock;float timer = 0, delay = 5, time;sf::Event event;while (window.isOpen()){time = clock.getElapsedTime().asSeconds();timer += time;clock.restart();// dispaly();while (window.pollEvent(event)){if (event.type == sf::Event::Closed) window.close();}if(timer > delay){dispaly();timer = 0;}}return 0;
}

(未完ing)


http://chatgpt.dhexx.cn/article/4OphMOOx.shtml

相关文章

SFML环境配置

材料&#xff1a; 1.visual studio 2017 2.SFML-2.5.1-windows-vc15-32-bit 准备阶段 1.进入SFML官网下载sfml-vs2017-32bit版本 2.将该压缩包解压在一个文件夹中 步骤&#xff1a; 1.进入vs&#xff0c;在上述文件夹中新建Empty Project&#xff0c;右键资源文件->添加-…

[SFML] 多个OpenGL上下文

代码 #include <iostream> #include <gl/glew.h> #include <SFML/Graphics.hpp> #include <windows.h>int main() {auto getInstance [](){return (HINSTANCE)GetModuleHandle(nullptr);};auto debug [](GLenum source, GLenum type, GLuint id, GL…

SFML配置问题

先去下载安装包&#xff0c;这里我就不多说了&#xff0c;我想说的是其中的报错问题&#xff0c;按照我所说的对照下去&#xff0c;一般不会出现报错现象。 ** 第一步&#xff1a; **找到项目属性&#xff0c;这里我选择所有配置和所有平台&#xff0c;你们也可以选择其他的。…

SFML+vs2019安装

SFMLvs2019安装 1.创建一个c空项目 2.打开属性管理器 3.添加新项目属性表 在64下单击鼠标右键 添加成功后回到属性表64找到刚刚添加的属性表单击鼠标右键–>属性单击 找到SFML安装目录的include&#xff0c;复制路径粘贴到C/C->常规–>附加包含目录 找到SFM…

SFML初学-俄罗斯方块实现

偶然看到大神使用 SFML 制作游戏&#xff0c;简单学习了一下这个库的使用并且仿照YouTube上大神的思路做了一个俄罗斯方块&#xff0c;目前只实现了出现方块、消除方块的功能&#xff0c;随着慢慢学习一点点继续修改吧&#xff1b; 资源&#xff1a; 源码&#xff1a; /*******…

使用c++SFML制作月圆之夜总集篇

写在开头 重新以时间线的形式整理一下去年使用c的SFML库制作月圆之夜&#xff08;游戏程序设计大作业&#xff09;的开发过程&#xff0c;括号里面是新的补充以及对一年前自己的吐槽 因为是在大二转专业后做首次接触游戏开发后才做的&#xff0c;当时c学习得并不好&#xff0…

SFML loadFromFile()出错:failed to load image

解决方法&#xff1a;确保你的依赖项和你的运行库一致。 如果你的附加依赖项&#xff08;即动态链接库的.lib文件&#xff09;是debug版本&#xff0c;即以-d结尾。那么你的运行库也必须为debug版&#xff0c;即MDd。&#xff08;如下&#xff09; 附加依赖项的位置&#xff1…

用c++和SFML实现简易的界面版贪吃蛇

运行截图 等待开始界面 运行过程 失败界面截图 SFML配置 csdn上面已经有很多SFML配置的blog&#xff0c;随便就能搜到。正常配置好SFML后&#xff0c;还需要将字体ttf文件放在源代码同一目录和exe同一目录中&#xff0c;不然无法显示字符 代码部分 下面贴上各个部分的代码 …

VS2017、VS2019配置SFML

一、sfml官网下载32位的版本 一样的设置&#xff0c;64位的版本我没有成功&#xff0c;用不了。 https://www.sfml-dev.org/ bin目录下的文件拷贝到System32和SysWOW64里面。 二、 鼠标右击红色处&#xff0c;弹出菜单&#xff0c;点最后那个属性。 如果不是win32&#xff0c;…

VS2019配置SFML

VS2019配置SFML 1.下载安装SFML SDK 网址&#xff1a;https://www.sfml-dev.org/download.php 解压并放在文件夹里&#xff0c;记住这个路径。 在我的电脑中这个路径是F:\CProjects\_library\SFML-2.5.1 2.VS新建一个C控制台项目 我命名为SfmlTest&#xff0c;并放在常用的项…

sfml-tutorials 官方教程 windows篇

系列文章 SFML-windows 篇 SFML-Events explained 篇 SFML-Keyboard, mouse and joystick 篇 SFML-Using OpenGL in a SFML window 篇 SFML-Drawing 2D stuff 篇 SFML-Shapes 篇 SFML-Sprites and textures 篇 文章目录 系列文章打开一个windows执行windows绘制windows控制帧速…

SFML基础

原文地址&#xff1a;https://www.cnblogs.com/karl07/p/10285692.html (1) 窗口和交互 创建一个新窗口&#xff1a; sf::RenderWindow window(sf::VideoMode(500,500),"new window"); 但是光创建一个窗口并不能显示 还要加一个循环 while (window.isOpen()){sf:…

引擎开发四: SFML库及使用

SFML 是多媒体库&#xff0c;它为PC的各个组件提供简单的界面&#xff0c;用来简化游戏和多媒体应用程序的开发。 主要由五个模块组成&#xff0c;分别是&#xff1a;系统&#xff0c;窗口&#xff0c;图形&#xff0c;音频和网络。 SFML 是跨平台的&#xff0c;通过 SFML&…

【C++】开源:多媒体SFML库使用入门

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍SFML库使用。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习知识&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&#…

使用SFML框架打造属于自己的俄罗斯方块

目录 一、效果展示 二、游戏说明 三、开发环境 四、代码展示 五、代码详解 1.游戏区域表示 2.方块表示 3.方块旋转 4.消行处理 六、个性化定制 七、结语 一、效果展示 二、游戏说明 相信大家都玩过俄罗斯方块&#xff0c;五种按键就能带来极高的可玩性。如果想要开发…

超详细!SFML库vs2022配置教程

1.官网下载SFML 官方网址&#xff1a;SFML 点击下载 根据自己电脑选择合适的版本下载 我的电脑是64位的 下载完成之后将文件放在一个自己方便找到的地方 2.vs2022配置 选择空项目 添加cpp源文件 附加包含目录 添加你SFML中的include路径 例如&#xff1a; 添加SFML中的li…

SFML学习笔记(1)——初识SFML

一、SFML SFML 是多媒体库&#xff0c;它为PC的各个组件提供简单的界面&#xff0c;用来简化游戏和多媒体应用程序的开发。 SFML分成以下五个模块&#xff0c;这些模块相互独立&#xff0c;也可以根据需要组合在一起: System(系统)&#xff1a;一个核心模块&#xff0c;它定义…

找出数组中第k大的数

给定一个数组&#xff0c;找出数组中第k大的数。其实现代码如下: package com.threeTop.www;/*** 找出数组中第k大的数* author wjgs**/ public class FindK {public static void find(int[]array,int begin,int end,int k){int ipartition(array,begin,end);if(i1>k){//左半…

n个数中找最大数c语言,N个数中找到第K大的数值(C语实现)

N个数中找到第K大的数值(C语实现) N个数中找到第K大的数值(C语实现) 研究生了,选了计算机算法这门课程,这周布置了一个作业,在OJ上做:**N个数中找到第K大的数值**。大一简单学过C语言基础,目前只能用C语言编程,后续会学C++编程。 分享一份不超时的C语代码~ 测试例子: 思…

快速排序计算第K大的数

先说结论&#xff0c;最终版本代码如下&#xff1a; public class KthNum {public static int k 2;public static boolean bigK false;public static void main(String[] args) {int arr[] {3, 2, 3, 1, 7, 4, 5, 5, 6};int kNum quickSort(arr);System.out.println("…