Advertisement
Cieslin

PRIR FRAKTALE

Nov 8th, 2018
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.68 KB | None | 0 0
  1. /************************************************************
  2.  * -- NIE USUWAJ TEJ INFORMACJI Z PROGRAMU ---------------- *
  3.  ************************************************************
  4.  * -- Program powstał na bazie kodu źródłowego ------------ *
  5.  * -- udostępnionego studentom na potrzeby przedmiotu ----- *
  6.  * -- Programowanie Równoległe i Rozproszone -------------- *
  7.  * -- Copyright (c) 2013 Politechnika Śląska w Gliwicach -- *
  8.  * -- Wydział Elektryczny --------------------------------- *
  9.  * -- Radosław Sokół, Marcin Połomski --------------------- *
  10.  ************************************************************/
  11.  
  12. #include <assert.h>
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include <exception>
  16. #include <omp.h>
  17.  
  18. #include "Complex.h"
  19.  
  20. TCHAR NazwaAplikacji[] = TEXT("FRAKTALE");
  21. TCHAR NazwaKlasy[] = TEXT("OKNOGLOWNE");
  22.  
  23. const int ImageWidth = 1024;
  24. const int ImageHeight = 768;
  25. char *Obraz = NULL;
  26.  
  27. unsigned char NrAlgorytmu = 0;
  28. double CzasPrzetwarzania = 0.0;
  29. TCHAR tAlgorytm[64];
  30. unsigned char tadl = 0;
  31. const int L_WATKOW = 8;
  32.  
  33. struct RGB { unsigned char B, G, R; };
  34.  
  35. inline unsigned int RoundUp4(const unsigned int i)
  36. {
  37.     return (i+3)&(~3);
  38. }
  39.  
  40. void WyczyscObraz(RGB* Raster, int Width, int Height)
  41. {
  42.     RGB *Punkt;
  43.     for (int y = 0; y < Height; ++y)
  44.     {
  45.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);      
  46.         for (int x = 0; x < Width; ++x)
  47.         {
  48.             Punkt->R = 0;
  49.             Punkt->G = 0;
  50.             Punkt->B = 0;          
  51.             ++Punkt;
  52.         }
  53.     }
  54. }
  55.  
  56. // Mandelbrot =====================================================================================
  57.  
  58. int IterateMandelbrot(Complex P, int maxIter)
  59. {
  60.     Complex z = P;
  61.     int cnt = 0;
  62.     while((z.x * z.x + z.y * z.y <= 4)&& (cnt < maxIter)){
  63.         z = ComplexSquare(z);
  64.         z.x += P.x;
  65.         z.y += P.y;
  66.         cnt++;
  67.     }
  68.     return cnt;
  69. }
  70.  
  71. void Mandelbrot(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax)
  72. {
  73.     RGB *Punkt;
  74.     float realInc = (RealMax - RealMin) / Width;
  75.     float imagInc = (ImagMax - ImagMin) / Height;
  76.     Complex z;
  77.     int x, y;
  78.     int cnt;
  79.  
  80.     for (y = 0, z.y = ImagMin; y < Height; ++y, z.y += imagInc)
  81.     {
  82.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  83.        
  84.         for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  85.         {
  86.             cnt = IterateMandelbrot(z, MaxIter);
  87.            
  88.             if(cnt == MaxIter)
  89.             {
  90.                 Punkt->R = 255;
  91.                 Punkt->G = 255;
  92.                 Punkt->B = 255;
  93.             }
  94.             else
  95.             {
  96.                 Punkt->R = 0;
  97.                 Punkt->G = cnt;
  98.                 Punkt->B = 0;
  99.             }
  100.            
  101.             ++Punkt;
  102.         }
  103.     }
  104. }
  105.  
  106. void MandelbrotParallel(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax)
  107. {
  108.     RGB *Punkt;
  109.     float realInc = (RealMax - RealMin) / Width;
  110.     float imagInc = (ImagMax - ImagMin) / Height;
  111.     Complex z;
  112.     int x, y;
  113.     int cnt;
  114.  
  115. #pragma omp parallel for private(y, Punkt, x, cnt, z) num_threads(L_WATKOW)
  116.         for (y = 0 ; y < Height; ++y )
  117.         {
  118.         z.y=ImagMin+imagInc*y;
  119.             Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  120.             for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  121.             {
  122.                 cnt = IterateMandelbrot(z, MaxIter);
  123.  
  124.                 if(cnt == MaxIter)
  125.                 {
  126.                     Punkt->R = 255;
  127.                     Punkt->G = 255;
  128.                     Punkt->B = 255;
  129.                 }
  130.                 else
  131.                 {
  132.                     Punkt->R = 0;
  133.                     Punkt->G = cnt;
  134.                     Punkt->B = 0;
  135.                 }
  136.                 ++Punkt;
  137.             }
  138.         }
  139. }
  140.  
  141. // Julia ==========================================================================================
  142.  
  143. int IterateJulia(Complex zInit, int maxIter, Complex c)
  144. {
  145.     Complex z = zInit;
  146.     int cnt = 0;
  147.     while((z.x * z.x + z.y * z.y <= 4)&& (cnt < maxIter)){
  148.         z = ComplexSquare(z);
  149.         z.x += c.x;
  150.         z.y += c.y;
  151.         cnt++;
  152.     }
  153.     return cnt;
  154. }
  155.  
  156. void Julia(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax, Complex c)
  157. {
  158.     RGB *Punkt;
  159.     float realInc = (RealMax - RealMin) / Width;
  160.     float imagInc = (ImagMax - ImagMin) / Height;
  161.     Complex z;
  162.     int x, y;
  163.     int cnt;
  164.  
  165.     for (y = 0, z.y = ImagMin; y < Height; ++y, z.y += imagInc)
  166.     {
  167.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  168.  
  169.         for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  170.         {
  171.             cnt = IterateJulia(z, MaxIter, c);
  172.  
  173.             if(cnt == MaxIter)
  174.             {
  175.                 Punkt->R = 255;
  176.                 Punkt->G = 255;
  177.                 Punkt->B = 255;
  178.             }
  179.             else
  180.             {
  181.                 Punkt->R = 0;
  182.                 Punkt->G = cnt;
  183.                 Punkt->B = 0;
  184.             }
  185.  
  186.             ++Punkt;
  187.         }
  188.     }
  189. }
  190.  
  191. void JuliaParallel(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax, Complex c)
  192. {
  193.     RGB *Punkt;
  194.     float realInc = (RealMax - RealMin) / Width;
  195.     float imagInc = (ImagMax - ImagMin) / Height;
  196.     Complex z;
  197.     int x, y;
  198.     int cnt;
  199.  
  200.     #pragma omp parallel for private(x, y, z, cnt, Punkt) num_threads(L_WATKOW)
  201.     for (y = 0; y < Height; ++y)
  202.     {
  203.         z.y = ImagMin+imagInc*y;
  204.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  205.  
  206.         for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  207.         {
  208.             cnt = IterateJulia(z, MaxIter, c);
  209.  
  210.             if(cnt == MaxIter)
  211.             {
  212.                 Punkt->R = 255;
  213.                 Punkt->G = 255;
  214.                 Punkt->B = 255;
  215.             }
  216.             else
  217.             {
  218.                 Punkt->R = 0;
  219.                 Punkt->G = cnt;
  220.                 Punkt->B = 0;
  221.             }
  222.             ++Punkt;
  223.         }
  224.         z.y += imagInc;
  225.     }
  226. }
  227.  
  228.  
  229. static void GenerujFraktal()
  230. {
  231.     assert(sizeof(RGB) == 3);
  232.     BITMAPFILEHEADER *bfh = reinterpret_cast<BITMAPFILEHEADER*>(Obraz);
  233.     BITMAPINFO *bi = reinterpret_cast<BITMAPINFO*>(Obraz + sizeof(BITMAPFILEHEADER));
  234.     RGB *Raster = reinterpret_cast<RGB*>(Obraz + bfh->bfOffBits);
  235.    
  236.     int Width = bi->bmiHeader.biWidth;
  237.     int Height = bi->bmiHeader.biHeight;
  238.  
  239.     // Stała C1 uzywane podczas generowania zbioru Julii
  240.     Complex c1;
  241.     c1.x = 0.281f; c1.y = 0.011f;
  242.    
  243.     // Stała C2 uzywane podczas generowania zbioru Julii
  244.     Complex c2;
  245.     c2.x = -0.810f; c2.y = 0.179f;
  246.    
  247.     switch (NrAlgorytmu)
  248.     {
  249.         case 0:
  250.             // Mandelbrot Sekwencyjny ----------------------------------------------------------------------           
  251.             tadl = wsprintf(tAlgorytm, TEXT(". . ."));         
  252.             WyczyscObraz(Raster, Width, Height);
  253.             break;
  254.  
  255.         case 1:        
  256.             tadl = wsprintf(tAlgorytm, TEXT("Mandlebrot Sekwencyjny"));
  257.             Mandelbrot(Raster, Width, Height, 500, -2.0f, 0.8f, -1.0f, 1.0f);          
  258.             break;
  259.  
  260.         case 2:          
  261.             tadl = wsprintf(tAlgorytm, TEXT("Julia Sekwencyjny dla C1"));          
  262.             Julia(Raster, Width, Height, 500, -1.0f, 1.0f, -1.0f, 1.0f, c1);
  263.             break;
  264.  
  265.         case 3:        
  266.             tadl = wsprintf(tAlgorytm, TEXT("Julia Sekwencyjny dla C2"));          
  267.             Julia(Raster, Width, Height, 500, -1.0f, 1.0f, -0.8f, 0.8f, c2);
  268.             break;
  269.  
  270.         case 4:
  271.             {
  272.                 tadl = wsprintf(tAlgorytm, TEXT("Mandelbrot Zrównoleglony"));
  273.                 MandelbrotParallel(Raster, Width, Height, 500, -2.0f, 0.8f, -1.0f, 1.0f);
  274.             }
  275.             break;     
  276.  
  277.         case 5:
  278.             {
  279.                 tadl = wsprintf(tAlgorytm, TEXT("Julia Zrównoleglony dla C1"));           
  280.                 JuliaParallel(Raster, Width, Height, 500, -1.0f, 1.0f, -1.0f, 1.0f, c1);
  281.             }
  282.             break;
  283.  
  284.         case 6:    
  285.             {
  286.                 tadl = wsprintf(tAlgorytm, TEXT("Julia Zrównoleglony dla C2"));
  287.                 JuliaParallel(Raster, Width, Height, 500, -1.0f, 1.0f, -0.8f, 0.8f, c2);
  288.             }
  289.             break; 
  290.  
  291.         default:           
  292.             tadl = wsprintf(tAlgorytm, TEXT(". . ."));         
  293.             WyczyscObraz(Raster, Width, Height);
  294.             break;
  295.     }
  296. }
  297.  
  298. static void Tworz(const HWND Okno)
  299. {
  300.     BITMAPFILEHEADER   bmfHeader;
  301.     BITMAPINFOHEADER   bi;
  302.    
  303.     bi.biSize = sizeof(BITMAPINFOHEADER);    
  304.     bi.biWidth = ImageWidth;
  305.     bi.biHeight = ImageHeight;
  306.     bi.biPlanes = 1;
  307.     bi.biBitCount = 24;
  308.     bi.biCompression = BI_RGB;    
  309.     bi.biSizeImage = 0;
  310.     bi.biXPelsPerMeter = 0;    
  311.     bi.biYPelsPerMeter = 0;    
  312.     bi.biClrUsed = 0;    
  313.     bi.biClrImportant = 0;
  314.    
  315.     DWORD dwBmpSize = ImageWidth * ImageHeight * bi.biBitCount/8;
  316.     HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
  317.     char *lpbitmap = (char *)GlobalLock(hDIB);
  318.    
  319.     DWORD dwSizeOfDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);   
  320.     bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
  321.     bmfHeader.bfSize = dwSizeOfDIB;
  322.     bmfHeader.bfType = 0x4D42;
  323.    
  324.     Obraz = new char[dwSizeOfDIB];
  325.     CopyMemory(Obraz, &bmfHeader, sizeof(BITMAPFILEHEADER));
  326.     CopyMemory(Obraz + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));
  327.     CopyMemory(Obraz + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER), lpbitmap, dwBmpSize);
  328.  
  329.     GlobalUnlock(hDIB);
  330.     GlobalFree(hDIB);
  331. }
  332.  
  333. static void Rysuj(const HWND Okno)
  334. {
  335.     RECT Rozmiar;
  336.     TCHAR Tekst[128];
  337.     PAINTSTRUCT PS;
  338.     unsigned int dl;
  339.     GetClientRect(Okno, &Rozmiar);
  340.     const HDC DC = BeginPaint(Okno, &PS);
  341.     if (Obraz != 0) {
  342.         BITMAPFILEHEADER *bfh = reinterpret_cast<BITMAPFILEHEADER*>(Obraz);
  343.         BITMAPINFO *bi = reinterpret_cast<BITMAPINFO*>(Obraz + sizeof(BITMAPFILEHEADER));
  344.         SetStretchBltMode(DC, HALFTONE);
  345.         StretchDIBits(DC, 0, 0, Rozmiar.right, Rozmiar.bottom, 0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
  346.             static_cast<void*>(Obraz + bfh->bfOffBits), bi, DIB_RGB_COLORS, SRCCOPY);
  347.         dl = swprintf_s(Tekst, TEXT("Czas obliczeń: %.2lf s"), CzasPrzetwarzania);
  348.         TextOut(DC, 5, 5, Tekst, dl);
  349.         TextOut(DC, 5, 25, tAlgorytm, tadl);
  350.     }
  351.     EndPaint(Okno, &PS);
  352. }
  353.  
  354. static void Znak(const HWND Okno, const TCHAR Znak)
  355. {
  356.     if (Znak >= TEXT('0') && Znak <= TEXT('9')) {      
  357.         SYSTEMTIME S1, S2;
  358.         NrAlgorytmu = Znak - TEXT('0');
  359.         SetWindowText(Okno, TEXT("Przetwarzanie..."));     
  360.         GetSystemTime(&S1);
  361.         if (NrAlgorytmu >= 0 && NrAlgorytmu <= 9)
  362.         {
  363.             GenerujFraktal();
  364.         }
  365.         GetSystemTime(&S2);
  366.         CzasPrzetwarzania = 3600.0 * (S2.wHour - S1.wHour) + 60.0 * (S2.wMinute - S1.wMinute)
  367.             + (S2.wSecond - S1.wSecond) + 0.001 * (S2.wMilliseconds - S1.wMilliseconds);       
  368.         InvalidateRect(Okno, NULL, FALSE);
  369.         SetWindowText(Okno, NazwaAplikacji);
  370.         UpdateWindow(Okno);
  371.     }
  372.  
  373.     if(Znak == 27)
  374.     {
  375.         DestroyWindow(Okno);
  376.     }
  377. }
  378.  
  379. static LRESULT CALLBACK FunkcjaOkienkowa(HWND Okno, UINT Komunikat, WPARAM wParam, LPARAM lParam)
  380. {
  381.     switch (Komunikat) {
  382.         case WM_CREATE:
  383.             Tworz(Okno);
  384.             tadl = wsprintf(tAlgorytm, TEXT("..."));
  385.             break;
  386.         case WM_CHAR:
  387.             Znak(Okno, static_cast<TCHAR>(wParam));
  388.             break;
  389.         case WM_PAINT:
  390.             Rysuj(Okno);
  391.             break;
  392.         case WM_DESTROY:
  393.             delete [] Obraz;
  394.             PostQuitMessage(0);
  395.             break;
  396.         default:
  397.             return DefWindowProc(Okno, Komunikat, wParam, lParam);
  398.     }
  399.     return 0;
  400. }
  401.  
  402. static bool RejestrujKlasy()
  403. {
  404.     WNDCLASSEX wc;
  405.     wc.cbSize = sizeof(WNDCLASSEX);
  406.     wc.cbClsExtra = wc.cbWndExtra = 0;
  407.     wc.hbrBackground = (HBRUSH) (1 + COLOR_WINDOW);
  408.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  409.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  410.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  411.     wc.hInstance = GetModuleHandle(NULL);
  412.     wc.lpfnWndProc = &FunkcjaOkienkowa;
  413.     wc.lpszClassName = NazwaKlasy;
  414.     wc.lpszMenuName = NULL;
  415.     wc.style = CS_HREDRAW | CS_VREDRAW;
  416.     return (RegisterClassEx(&wc) != 0);
  417. }
  418.  
  419. static void WyrejestrujKlasy()
  420. {
  421.     UnregisterClass(NazwaKlasy, GetModuleHandle(NULL));
  422. }
  423.  
  424. int WINAPI WinMain(HINSTANCE Instancja, HINSTANCE Poprzednia, LPSTR Parametry, int Widocznosc)
  425. {
  426.     // Zarejestruj klasę. Protestuj, jeżeli wystąpił błąd.
  427.     if (!RejestrujKlasy()) {
  428.         MessageBox(NULL, TEXT("Nie udało się zarejestrować klasy okna!"),
  429.             NazwaAplikacji, MB_ICONSTOP | MB_OK);
  430.         return 1;
  431.     }
  432.     // Stwórz główne okno. Również protestuj, jeżeli wystąpił błąd.
  433.     HWND GlowneOkno = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_CLIENTEDGE,
  434.         NazwaKlasy, NazwaAplikacji, WS_OVERLAPPEDWINDOW,
  435.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  436.         NULL, NULL, Instancja, NULL);
  437.     if (GlowneOkno == NULL) {
  438.         MessageBox(NULL, TEXT("Nie udało się stworzyć głównego okna!"),
  439.             NazwaAplikacji, MB_ICONSTOP | MB_OK);
  440.         return 2;
  441.     }
  442.     // Wyświetl i uaktualnij nowo stworzone okno.
  443.     ShowWindow(GlowneOkno, Widocznosc);
  444.     UpdateWindow(GlowneOkno);
  445.     // Główna pętla komunikatów wątku.
  446.     MSG Komunikat;
  447.     while (GetMessage(&Komunikat, NULL, 0, 0) > 0) {
  448.         TranslateMessage(&Komunikat);
  449.         DispatchMessage(&Komunikat);
  450.     }
  451.     // Zwolnij pamięć klas i zakończ proces.
  452.     WyrejestrujKlasy();
  453.     return static_cast<int>(Komunikat.wParam);
  454. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement