混沌分形之填充集
通过分形来生成图像,有一个特点是:不想生成什么样的图像就写出相应的算法,而是生成出来的图像像什么,那算法就是什么。总之,当你在写这个算法时或设置相关参数时,你几乎无法猜测出你要生成的图像是什么样子。而生成图像的时间又比较久,无法实时地调整参数。所以我这使用了填充集的方式,先计算少量的顶点,以显示出图像的大致轮廓。确定好参数后再进行图像生成。所谓填充集,就是随机生成顶点位置,当满足要求时顶点保留,否则剔除。这里将填充集的方式来生成Julia集,曼德勃罗集和牛顿迭代集.
(1)Julia集
// 填充Julia集
// http://www.douban.com/note/230496472/
class JuliaSet2 : public FractalEquation
{
public:
JuliaSet2()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f;
m_ParamA = 0.11f;
m_ParamB = 0.615f;
m_nIterateCount = 80;
}
void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
x = outX = yf_rand_real(-1.0f, 1.0f);
y = outY = yf_rand_real(-1.0f, 1.0f);
float lengthSqr;
float temp;
int count = 0;
do
{
temp = x * x - y * y + m_ParamA;
y = 2 * x * y + m_ParamB;
x = temp;
lengthSqr = x * x + y * y;
count++;
}
while ((lengthSqr < 4.0f) && (count < m_nIterateCount));
if (lengthSqr > 4.0f)
{
outX = 0.0f;
outY = 0.0f;
}
outZ = z;
}
bool IsValidParamA() const {return true;}
bool IsValidParamB() const {return true;}
private:
int m_nIterateCount;
};
(2)曼德勃罗集
// 曼德勃罗集
// http://www.cnblogs.com/Ninputer/archive/2009/11/24/1609364.html
class MandelbrotSet : public FractalEquation
{
public:
MandelbrotSet()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f;
m_ParamA = -1.5f;
m_ParamB = 1.0f;
m_ParamC = -1.0f;
m_ParamD = 1.0f;
m_nIterateCount = 100;
}
void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float cr = m_ParamA + (m_ParamB - m_ParamA)*((float)rand()/RAND_MAX);
float ci = m_ParamC + (m_ParamD - m_ParamC)*((float)rand()/RAND_MAX);
outX = 0.0f;
outY = 0.0f;
float lengthSqr;
float temp;
int count = 0;
do
{
temp = outX * outX - outY * outY + cr;
outY = 2 * outX * outY + ci;
outX = temp;
lengthSqr = outX * outX + outY * outY;
count++;
}
while ((lengthSqr < 4.0f) && (count < m_nIterateCount));
if (lengthSqr < 4.0f)
{
outX = cr;
outY = ci;
}
else
{
outX = 0.0f;
outY = 0.0f;
}
outZ = z;
}
bool IsValidParamA() const {return true;}
bool IsValidParamB() const {return true;}
bool IsValidParamC() const {return true;}
bool IsValidParamD() const {return true;}
private:
int m_nIterateCount;
};
(3)牛顿迭代集
// 牛顿迭代
// http://www.douban.com/note/230496472/
class NewtonIterate : public FractalEquation
{
public:
NewtonIterate()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f;
m_ParamA = 1.0f;
m_nIterateCount = 64;
}
void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
x = outX = yf_rand_real(-m_ParamA, m_ParamA);
y = outY = yf_rand_real(-m_ParamA, m_ParamA);
float xx, yy, d, tmp;
for (int i = 0; i < m_nIterateCount; i++)
{
xx = x*x;
yy = y*y;
d = 3.0f*((xx - yy)*(xx - yy) + 4.0f*xx*yy);
if (fabsf(d) < EPSILON)
{
d = d > 0.0f ? EPSILON : -EPSILON;
}
tmp = x;
x = 0.666667f*x + (xx - yy)/d;
y = 0.666667f*y - 2.0f*tmp*y/d;
}
if (x < 0.0f)
{
outX = 0.0f;
outY = 0.0f;
}
outZ = z;
}
bool IsValidParamA() const {return true;}
private:
int m_nIterateCount;
};
(4)
关于基类FractalEquation的定义见:混沌与分形
再发几幅图像:
——
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?