// ■マンデルブロー集合(Mandelbrot set)の描画 // // CST: 計算開始実数部, CED: 計算終了実数部 // DST: 計算開始虚数部, DED: 計算終了虚数部 // SC: スケール, DT: 計算ステップ数 // XST, YST: 表示画面中央位置の画面XY座標 // (修練も発散も検出できなかった場所は黒で表示する) #include "myWin.h" double CST=-2, CED=2, DST=-2,DED=2, DT=0.01,SC=100, XST, YST; // 以下のように値を変えてみよう。 //double CST=-1.1125, CED=-1.1075, DST=-0.25,DED=-0.245, DT=0.000005,SC=80000, XST,YST; //double CST=-1.115, CED=-1.105, DST=-0.25,DED=-0.24, DT=0.000005,SC=40000, XST,YST; //double CST=-1.3, CED=-1.0, DST=-0.5,DED=-0.2, DT=0.001,SC=1000, XST,YST; //double CST=-1, CED=-0.9, DST=0.2,DED=0.3, DT=0.0001,SC=4000, XST,YST; //double CST=0, CED=0.002, DST=0.636,DED=0.638, DT=0.000002,SC=200000, XST,YST; //double CST=-0.9995, CED=-0.9990, DST=0.2870,DED=0.2875, DT=0.000001,SC=800000, XST,YST; //double CST=0, CED=0.0001, DST=0.6360,DED=0.6361, DT=0.0000002,SC=4000000, XST,YST; int exID[]={0x000077, 0x0000AA, 0x0000FF, 0x0077FF, 0x00FFFF, 0x77FFFF};//発散したときの色 int cnID[]={0x770000, 0xAA0000, 0xFF0000, 0xFF7700, 0xFFFF00, 0xFFFF77};//収斂したときの色 static HDC hbuf; static HBITMAP hBM; int Iter(double C, double D){// 複素数の繰り返し演算による発散回数の設定 double A=0, B=0, AA, BB, DA, DB; for(int i=1; i<400; i++){ AA=A; BB=B; A = AA * AA - BB * BB + C; B = 2 * AA * BB + D; if((A * A + B * B) >= 4) return i; // 発散判定(発散したとき正の数) DA = A - AA; DB = B - BB; // 収斂判定(収斂したとき負の数) if((DA * DA + DB * DB) < 0.00001) return -i; } return 0;// 収斂も発散もしないとき振動状態 } void initBitMap(HWND hw){// ビットマップ作成とメモリデバイスコンテキスト作成 HDC hdc=GetDC(hw); hBM=CreateCompatibleBitmap(hdc,1000,1000); hbuf=CreateCompatibleDC(hdc);SelectObject(hbuf,hBM); SelectObject(hbuf,GetStockObject(NULL_PEN)); PatBlt(hbuf,0,0,1000,1000,WHITENESS); ReleaseDC(hw, hdc); } void Mandelbrot(){ XST=240-SC*(CST+CED)/2; YST=230+SC*(DST+DED)/2; for(double C=CST ; C<=CED; C+=DT) for(double D=DST;D<=DED; D+=DT){ int ID=Iter(C,D), CL=(ID==0)? 0:(ID>0 ? exID[ID % 6]: cnID[(-ID) % 6]); int XP = (int)(XST + C * SC+0.5), YP=(int)(YST - D * SC+0.5); SetPixel(hbuf,XP,YP,CL); } } void procCreate(HWND hw, WPARAM wp, LPARAM lp){ SetWindowText(hw,TEXT("マンデルブロ集合(Mandelbrot Set)")); MoveWindow(hw,0,0,500,500,true); initBitMap(hw);Mandelbrot(); InvalidateRect(hw,NULL,FALSE); } void procPaint(HWND hw, WPARAM wp, LPARAM lp){// ビットマップを画面に表示 PAINTSTRUCT ps; HDC hdc=BeginPaint(hw, &ps); BitBlt(hdc,0,0,1000,1000,hbuf,0,0,SRCCOPY); EndPaint(hw,&ps); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp){ switch(msg){ case WM_DESTROY : PostQuitMessage(0) ; return 0; case WM_CREATE : procCreate(hw,wp,lp) ; return 0; case WM_PAINT : procPaint (hw, wp, lp); return 0; } return DefWindowProc(hw, msg, wp, lp); }