- 先了解一下曼德博集合
下面引用百科
曼德布洛特集合(Mandelbrot set)是在复平面上组成分形的点的集合,一种分形图案。
- 中文名
- 曼德勃罗集合
- 外文名
- Mandelbrot set
- 含 义
- 复平面上组成分形的点的集合
- 性 质
- 分形图案
曼德布洛特复数集合(Mandelbrot set,或译为曼德博集合)是一种在复平面上组成分形的点的集合,以数学家本华·曼德博的名字命名。曼德博集合与朱利亚集合有些相似的地方,例如使用相同的复二次多项式来进行迭代。
曼德布洛特集合可以用复二次多项式:f_c(z) = z^2 +c
来定义 其中c是一个复参数。对于每一个c,从开始对fc(z)进行迭代。
序列 的值或者延伸到无限大,或者只停留在有限半径的圆盘内。
曼德布洛特集合就是使以上序列不延伸至无限大的所有c点的集合。
从数学上来讲,曼德布洛特集合是一个复数的集合。一个给定的复数c或者属于曼德布洛特集合M,或者不是。
For Each z0 in Complex repeats = 0 z=z0 Do z=z^2+z0 repeate = repeats+1 Loop until abs(z)>Bailout or repeats >= MaxRepeats If repeats >= MaxRepeats Then Draw z0,Black Else Draw z0,f(z,z0,Repeats) 'f返回颜色 End IfNextf函数的一些例子直接利用循环终止时的Repeats 综合利用z和Repeats Orbit Traps也可以用Mathematica制作 DensityPlot[Block[{z, t = 0}, z = x + y*I; While[(Abs[z] < 2.0) && (t < 100), ++t; z = z^2 + x + y*I]; Return[t]],{x, -2, 0.8}, {y, -1.5, 1.5}, PlotPoints -> 500, Mesh -> False
效果
- 实现代码
// 曼德博集合.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "resource.h" #include <math.h> #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text const int iXmax = 600; const int iYmax = 600; const double CxMin = -2.5; const double CxMax = 1.5; const double CyMin = -2.0; const double CyMax = 2.0; const int IterationMax = 200; const double EscapeRadius = 2; // Foward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MY); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // // COMMENTS: // // This function and its usage is only necessary if you want this code // to be compatible with Win32 systems prior to the 'RegisterClassEx' // function that was added to Windows 95. It is important to call this function // so that the application will get 'well formed' small icons associated // with it. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MY); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_MY; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } // // FUNCTION: InitInstance(HANDLE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; TCHAR szHello[MAX_LOADSTRING]; LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: {//添加大括号,使内部的变量初始化赋值编译通过 hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... int iX,iY; double Cx,Cy; double PixelWidth = (CxMax - CxMin)/iXmax; double PixelHeight; PixelHeight = (CyMax - CyMin)/iYmax; COLORREF color; double Zx,Zy; double Zx2,Zy2; INT Iteration; double ER2; ER2 = EscapeRadius *EscapeRadius; //依据曼德博集合计算原理,获取每个像素的属性 for(iY = 0;iY < iYmax;iY++)//循环每一行 { Cy = CyMin + iY*PixelHeight; if(fabs(Cy) < PixelHeight/2) Cy = 0.0; for(iX=0;iX < iXmax;iX++)//循环每一列 { Cx = CxMin +iX* PixelHeight; Zx = Zy= Zy2=Zx2 = 0.0; Iteration = 0; //针对每个像素进行循环计算 while(Iteration < IterationMax && ((Zx2 + Zy2)<ER2)) { Zy = 2* Zx*Zy + Cy; Zx = Zx2 - Zy2 + Cx; Zx2 = Zx*Zx; Zy2 = Zy *Zy; Iteration++; } if(Iteration == IterationMax) color = RGB(0,0,0);//前景色黑色 else color = RGB(255,255,255);//背景色白色 SetPixel(hdc,iX,iY,color); } } // RECT rt; // GetClientRect(hWnd, &rt); // DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); EndPaint(hWnd, &ps); break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // Mesage handler for about box. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; }