討論區快速選單
知識庫快速選單
討論區最近新進100則主題 政府補助!學嵌入式+物聯網 沒有人比Cloudera更了解大數據
[ 回上頁 ] [ 討論區發言規則 ]
碎形幾何測試程式
更改我的閱讀文章字型大小
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1003 | 人氣 3227 | 評價 1260 | 評價/貼文 1.26 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/5/6 下午 02:31:42
https://youtu.be/kfXl5fsVBVY

以上影片說的是碎形幾何,若覺得手癢也想試試,以下的程式可幫上一點忙。

程式使用到 CxxlMan2 程式庫,可到 https://1drv.ms/u/s!Ap_vSwKlDD2gqWgkbgj_x6QbCoSS 下載,不過只用到 cxxlcommon\include 內的引入檔,所以不用編譯這個程式庫,只要把 THREADMGR.HPP 所在的完整路徑加到 include path 就可以了。

程式在 Win10 用 vs2015 和 MinGW 6.3 編譯跑過沒有問題,程式只是一個架構,把程式碼整個複製貼上就能用了。
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1003 | 人氣 3227 | 評價 1260 | 評價/貼文 1.26 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/5/6 下午 02:33:03
#include <windows.h>
#include <THREADMGR.HPP>

using namespace CxxlMan2;

HWND g_hwnd;
bool isQuit = false;
HDC g_memDC; // 輔助繪圖設備
RECT g_rcClient;//區域結構
const Tchar *g_szClassName = TEXT("myWindowClass");

// 主要的功能宣告,邏輯運算放這裡,自由發揮
void Fractal(float X, float Y, ThreadLimit &Fractal_TL);

// Fractal() 算出來的結果交由這函數畫到畫布上
// 畫布左上是 (0.0, 0.0) 右下是 (1.0, 1.0)
void Show(float X, float Y)
{
 SetPixel(g_memDC, g_rcClient.right * X, g_rcClient.bottom * Y,
      RGB(255, 0, 0));
 InvalidateRect(g_hwnd, nullptr, false);
}


void Draw()
{
 HDC hDC = GetDC(g_hwnd); //獲得系統繪圖設備
 g_memDC = CreateCompatibleDC(0); //創建輔助繪圖設備

 GetClientRect(g_hwnd, &g_rcClient);//獲得 client 區域

 //創建掩碼位圖(畫布)
 HBITMAP bmpBack = CreateCompatibleBitmap(hDC,
  g_rcClient.right - g_rcClient.left,
  g_rcClient.bottom - g_rcClient.top);

 SelectObject(g_memDC, bmpBack); //將畫布貼到繪圖設備上

 //擦除背景
 //獲得庫存物體,白色畫刷。
 HBRUSH brushTemp = (HBRUSH)GetStockObject(WHITE_BRUSH);
 FillRect(g_memDC, &g_rcClient, brushTemp);//填充客戶區域。

 // 加上區塊可以等待 Fractal_TL 結束才繼續
 {
  ThreadLimit Fractal_TL(std::thread::hardware_concurrency());
  Fractal_TL.Thread(Fractal, 0.5, 0.5, std::ref(Fractal_TL));
 }

 DeleteObject(bmpBack); //釋放位圖資源
 DeleteDC(g_memDC); //釋放輔助繪圖設備
 ReleaseDC(g_hwnd, hDC); //歸還繫統繪圖設備
 PostMessage(g_hwnd, WM_DESTROY, 0, 0);
}


// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, Uint msg,
 WPARAM wParam, LPARAM lParam)
{
 switch (msg)
 {
 case WM_KEYDOWN:
  if (wParam == 0x51) // Q key
   isQuit = true;
 case WM_PAINT:
 {
  PAINTstruct ps;
  HDC hdc = BeginPaint(hwnd, &ps);
  if (g_memDC)
   //複製到系統設備上顯示..
   BitBlt(hdc, g_rcClient.left, g_rcClient.top,
    g_rcClient.right, g_rcClient.bottom,
    g_memDC, 0, 0, SRCCOPY);

  EndPaint(hwnd, &ps);
 }
 break;

 case WM_CLOSE:
  DestroyWindow(hwnd);
  break;
 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 default:
  return DefWindowProc(hwnd, msg, wParam, lParam);
 }
 return 0;
}

作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1003 | 人氣 3227 | 評價 1260 | 評價/貼文 1.26 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/5/6 下午 02:33:35
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPSTR lpCmdLine, int nCmdShow)
{
 WNDCLASSEX wc;
 MSG Msg;

 //Step 1: Registering the Window Class
 wc.cbSize = sizeof(WNDCLASSEX);
 wc.style = 0;
 wc.lpfnWndProc = WndProc;
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 wc.hInstance = hInstance;
 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
 wc.lpszMenuName = NULL;
 wc.lpszClassName = g_szClassName;
 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

 if (!RegisterClassEx(&wc))
 {
  MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"),
   MB_ICONEXCLAMATION | MB_OK);
  return 0;
 }

 // Step 2: Creating the Window
 g_hwnd = CreateWindowEx(
  WS_EX_CLIENTEDGE,
  g_szClassName,
  TEXT("碎形測試"),
  WS_OVERLAPPEDWINDOW,
  CW_USEdefault, CW_USEdefault, 300, 300,
  NULL, NULL, hInstance, NULL);

 if (g_hwnd == NULL)
 {
  MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"),
   MB_ICONEXCLAMATION | MB_OK);
  return 0;
 }

 ShowWindow(g_hwnd, nCmdShow);
 UpdateWindow(g_hwnd);

 ThreadLimit TL(1);
 TL.Thread(Draw);

 // Step 3: The Message Loop
 while (GetMessage(&Msg, NULL, 0, 0) > 0)
 {
  TranslateMessage(&Msg);
  DispatchMessage(&Msg);
 }
 return Msg.wParam;
}

// 以下是實作的程式碼,可依自己的想法做修改
float Ax = 0.5, Ay = 0.1,
   Bx = 0.1, By = 0.9,
   Cx = 0.9, Cy = 0.9;

void Fractal(float X, float Y, ThreadLimit &Fractal_TL)
{
 if (isQuit == false)
 {
  Show(X, Y);
  Fractal_TL.Thread(Fractal, X + (Ax - X) / 2, Y + (Ay - Y) / 2,
           std::ref(Fractal_TL));
  Fractal_TL.Thread(Fractal, X + (Bx - X) / 2, Y + (By - Y) / 2,
           std::ref(Fractal_TL));
  Fractal_TL.Thread(Fractal, X + (Cx - X) / 2, Y + (Cy - Y) / 2,
           std::ref(Fractal_TL));
 }
 else
  Fractal_TL.Clear();
}
作者 : cxxlman(CxxlMan) C++優秀好手貼文超過1000則
[ 貼文 1003 | 人氣 3227 | 評價 1260 | 評價/貼文 1.26 | 送出評價 27 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/5/6 下午 02:34:12
執行時可按 Q 鍵結束程式,因程式使用 ThreadLimit 作為任務的處理工具,加上程式的任務沒有止境,若不按 Q 鍵結束程式也會因記憶體資源用完而自行結束程式。

其中 Fractal() 可以依自己的想法自己做修改,其他的部份沒必要就不用去動它,注意程式的畫布定義左上為 (0.0, 0.0) 右下為 (1.0, 1.0)。下圖是執行結果的截圖:
http://imagizer.imageshack.us/a/img924/7278/XFHh8e.png

影片採用的是隨機的表現方法,這程式採用量子演算法,意思是只要有可能就讓它發生,也就是走遍所有可能,也叫窮盡法或暴力法。影片採用隨機的表演方式是正確的,比較有衝擊性的戲劇效果,不然一板一眼的說明,可能沒人會繼續看下去。
 板主 : simula
 > C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++
1 Raymond 13050 
2 青衫 4760 
3 simula 4690 
4 coco 4030 
5 白老鼠(Gary) 3670 
6 ozzy 2540 
7 Ben 2250 
8 Anderson 1960 
9 windblown 1650 
10 Kenny 1560 
C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.140625