真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

分形之曼德勃羅集-創(chuàng)新互聯(lián)

分形的定義及介紹,知乎、百度上非常多。分形有很多, 其中曼德勃羅集是我上大學時老師講的一個,當時感覺非常驚奇,一直記得。前幾天又突發(fā)奇想,看看分形的圖片,現(xiàn)在網(wǎng)上真是多。就捯飭了一個。覺得還是很有意思。

成都創(chuàng)新互聯(lián)云計算的互聯(lián)網(wǎng)服務提供商,擁有超過13年的服務器租用、資陽托管服務器、云服務器、虛擬空間、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗,已先后獲得國家工業(yè)和信息化部頒發(fā)的互聯(lián)網(wǎng)數(shù)據(jù)中心業(yè)務許可證。專業(yè)提供云主機、虛擬空間、域名注冊、VPS主機、云服務器、香港云服務器、免備案服務器等。

下面以曼德勃羅集分形公式,利用C++builder XE8做一個小小的程序。系統(tǒng)是Windows10,64位。


一、曼德勃羅集公式

曼德勃羅特集是一個幾何圖形,?是曼德勃羅教授在上個世紀七十年代發(fā)現(xiàn)的。?這個點集出自迭代公式:

Z_{n+1}=Z^{2}_{n}+C

其中,ZC均為復數(shù)。

對于該非線性迭代公式,所有使得無限迭代后的結(jié)果能保持有限數(shù)值的復數(shù)z的集合(也稱該迭代函數(shù)的Julia集)連通的C,構(gòu)成曼德勃羅集。


二、曼德勃羅分形迭代公式?

設(shè):Z_{n}=x_{n}+y_{n}i

?C_{n}=c_{n}x+c_{n}yi

可得到:

Z_{n+1}=(x_{n}+y_{n}i)^{2}+(cx_{n}+cy_{n}i) =(x_{n}^{2}-y_{n}^{2}+cx_{n})+(2x_{n}y_{n}+cy_{n})i

即:

x_{n+1}=x_{n}^{2}-y_{n}^{2}+cx_{n}

y_{n+1}=2x_{n}y_{n}+cy_{n}

對每一個連通點的C,利用上述公式進行迭代,并且滿足一定的迭代次數(shù)或者收斂點。對一系列的連通點集進行迭代,即可得到曼德勃羅集。


三、利用C++builder XE8編程

下面是代碼,有詳細的說明。

程序文件:

//---------------------------------------------------------------------------

#include#pragma hdrstop

#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
//創(chuàng)建總體視圖時進行初始化。
void __fastcall TMainForm::FormCreate(TObject *Sender)   
{
	MainForm->Width = 560;
	MainForm->Height = 436;
	MainForm->BorderStyle = bsSingle;         //設(shè)置為不可調(diào)整大小
	MainForm->Color = clSkyBlue;              //設(shè)置背景為天藍色

	FractalImage->Height = 400;               //設(shè)置圖像高度
	FractalImage->Width = 400;                //設(shè)置圖像寬度
	FractalImage->Canvas->Pen->Color=clBlack; //設(shè)置圖像畫筆為黑色

	ZoomShape->Brush->Style = bsClear;        //放大框只保留外框線條
	ZoomShape->Visible = false;               //剛創(chuàng)建時,先隱藏放大框

	for(int i=0;i<400;i++)                    //把圖片置黑色
	{
		FractalImage->Canvas->MoveTo(i,0);    //移動至第i列
		FractalImage->Canvas->LineTo(i,400);  //豎著畫黑色線
	}

	mousedownFlag=false;                      //鼠標標志關(guān)閉
	ZoomBut->Enabled=false;                   //沒有圖的時候,關(guān)閉放大功能
}
//---------------------------------------------------------------------------
//分形重置
//左下角為(-2.5,-2.0),寬高為4.0,因此右上角為(1.5,2.0)
void __fastcall TMainForm::ResetButClick(TObject *Sender)
{
	x1=-2.5;                            //最原始的兩個坐標。使用這兩個數(shù)字可以使圖形居中。
	y1=-2.0;                            //
	width1=4.0;                         //整個寬度為4。這個是基數(shù)。
	ZoomButClick( ResetBut );
}
//---------------------------------------------------------------------------
//用于放大選擇的區(qū)域
void __fastcall TMainForm::ZoomButClick(TObject *Sender)
{
	int i,j;                        //行,列
	int red,green,blue,times;       //設(shè)置各像素點的顏色及迭代次數(shù);
	long double zx,zy,zxs,zys;
	bool inset;                     //置色標志
	FinishFlag=false;               //計算完成置否
	ZoomShape->Visible = false;     //隱藏放大框
	ResetBut->Enabled=false;        //關(guān)閉復位功能
	ZoomBut->Enabled=false;         //關(guān)閉放大功能
	ExitBut->Enabled=false;         //關(guān)閉退出功能

	if( width1 >0 )
	{
		width=width1;
		X0=x1;
		Y0=y1;
		IterationDetail=IterationEdit->Text.ToInt(); //得到迭代次數(shù)
		ScaleEdit->Text=4/width;  //放大位數(shù)。4為基數(shù)寬度。
		for(i=0;i<400;i++)        //核心代碼。按列計算每一個像素點。同時將像素點轉(zhuǎn)換的坐標作為迭代公式中的C
		{
			c_Real=X0+((double)i)*width/400.0; //計算公式中常數(shù)部分的實部
			for(j=0;j<400;j++)            //計算每一列的每一個像素。自上向下開始計算。
			{
				c_Image=Y0+((double)(400-j))*width/400.0;  //公式中常數(shù)部分的虛部
				zx=0;
				zy=0;
				inset=true;
				times=0;                  //對每個像素點的計算都要重新置0。
				while( inset && times< IterationDetail )    //當inset為真,且未達到循環(huán)次數(shù)時,繼續(xù)計算
				{
					times++;
					zxs=zx*zx;
					zys=zy*zy;
					zy=2*zx*zy+c_Image;   //迭代后的y
					zx=zxs-zys+c_Real;    //迭代后的X
					if( zxs+zys >= 4.0 )  //如果此點的循環(huán)次數(shù)未到,有發(fā)散的情況,則置為false。
						inset = false;
				}
				if( inset )                   //如果不發(fā)散,則置黑色
				{
					FractalImage->Canvas->Pixels[i][j]=TColor RGB( 0,0,0 );   //這種方法能實現(xiàn)。下面兩種方法都可以。
				}
				else                           //如果擴散,則用迭代次數(shù)times來設(shè)置像素點的顏色。
				{
					red=( times+100 )%200+50;  //這幾種顏色的數(shù)字可以試著修改,會得到不同的顏色。這里的red、green、blue不是真正的紅色、綠色和藍色,而是后面的參數(shù)。
					green=( times+red )%200+50;
					blue=( red+green )%200+50;
					FractalImage->Canvas->Pixels[i][j]=TColor RGB(red,green,blue); //轉(zhuǎn)換為TColor。
				}
			}
			Update();              //可以看到畫線過程。不使用該方法,則是畫完圖后,一次性更新圖片。
		}
	}
	ResetBut->Enabled=true;         //打開復位關(guān)閉功能
	ZoomBut->Enabled=true;          //打開放大功能
	ExitBut->Enabled=true;          //打開退出功能
	FinishFlag=true;
}
//---------------------------------------------------------------------------
//計算鼠標左鍵按下時的坐標值,并轉(zhuǎn)換為相對圖片原點的相對坐標
void __fastcall TMainForm::FractalImageMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{                                            //圖像鼠標坐標值左上角為(0,0),右下角為(400,400)
	ZoomShape->Visible = true;               //顯示放大選擇框
	if( FinishFlag && Button==mbLeft)
	{
		ZoomShape->Left=FractalImage->Left+X;   //放大選擇框的左邊為圖像的左邊+鼠標的橫坐標;
		ZoomShape->Top=FractalImage->Top+Y;     //放大選擇框的上邊為圖像的上邊+鼠標的縱坐標;
		LtX=X;                                  //記下當鼠標按下時相對圖片左上角位置的坐標X
		mousedownFlag=true;                     //記錄下按下鼠標的標志
		ltx=X0+((double)X)*width/400.0;         //計算左上角坐標ltx,轉(zhuǎn)換為相對圖片原點(中心點0,0)的坐標
		lty=Y0+((double)(400-Y))*width/400.0;   //計算左上角坐標lty,轉(zhuǎn)換為相對原點坐標值。
	}
}
//---------------------------------------------------------------------------
//抬起鼠標左鍵后,記下鼠標位置。轉(zhuǎn)換為相對圖片中心(原點)坐標。
void __fastcall TMainForm::FractalImageMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
		  int X, int Y)                   //計算選中圖框后的坐標,并且要保存下來。用于后續(xù)的計算。
{
	int Wide;
	if( FinishFlag && Button == mbLeft )  //計算完成并且是按下鼠標左鍵
	{
		mousedownFlag=false;
		rbx=X0+((double)X)*width/400.0;   //計算相對圖片中原點(中心點(0,0)位置的右下角坐標。
		width1=rbx-ltx;                   //計算選框的寬度,這個寬度不是像素寬度,而是坐標寬度。
		rby=lty-width1;                   //選框的高度與寬度一樣。
		x1=ltx;
		y1=rby;
		Wide=X-LtX;                     //用鼠標抬起時的坐標-按下鼠標左鍵的坐標,得到寬度
		ZoomShape->Height=Wide;            //選擇框的大小。
		ZoomShape->Width=Wide;             //正方形
	}
}
//---------------------------------------------------------------------------
//沒有這個移動的函數(shù)也可以,但有了可以畫出鼠標移動時的選擇框線。其代碼與鼠標左鍵彈起相同。
void __fastcall TMainForm::FractalImageMouseMove(TObject *Sender, TShiftState Shift, int X,
		  int Y)
{
	int Wide;
	if( mousedownFlag )
	{
		rbx=X0+((double)X)*width/400.0;      //得到右下角坐標X。
		width1=rbx-ltx;
		rby=lty-width1;                      //得到右下角坐標y
		x1=ltx;
		y1=rby;
		Wide=X-LtX;                          //寬度:鼠標的坐標X-左上角x坐標
		ZoomShape->Height=Wide; //放大選擇框的高度
		ZoomShape->Width=Wide;  //放大選擇框的寬度。兩個相等,為正文形。
//		ZoomShape->Update();
	}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ExitButClick(TObject *Sender)
{
	Close();
}
//---------------------------------------------------------------------------

其中,下面是關(guān)鍵代碼。這一段,從左上角開始,對每一個像素點進行迭代計算。

//用于放大選擇的區(qū)域
void __fastcall TMainForm::ZoomButClick(TObject *Sender)
{
	int i,j;                        //行,列
	int red,green,blue,times;       //設(shè)置各像素點的顏色及迭代次數(shù);
	long double zx,zy,zxs,zys;
	bool inset;                     //置色標志
	FinishFlag=false;               //計算完成置否
	ZoomShape->Visible = false;     //隱藏放大框
	ResetBut->Enabled=false;        //關(guān)閉復位功能
	ZoomBut->Enabled=false;         //關(guān)閉放大功能
	ExitBut->Enabled=false;         //關(guān)閉退出功能

	if( width1 >0 )
	{
		width=width1;
		X0=x1;
		Y0=y1;
		IterationDetail=IterationEdit->Text.ToInt(); //得到迭代次數(shù)
		ScaleEdit->Text=4/width;  //放大位數(shù)。4為基數(shù)寬度。
		for(i=0;i<400;i++)        //核心代碼。按列計算每一個像素點。同時將像素點轉(zhuǎn)換的坐標作為迭代公式中的C
		{
			c_Real=X0+((double)i)*width/400.0; //計算公式中常數(shù)部分的實部
			for(j=0;j<400;j++)            //計算每一列的每一個像素。自上向下開始計算。
			{
				c_Image=Y0+((double)(400-j))*width/400.0;  //公式中常數(shù)部分的虛部
				zx=0;
				zy=0;
				inset=true;
				times=0;                  //對每個像素點的計算都要重新置0。
				while( inset && times< IterationDetail )    //當inset為真,且未達到循環(huán)次數(shù)時,繼續(xù)計算
				{
					times++;
					zxs=zx*zx;
					zys=zy*zy;
					zy=2*zx*zy+c_Image;   //迭代后的y
					zx=zxs-zys+c_Real;    //迭代后的X
					if( zxs+zys >= 4.0 )  //如果此點的循環(huán)次數(shù)未到,有發(fā)散的情況,則置為false。
						inset = false;
				}
				if( inset )                   //如果不發(fā)散,則置黑色
				{
					FractalImage->Canvas->Pixels[i][j]=TColor RGB( 0,0,0 );   //這種方法能實現(xiàn)。下面兩種方法都可以。
				}
				else                           //如果擴散,則用迭代次數(shù)times來設(shè)置像素點的顏色。
				{
					red=( times+100 )%200+50;  //這幾種顏色的數(shù)字可以試著修改,會得到不同的顏色。這里的red、green、blue不是真正的紅色、綠色和藍色,而是后面的參數(shù)。
					green=( times+red )%200+50;
					blue=( red+green )%200+50;
					FractalImage->Canvas->Pixels[i][j]=TColor RGB(red,green,blue); //轉(zhuǎn)換為TColor。
				}
			}
			Update();              //可以看到畫線過程。不使用該方法,則是畫完圖后,一次性更新圖片。
		}
	}
	ResetBut->Enabled=true;         //打開復位關(guān)閉功能
	ZoomBut->Enabled=true;          //打開放大功能
	ExitBut->Enabled=true;          //打開退出功能
	FinishFlag=true;
}
//---------------------------------------------------------------------------

把像素點的相對坐標(x,y),作為迭代公式中的C值進行迭代計算。

在迭代次數(shù)不到1000次(我的迭代次數(shù))且向量值:>=4.0時,將該點置彩色,色彩值與迭代次數(shù)相關(guān);

否則,置該點為黑色。具體就是下面這段代碼:

		while( inset && times< IterationDetail )    //當inset為真,且未達到循環(huán)次數(shù)時,繼續(xù)計算
				{
					times++;
					zxs=zx*zx;
					zys=zy*zy;
					zy=2*zx*zy+c_Image;   //迭代后的y
					zx=zxs-zys+c_Real;    //迭代后的X
					if( zxs+zys >= 4.0 )  //如果此點的循環(huán)次數(shù)未到,有發(fā)散的情況,則置為false。
						inset = false;
				}
				if( inset )                   //如果不發(fā)散,則置黑色
				{
					FractalImage->Canvas->Pixels[i][j]=TColor RGB( 0,0,0 );   //這種方法能實現(xiàn)。下面兩種方法都可以。
				}
				else                           //如果擴散,則用迭代次數(shù)times來設(shè)置像素點的顏色。
				{
					red=( times+100 )%200+50;  //這幾種顏色的數(shù)字可以試著修改,會得到不同的顏色。這里的red、green、blue不是真正的紅色、綠色和藍色,而是后面的參數(shù)。
					green=( times+red )%200+50;
					blue=( red+green )%200+50;
					FractalImage->Canvas->Pixels[i][j]=TColor RGB(red,green,blue); //轉(zhuǎn)換為TColor。
				}

其中,

C++builder中,

FractalImage->Canvas->Pixels[i][j]=TColor RGB(red,green,blue);

在RGB(red,green,blue)前加TColor,強制轉(zhuǎn)換為TColor,否則編譯會出現(xiàn)warning ,但連接能夠通過,程序能夠正常運行。??


頭文件

//---------------------------------------------------------------------------

#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include#include#include#include#include//---------------------------------------------------------------------------
class TMainForm : public TForm
{
__published:	// IDE-managed Components
	TImage *FractalImage; //顯示分形圖像
	TShape *ZoomShape;    //放大選擇框
	TButton *ResetBut;    //復位按鈕
	TButton *ZoomBut;     //放大按鈕
	TButton *ExitBut;       //顯示放大選擇框右上角y坐標
	TEdit *IterationEdit; //用于輸入迭代次數(shù)。迭代次數(shù)越大,圖像越精細,但計算越慢。太大會非常的慢;超過10億次報錯。
	TEdit *ScaleEdit;     //僅用于顯示放大倍數(shù)。
	TLabel *IterationLabel;//迭代次數(shù)標簽
	TLabel *ScaleEditLabel;//放大倍數(shù)標簽

	void __fastcall FormCreate(TObject *Sender);      //程序初始化部分
	void __fastcall ResetButClick(TObject *Sender);   //分形重置
	void __fastcall ZoomButClick(TObject *Sender);    //放大
	void __fastcall ExitButClick(TObject *Sender);
	void __fastcall FractalImageMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
		  int X, int Y);
	void __fastcall FractalImageMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
		  int X, int Y);
	void __fastcall FractalImageMouseMove(TObject *Sender, TShiftState Shift, int X, int Y);

private:	// User declarations
	bool FinishFlag;            //完成畫圖標志
	double c_Real, c_Image;     //計算公式中,常數(shù)部分的實況與虛部
	double X0,Y0;               //最原始的兩個坐標
	double x1,y1;               //選擇待放大圖像部分的坐標值
	double LtX, LtY;            //記錄鼠標按下時的坐標值。實際代碼中,未用到ltY
	double ltx,lty, rbx, rby;   //左上角:left top x,left top y,右下角:right bottom x, right bottom y
	double width;               //
	double width1;              //分形的坐標寬度(不是按照像素數(shù)量寬度)。
	int IterationDetail;        //迭代次數(shù)。越大,越精細,但也越慢。
	bool mousedownFlag;         //鼠標按下標志。
public:		// User declarations
	__fastcall TMainForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif
四、部分圖片

該程序?qū)τ嬎銠C的整體配置不是很高,但對于CPU的計算能力有較高的要求,對硬盤和內(nèi)存要求不高。

我的筆記本是10年前的,Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz ? 2.30 GHz,迭代次數(shù)在100000(十萬)時,還勉強能算,再高,就非常慢了。

下面一張都是上面一張圖片的局部放大圖片。

圖1 復位后的曼德勃羅分形圖片

圖2 圖1中局部放大的圖片

圖3? 圖2局部放大圖片

圖4 圖3局部放大分形

圖5 圖4局部放大

圖6? 圖5 的局部放大

圖7 圖6的局部放大

圖8? 圖7增加迭代次數(shù)為10萬的迭代結(jié)果

圖8 與圖7 相比,迭代次數(shù)增加到10萬次??梢钥闯觯毠?jié)明顯不一樣。后面的計算都是按照10萬次計算的。圖片細節(jié)好,但我的筆記本比較慢。?

圖9 圖8 的局部放大

圖10

圖11

再放大,就開始馬賽克了。?

程序本身不復雜,代碼很少。

我已經(jīng)將該程序源代碼、可執(zhí)行程序壓縮為壓縮包,上傳到資源上。release版本可以拿出來單獨運行。有興趣的可以運行一下試試。?

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


本文標題:分形之曼德勃羅集-創(chuàng)新互聯(lián)
分享地址:http://weahome.cn/article/dpijoh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部