zoukankan      html  css  js  c++  java
  • win32_c语言绘制曼德博集合(分形绘制)

    • 先了解一下曼德博集合

    下面引用百科

    曼德布洛特集合(Mandelbrot set)是在复平面上组成分形的点的集合,一种分形图案。
     
    中文名
    曼德勃罗集合
    外文名
    Mandelbrot set
    含    义
    复平面上组成分形的点的集合
    性    质
    分形图

    目录

     
    曼德布洛特复数集合(Mandelbrot set,或译为曼德博集合)是一种在复平面上组成分形的点的集合,以数学家本华·曼德博的名字命名。曼德博集合与朱利亚集合有些相似的地方,例如使用相同的复二次多项式来进行迭代
    曼德布洛特集合可以用复二次多项式:f_c(z) = z^2 +c
    来定义 其中c是一个复参数。对于每一个c,从开始对fc(z)进行迭代。
    序列 的值或者延伸到无限大,或者只停留在有限半径的圆盘内。
    曼德布洛特集合就是使以上序列不延伸至无限大的所有c点的集合。
    从数学上来讲,曼德布洛特集合是一个复数的集合。一个给定的复数c或者属于曼德布洛特集合M,或者不是。

    计算的方法


    曼德布洛特集合一般用计算机程序计算。对于大多数的分形软件,例如Ultra fractal,内部已经有了比较成熟的例子。下面的程序是一段伪代码,表达了曼德布洛特集合的计算思路[1]。
    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;
      }
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    22. Generate Parentheses (backTracking)
    21. Merge Two Sorted Lists
    20. Valid Parentheses (Stack)
    19. Remove Nth Node From End of List
    18. 4Sum (通用算法 nSum)
    17. Letter Combinations of a Phone Number (backtracking)
    LeetCode SQL: Combine Two Tables
    LeetCode SQL:Employees Earning More Than Their Managers
  • 原文地址:https://www.cnblogs.com/ncgds/p/6652165.html
Copyright © 2011-2022 走看看