exerknife吧 关注:8贴子:354
  • 7回复贴,共1

she_c++ 传说中的复数

只看楼主收藏回复

// Ex13_05.cpp : Defines the entry point for the application.
// Using a task group
#include "stdafx.h"
#include "Resource.h"
#include "Fushu.h"
#include "ppl.h"
#include <functional>
//#include "HRTimer.h"
#include "commctrl.h"                   // For the status bar
#include <string>
#include <sstream>
#include <OleCtl.h>
class HRTimer
{
public:
HRTimer(void) : frequency(1.0 / GetFrequency()) { }
double GetFrequency(void)
{
    LARGE_INTEGER proc_freq;
    ::QueryPerformanceFrequency(&proc_freq);
    return static_cast<double>(proc_freq.QuadPart);
}
void StartTimer(void)
{
    DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0);
    ::QueryPerformanceCounter(&start);
    ::SetThreadAffinityMask(::GetCurrentThread(), oldmask);
}
double StopTimer(void)
{
    DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0);
    ::QueryPerformanceCounter(&stop);
    ::SetThreadAffinityMask(::GetCurrentThread(), oldmask);
    return ((stop.QuadPart - start.QuadPart) * frequency);
}
private:
    LARGE_INTEGER start;
    LARGE_INTEGER stop;
    double frequency;
};
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst;                                        // current instance
TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];        // the main window class name
const size_t MaxIterations(8000);       // Maximum iterations before infinity
HRTimer timer;                          // Timer object to calculate processor time
bool parallel(false);                   // True for parallel execution
// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);



1楼2011-03-31 17:51回复
    size_t IteratePoint(double zReal, double zImaginary, double cReal, double cImaginary);
    COLORREF Color(int n);                             // Selects a pixel color based on n
    void DrawSet(HWND hWnd);                           // Draws the Mandelbrot set
    void DrawSetParallel(HWND hWnd);                   // Draws the Mandelbrot set with parallel ops
    void UpdateStatusBarTime(HWND hWnd, double time); // Updates the status bar with the execution time
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
         // TODO: Place code here.
        MSG msg;
        HACCEL hAccelTable;
        // Initialize global strings
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_FUSHU, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);
        // Perform application initialization:
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }
        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FUSHU));
        // Main message loop:
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        return (int) msg.wParam;
    }
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style            = CS_HREDRAW | CS_VREDRAW;
    


    2楼2011-03-31 17:51
    回复
      2026-04-15 09:00:51
      广告
      不感兴趣
      开通SVIP免广告
          wcex.lpfnWndProc    = WndProc;
          wcex.cbClsExtra        = 0;
          wcex.cbWndExtra        = 0;
          wcex.hInstance        = hInstance;
          wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FUSHU));
          wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
          wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
          wcex.lpszMenuName    = MAKEINTRESOURCE(IDI_FUSHU);
          wcex.lpszClassName    = szWindowClass;
          wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
          return RegisterClassEx(&wcex);
      }
      BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
      {
         HWND hWnd;
         hInst = hInstance; // Store instance handle in our global variable
         hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
           100, 100, 500, 400, NULL, NULL, hInstance, NULL);
         if (!hWnd)
         {
            return FALSE;
         }
         HWND hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
                                    WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
                                    hWnd, (HMENU)0, GetModuleHandle(NULL), NULL);
      // Set up the panels in the statusbar
      int statwidths[] = {100,200, -1};
      SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
      SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)_T("Processor Time :"));
      SendMessage(hStatus, SB_SETTEXT, 2, (LPARAM)_T(" Right-click for parallel execution"));
         ShowWindow(hWnd, nCmdShow);
         UpdateWindow(hWnd);
         return TRUE;
      }
      LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
      {
          int wmId, wmEvent;
          PAINTSTRUCT ps;
          HDC hdc;
          switch (message)
          {
          case WM_COMMAND:
              wmId    = LOWORD(wParam);
              wmEvent = HIWORD(wParam);
              // Parse the menu selections:
              switch (wmId)
      


      3楼2011-03-31 17:51
      回复
                {
                case IDM_ABOUT:
                    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                    break;
                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
                }
                break;
            case WM_CREATE:
                SetWindowLong( hWnd, GWL_EXSTYLE, GetWindowLong( hWnd, GWL_EXSTYLE) | 0x80000 );
                ::SetLayeredWindowAttributes( hWnd, RGB(0xff,0,0), 90, LWA_ALPHA );
                break;
            case WM_PAINT:
                hdc = BeginPaint(hWnd, &ps);
                // TODO: Add any drawing code here...
            timer.StartTimer();
            if(parallel)
              DrawSetParallel(hWnd);
            else
              DrawSet(hWnd);
            UpdateStatusBarTime(hWnd, timer.StopTimer());
                EndPaint(hWnd, &ps);
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
        case WM_RBUTTONDOWN:
            parallel = !parallel;
            SendMessage(GetDlgItem(hWnd, 0), SB_SETTEXT, 2,
              (LPARAM)(parallel ? _T(" Right-click for serial execution") : _T(" Right-click for parallel execution")));
            InvalidateRect (hWnd, NULL, TRUE);
            UpdateWindow (hWnd);
            break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
            return 0;
        }
        // Message handler for about box.
        INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
        {
            UNREFERENCED_PARAMETER(lParam);
            switch (message)
            {
            case WM_INITDIALOG:
                return (INT_PTR)TRUE;
            case WM_COMMAND:
                if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
                {
                    EndDialog(hDlg, LOWORD(wParam));
        


        4楼2011-03-31 17:51
        回复
                      return (INT_PTR)TRUE;
                  }
                  break;
              }
              return (INT_PTR)FALSE;
          }
          // Iterates current point to determine membership of Mandelbrot set
          size_t IteratePoint(double zReal, double zImaginary, double cReal, double cImaginary)
          {
          double zReal2(0.0), zImaginary2(0.0); // z components squared
          size_t n(0);
          for( ; n < MaxIterations ; ++n)       // Iterate equation Zn = Zn-1**2 + K
          {                                     // for Mandelbrot K = c and Z0 = c
              zReal2 = zReal*zReal;
              zImaginary2 = zImaginary*zImaginary;
              if(zReal2 + zImaginary2 > 4)        // If distance from origin > 2, point will
                break;                            // go to infinity so we are done
              // Calculate next Z value
              zImaginary = 2*zReal*zImaginary + cImaginary;
              zReal = zReal2 - zImaginary2 + cReal;
          }
          return n;
          }
          // Select a color based on the value of n
          COLORREF Color(int n)
          {
          if(n == MaxIterations) return RGB(0, 0, 0);
          const int nColors = 22;
          switch(n%nColors)
          {
              case 0: return RGB(100,100,100);   case 1: return RGB(100,0,0);
              case 2: return RGB(200,0,0);       case 3: return RGB(100,100,0);
              case 4: return RGB(200,100,0);     case 5: return RGB(200,200,0);
              case 6: return RGB(0,200,0);       case 7: return RGB(0,100,100);
              case 8: return RGB(0,200,100);     case 9: return RGB(0,100,200);
              case 10: return RGB(0,200,200);    case 11: return RGB(0,0,200);
              case 12: return RGB(100,0,100);    case 13: return RGB(200,0,100);
              case 14: return RGB(100,0,200);    case 15: return RGB(200,0,200);
                  case 16: return RGB(120,0,200);    case 17: return RGB(200,66,200);
                      case 18: return RGB(240,0,200);    case 19: return RGB(44,33,44);
                          case 20: return RGB(40,40,200);    case 21: return RGB(33,30,40);
          


          5楼2011-03-31 17:51
          回复
                default: return RGB(200,200,200);
            };
            }
            // Draws the Mandelbrot set
            void DrawSet(HWND hWnd)
            {
            // Get client area dimensions, which will be the image size
            RECT rect;
            GetClientRect(hWnd, &rect);
            int imageHeight(rect.bottom);
            int imageWidth(rect.right);
            // Create bitmap for one row of pixels in image
            HDC Hdc(GetDC(hWnd));                  // Get device context
            HDC hdc = CreateCompatibleDC(Hdc);
            HDC memDC = CreateCompatibleDC(Hdc);   // Get device context to draw pixels
            HBITMAP bmp = CreateCompatibleBitmap(Hdc, imageWidth, 1);
            HGDIOBJ oldBmp = SelectObject(memDC, bmp);   // Selct bitmap into DC
            HBITMAP bmp2 = CreateCompatibleBitmap(Hdc, imageWidth, imageHeight);
            HGDIOBJ oldBmp2 = SelectObject(hdc, bmp2);   // Selct bitmap into DC
            // Client area axes
            const double realMin(-2.1);       // Minimum real value
            double imaginaryMin(-1.3);        // Minimum imaginary value
            double imaginaryMax(+1.3);        // Maximum imaginary value
            //const double realMin(-2.1);       // Minimum real value
            //double imaginaryMin(-1.3);        // Minimum imaginary value
            //double imaginaryMax(+1.3);        // Maximum imaginary value
            // Set maximum imaginary so axes are the same scale
            double realMax(realMin+(imaginaryMax-imaginaryMin)*imageWidth/imageHeight);
            // Get scale factors to convert pixel coordinates
            double realScale((realMax-realMin)/(imageWidth-1));
            double imaginaryScale((imaginaryMax-imaginaryMin)/(imageHeight-1));
            double cReal(0.0), cImaginary(0.0);   // Stores c components
            double zReal(0.0), zImaginary(0.0);   // Stores z components
            for(int y = 0 ; y < imageHeight ; ++y)             // Iterate over image rows
            {
                zImaginary = cImaginary = imaginaryMax - y*imaginaryScale;
                for(int x = 0 ; x < imageWidth ; ++x)            // Iterate over pixels in a row
                {
                  zReal = cReal = realMin + x*realScale;
                  // Set current pixel color based on n
                  SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
                }
                // Transfer pixel row to client area device context
                BitBlt(hdc, 0, y, imageWidth, 1, memDC, 0, 0, SRCCOPY);
            }
            BitBlt( Hdc, 0,0, imageWidth,imageHeight, hdc, 0,0, SRCCOPY );
            SelectObject(memDC, oldBmp);
            DeleteObject(bmp);                       // Delete bitmap
            


            6楼2011-03-31 17:51
            回复
              SelectObject(hdc, oldBmp2 );
              DeleteObject(bmp2);
              DeleteDC(memDC);                         // and our working DC
              DeleteDC(hdc);                           // and client area DC
              }
              // Draws the Mandelbrot set
              void DrawSetParallel(HWND hWnd)
              {
              HDC hdc(GetDC(hWnd));                  // Get device context
              // Get client area dimensions, which will be the image size
              RECT rect;
              GetClientRect(hWnd, &rect);
              int imageHeight(rect.bottom);
              int imageWidth(rect.right);
              // Create bitmap for one row of pixels in image
              HDC memDC1 = CreateCompatibleDC(hdc);   // Get device context to draw pixels
              HDC memDC2 = CreateCompatibleDC(hdc);   // Get device context to draw pixels
              HBITMAP bmp1 = CreateCompatibleBitmap(hdc, imageWidth, 1);
              HBITMAP bmp2 = CreateCompatibleBitmap(hdc, imageWidth, 1);
              HGDIOBJ oldBmp1 = SelectObject(memDC1, bmp1);   // Select bitmap into DC1
              HGDIOBJ oldBmp2 = SelectObject(memDC2, bmp2);   // Select bitmap into DC2
              // Client area axes
              const double realMin(-2.1);       // Minimum real value
              double imaginaryMin(-1.3);        // Minimum imaginary value
              double imaginaryMax(+1.3);        // Maximum imaginary value
              // Set maximum real so axes are the same scale
              double realMax(realMin+(imaginaryMax-imaginaryMin)*imageWidth/imageHeight);
              // Get scale factors to convert pixel coordinates
              double realScale((realMax-realMin)/(imageWidth-1));
              double imaginaryScale((imaginaryMax-imaginaryMin)/(imageHeight-1));
                  // Lambda expression to create an image row
                   auto rowCalc = [&] (HDC& memDC, int yLocal)
                  {
                    double zReal(0.0), cReal(0.0);
                    double zImaginary(imaginaryMax - yLocal*imaginaryScale);
                    double cImaginary(zImaginary);
                    for(int x = 0 ; x < imageWidth ; ++x)            // Iterate over pixels in a row
                    {
                      zReal = cReal = realMin + x*realScale;
                      // Set current pixel color based on n
                      SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
                    }
                  };
              Concurrency::task_group taskGroup;
              


              7楼2011-03-31 17:51
              回复
                for(int y = 1 ; y < imageHeight ; y += 2)             // Iterate over image rows
                {
                    taskGroup.run([&]{rowCalc(memDC1, y-1);});
                    rowCalc(memDC2, y);
                    taskGroup.wait();   
                    BitBlt(hdc, 0, y-1, imageWidth, 1, memDC1, 0, 0, SRCCOPY);
                    BitBlt(hdc, 0, y, imageWidth, 1, memDC2, 0, 0, SRCCOPY);
                }
                // If there's an odd number of rows, take care of the last one
                if(imageHeight%2 == 1)
                {
                    rowCalc(memDC1, imageWidth-1);
                    BitBlt(hdc, 0, imageHeight-1, imageWidth, 1, memDC1, 0, 0, SRCCOPY);
                }
                SelectObject(memDC1, oldBmp1);
                SelectObject(memDC2, oldBmp2);
                DeleteObject(bmp1);                       // Delete bitmap 1
                DeleteObject(bmp2);                       // Delete bitmap 2
                DeleteDC(memDC1);                         // and our working DC 1
                DeleteDC(memDC2);                         // and our working DC 2
                ReleaseDC(hWnd, hdc);                     // Release client area DC
                }
                void UpdateStatusBarTime(HWND hWnd, double time)
                {
                std::basic_stringstream<TCHAR> ss;                // Create a string stream
                ss.setf(std::ios::fixed, std::ios::floatfield);   // Turn on fixed & turn off float
                ss.precision(2);                                  // Two decimal places
                ss << _T(" ") << time << _T(" seconds");         // Write time to ss
                SendMessage(GetDlgItem(hWnd, 0), SB_SETTEXT, 1, (LPARAM)(ss.str().c_str()));
                }
                


                8楼2011-03-31 17:51
                回复