怎麼用c語言實現分形圖形?

例如曼德博集合、茹利亞集合,只能一個pixel一個pixel的點亮。


其實你只需要將那些分形集的數學公式變為你的代碼就能很容易地寫出來了,比如說這是一個 Mandelbrot 集的例子:

#include &
#include &
#include "svpng.inc"

double mandelbrot(double x, double y) {
double a = x, b = y;
for(int i = 0; i &< 128; ++i) { double c = a * a - b * b + x, d = 2 * a * b + y; a = c, b = d; if(a * a + b * b &> 4) return 1 - i / 128.0;
}
return 0;
}
uint8_t data[1024 * 1536 * 3];
int main(void) {
uint8_t* p = data;
for(int i = 0; i &< 1024; ++i) { for(int j = 0; j &< 1536; ++j) { uint8_t n = mandelbrot(j / 512.0 - 2, i / 512.0 - 1) * 255; *p++ = n; *p++ = n; *p++ = n; } } FILE* file = fopen("Mandelbrot.png", "wb"); svpng(file, 1536, 1024, data, 0); fclose(file); }

(方便起見,使用了 @Milo Yip 老師編寫的miloyip/svpng)

輸出:


遞歸


突然想起學習CUDA時寫過,也寫了個CPU+OpenCV版本的,先佔個坑,白天閑時找找再回來更新。

--------更新2017-06-02--------

代碼已託管上傳至github,附可執行文件。

https://github.com/KondeU/JuliaImage_WithCPU

-------------- 代碼找到了,回來更新 (2017/05/26) --------------

暫時不可轉載哦,圖片不可盜用~代碼可以給開發者拿去研究~~

提供的是Julia集合的變換。我挺喜歡分形的,總能有驚喜,能產生許許多多好看的圖形。

先放效果圖吧,參數可參考效果圖。代碼在後頭。

以下是代碼:(破乎的代碼塊編輯器真難用)

// JuliaImage_WithCPU.cpp
// Writed by kondeu, 20,Oct,2016

// Standard header
#include&
using namespace std;

// OpenCV header
#include "cv.h"
#include "highgui.h"

#define JI_CHANNEL 4
#define JI_ITERACOUNT 200
#define JI_THRESHOLD 1000

class CComplex
{
public:

CComplex(float fR = 0, float fI = 0)
{
m_fR = fR;
m_fI = fI;
}

inline float CulcLength2()
{
return m_fR * m_fR + m_fI * m_fI;
}

inline CComplex operator *(const CComplex c)
{
return CComplex(
(this-&>m_fR * c.m_fR - this-&>m_fI * c.m_fI),
(this-&>m_fI * c.m_fR + this-&>m_fR * c.m_fI));
}
inline CComplex operator +(const CComplex c)
{
return CComplex(this-&>m_fR + c.m_fR, this-&>m_fI + c.m_fI);
}

inline void SetR(float fR)
{
m_fR = fR;
}
inline void SetI(float fI)
{
m_fI = fI;
}
inline float GetR() const
{
return m_fR;
}
inline float GetI() const
{
return m_fI;
}

private:

float m_fR; // Real number
float m_fI; // Imaginary number
};

void BmpOrg2CrtOrg(float fCrtX, float fCrtY, const int x, const int y,
const float fScale, const int iBmpWidth, const int iBmpHeigth)
{
fCrtX = fScale * (float)(x - iBmpWidth / 2) / (iBmpWidth / 2);
fCrtY = fScale * (float)(y - iBmpHeigth / 2) / (iBmpHeigth / 2);

//fCrtX = fScale * (float)(x / 2) / (iBmpWidth / 2);
//fCrtY = fScale * (float)(y / 2) / (iBmpHeigth / 2);

//fCrtX = (float)iBmpWidth / 2 - x;
//fCrtY = (float)iBmpHeigth / 2 - y;
}

int IsJulia(int iIteraCount, const float fCrtX, const float fCrtY, const CComplex cJuliaConstant)
{
CComplex cCrtPix(fCrtX, fCrtY);

for (int i = 0; i &<= JI_ITERACOUNT; i++) { iIteraCount = i; cCrtPix = cCrtPix * cCrtPix + cJuliaConstant; if (cCrtPix.CulcLength2() &> JI_THRESHOLD)
{
return 0;
}
}

return 1;
}

void GenerateJuliaImage(IplImage * pImage, const float fScale, const CComplex cJuliaConstant)
{
for (int y = 0; y &< pImage-&>height; y++)
{
for (int x = 0; x &< pImage-&>width; x++)
{
int iIteraCount;
float fCrtX, fCrtY;
BmpOrg2CrtOrg(fCrtX, fCrtY, x, y, fScale, pImage-&>width, pImage-&>height);
int iIsJulia = IsJulia(iIteraCount, fCrtX, fCrtY, cJuliaConstant);

int iOffset = y * pImage-&>widthStep + JI_CHANNEL * x;
pImage-&>imageData[iOffset + 0] = ((iIteraCount &>= JI_ITERACOUNT) ? 0 : 255 - iIteraCount);
pImage-&>imageData[iOffset + 1] = ((iIteraCount &>= JI_ITERACOUNT) ? 0 : 255 - iIteraCount);
pImage-&>imageData[iOffset + 2] = ((iIteraCount &>= JI_ITERACOUNT) ? 0 : ((iIteraCount * 255) / JI_ITERACOUNT));
pImage-&>imageData[iOffset + 3] = 255;
}
}
}

int main(void)
{
char cCmd = "/0";

while(true)
{
cout &<&< "------------------------ Julia Image Generater ------------------------" &<&< endl; cout &<&< "Julia Image with CPU Core, coded by kondeu, 20,Oct,2016." &<&< endl; cout &<&< "Press any key with enter to continue, or press "q" with enter to exit." &<&< endl; cin &>&> cCmd;

if (cCmd == "q")
{
break;
}

cout &<&< "Input param to create julia image." &<&< endl; int iBmpWidth, iBmpHeigth; float fScale; CComplex cJuliaConstant; cout &<&< "Image size - width:" &<&< endl; cin &>&> iBmpWidth;

cout &<&< "Image size - heigth:" &<&< endl; cin &>&> iBmpHeigth;

cout &<&< "Julia constant - real number:" &<&< endl; cin &>&> fScale;
cJuliaConstant.SetR(fScale);

cout &<&< "Julia constant - imaginary number:" &<&< endl; cin &>&> fScale;
cJuliaConstant.SetI(fScale);

cout &<&< "Scale:" &<&< endl; cin &>&> fScale;

cout &<&< "Alloc memory to store image." &<&< endl; IplImage * pImage = cvCreateImageHeader(cvSize(iBmpWidth, iBmpHeigth), IPL_DEPTH_8U, JI_CHANNEL); pImage-&>origin = IPL_ORIGIN_TL;
cvCreateData(pImage);

cout &<&< "Generating julia iamge..." &<&< endl; GenerateJuliaImage(pImage, fScale, cJuliaConstant); cout &<&< "Generated julia iamge successfully." &<&< endl; cvNamedWindow("Julia image generate", CV_WINDOW_AUTOSIZE); cvShowImage("Julia image generate", pImage); cvWaitKey(0); cvDestroyWindow("Julia image generate"); cvReleaseImage(pImage); cout &<&< "-----------------------------------------------------------------------" &<&< " " &<&< endl; } return 0; }


類似蕨類植物樹葉那種分形幾何?


推薦閱讀:

如何通俗地解釋 C 語言中 #include<> 的用途?
C語言 主函數退出前,還佔用了大量的內存,是什麼原因造成的呢?
vc++6.0是不是很多優點?如何使用visual studio2013達到相同的功能?

TAG:程序員 | C編程語言 | CC | 分形理論 | 計算機圖形學 |