/************************************************************************** * FRACTALS: ZOOM ON THE SET OF MANDELBROT * * ----------------------------------------------------------------------- * * TUTORIAL: * * * * The set of Mandelbrot is a figure in the complex plane, that is (for no * * mathematicians) the plane allowing to represent complex numbers having * * the form a + i b, a is the real part (ox componant) and b is the * * imaginary part (oy componant). The imaginary number i is the unity of * * axis oy, defined as i x i = -1. In the following, we will use the * * multiplication of two complex numbers and the module value of a complex * * number before defining the set of Mandelbrot itself. * * * * Multiply z1 by z2 * * * * Let be z1 = a1 + i b1 and z2 = a2 + i b2, two complex numbers. To cal- * * culate Z = z1 x z2, one just has to algebraically develop the expression* * (a1 + i b1)*(a2 + i b2), replacing i² by -1 and sepatating constant * * terms from i terms. One easily obtains: * * * * Z = (a² - b²) + i (2ab) * * * * Module of a complex number * * * * Every complex number a + i b can be represented as the point of coordi- * * nates (a, b) in the complex plane. Its module is nothing other than the * * distance of this point from origin (0,0), that is to say: * * * * | Z | = square root of (a² + b²) * * * * We can now define the iterative process that will lead us to the magni- * * ficent "Set of Mandelbrot": * * * * We take, as a starting point, a fixed complex number c, and we calculate* * the complex expression z² + c, z being a variable complex number. * * Let us take z = 0, then z² + c equals c. Let us replace z by c in the * * formula z² + c, then we obtain c² + c. Let us again remplace z by this * * new value, then we obtain (c²+c)² + c. Such a process is indefinitly * * resumed, each new value z² + c is taken as new value z. This provides * * an unlimited series of z numbers. * * * * The mathematician Mandelbrot was the first to notice that, according to * * the chosen value c, the series of complex numbers z so obtained could * * have a module, either rapidly tending towards infinity, or tending * * towards a finite value, whatever the number of iterations may be. * * * * Two examples: * * * * 1) c = 1 + i * * * * iteration new z module of z * * ____________________________________________ * * 1 1 + 3i 3,16227... * * 2 -7 + 7i 9,89949... * * 3 1-97i 97,00515... * * 4 -9407-193i 9408,97965 * * * * The module of z increases very rapidly. * * * * 2) c = -1 + 0,25 i * * * * iteration new z module de z * * ____________________________________________ * * 1 -0,5 - 0i 0,5 * * 2 -0,25 + 0,5i 0,55902... * * 3 -0,687 + 0,25i 0,73154... * * * * At 80th iteration, z = 0.40868 + 0,27513 i, the module equals 0,49266...* * The module remains with a finite value, whatever the number of itera- * * tions may be. Practically, we will consider that the limit is obtained * * after 100 iterations, if the module of z is < 4. The set of Mandelbrot, * * still called the Mandelbrot man, because of its shape, is constituted * * by all the points for which the expression z² + c has a finite value * * whatever the number of iterations may be. * * * * This program allows to make a zoom on a particular zone of the Mandel- * * brot domain by fixing the following parameters: * * * * x1 et x2 limits in ox * * y1 et y2 limits in oy * * limite number of iterations (usually 100) * * * * Some interesting examples: * * * * x1 = -0.67166 x2 = -0.44953 * * y1 = 0.49216 y2 = 0.71429 Lim = 250 * * * * x1 = -0.19050 x2 = -0.13824 * * y1 = 1.01480 y2 = 1.06707 Lim = 320 * * * * x1 = -0.74591 x2 = -0.74448 * * y1 = 0.11196 y2 = 0.11339 Lim = 250 * * * * These three examples are quite acceptable with limite = 100. * * * * Up to you to discover other ones ! * * * * * * See also programs mandel.cpp and julia.cpp. * * * * ----------------------------------------------------------------------- * * REFERENCE: * * "Graphisme dans le plan et dans l'espace avec Turbo Pascal 4.0 * * By R. Dony - MASSON, Paris 1990" [BIBLI 12]. * * * * Visual C++ version by J-P Moreau * * (to be used with mandzoom.mak and Gr2d.cpp) * * (www.jpmoreau.fr) * **************************************************************************/ #include #include #include #include HDC hdc; RECT rect; HPEN hpen, hpenOld; //Functions used here of module Gr2D.cpp void Fenetre(double,double,double,double); void Cloture(int,int,int,int); void Bordure(); void MoveXY(double,double); void LineXY(double,double); //"home made" graphic commands for hdc environment used by above functions void DrawPixel(int ix,int iy) { //sorry, no other available command found Rectangle(hdc,rect.left+ix,rect.top+iy, rect.left+ix+2,rect.top+iy+1); } void Swap(int *i1,int *i2) { int it; it=*i1; *i1=*i2; *i2=it; } void DrawLine(int ix1,int iy1,int ix2,int iy2) { int i,il,ix,iy; float dx,dy; if (ix2 4) { indice=compt % 5; //change color pen after each compt increment switch(indice) { case 0: SelectObject(hdc,hpenOld); break; case 1: SelectObject(hdc,hpen); break; case 2: SelectObject(hdc,hpen1); break; case 3: SelectObject(hdc,hpen2); break; case 4: SelectObject(hdc,hpen3); } MoveXY(-xx,-yy); LineXY(-xx+incX,-yy); MoveXY(xx,yy); LineXY(xx+incX,yy); } yy=yy+incY; } xx=xx+incX; } //prepare drawing caption (parameter values) sprintf(sx1,"x1=%5.3f",x1); sprintf(sx2," x2=%5.3f",x2); sprintf(sy1," y1=%5.3f",y1); sprintf(sy2," y2=%5.3f",y2); sprintf(slim," Lim=%4d",limite); strcpy(s,sx1); strcat(s,sx2); strcat(s,sy1); strcat(s,sy2); strcat(s,slim); sx=(MaxX-15-10*strlen(s)) / 2; //center caption horizontaly SelectObject(hdc,hpenOld); //restore default black pen OutText(sx,MaxY-20,s); //display caption downwards //free memory for additional pens DeleteObject(hpen1); DeleteObject(hpen2); DeleteObject(hpen3); } //Draw_Mandzoom() //Handle window Paint and Destroy messages long FAR PASCAL /*_export*/ WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam) { PAINTSTRUCT ps; switch (message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); hpen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); hpenOld = SelectObject(hdc,hpen); Draw_Mandzoom(); SelectObject(hdc,hpenOld); DeleteObject(hpen); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } // main program int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { static char szAppName[] = "Mandzoom"; HWND hwnd; MSG msg; WNDCLASS wndclass; if (!hPrevInstance) { wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; RegisterClass(&wndclass); } hwnd = CreateWindow(szAppName, // window class name " ZOOM ON MANDELBROT", // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //end of file mandzoom.cpp