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;
      }
  • 相关阅读:
    luogu P2439 [SDOI2005]阶梯教室设备利用
    bzoj1559: [JSOI2009]密码
    bzoj3172: [Tjoi2013]单词
    后缀树简短实现
    [APIO2010]特别行动队 --- 斜率优化DP
    [APIO2014]序列分割 --- 斜率优化DP
    [HNOI2012]集合选数 --- 状压DP
    UVA11107 Life Forms --- 后缀数组
    [TJOI2017]DNA --- 后缀数组
    [NOI2014]购票 --- 斜率优化 + 树形DP + 数据结构
  • 原文地址:https://www.cnblogs.com/ncgds/p/6652165.html
Copyright © 2011-2022 走看看