// ■マンデルブロー集合(Mandelbrot set)の描画 // // CST: 計算開始実数部, CED: 計算終了実数部 // DST: 計算開始虚数部, DED: 計算終了虚数部 // SC: スケール, DT: 計算ステップ数 // XST, YST: 表示画面中央位置の画面XY座標 // (修練も発散も検出できなかった場所は黒で表示する) // // @右ボタンダブルクリックで配色タイプを変更します。 // A左ボタンダブルクリックで拡大します。 // B左ボタンドラッギングで上下または左右に動きます。 // (斜めには動きませんので、上下/左右の組み合わせで移動して下さい) // C右ボタンドラッギングで縮小します。 // #include "myWin.h" #define swap(type, x,y) do{type t;t=x;x=y;y=t;}while(0) // LOOPを大きくすると絵が緻密になるが、速度が遅くなる。 #define LOOP 1024 // 初期値は以下のように設定しよう。 double CST = -2 , CED = 2 , DST = -2; //double CST = -1.1125, CED = -1.1075, DST = -0.25; //double CST = -1.115 , CED = -1.105 , DST = -0.25; //double CST = -1.3 , CED = -0.9 , DST = -0.5; //double CST = -1 , CED = -0.9 , DST = 0.2; //double CST = 0 , CED = 0.002 , DST = 0.636; //double CST = -0.9995, CED = -0.9990, DST = 0.2870; //double CST = -0.9995, CED = -0.9994, DST = 0.2870; double DED, DT, SC, XST, YST; int curX,curY; int exID[]={0x000077, 0x0000AA, 0x0000FF, 0x0077FF, 0x00FFFF, 0x77FFFF};//発散したときの色 int cnID[]={0x770000, 0xAA0000, 0xFF0000, 0xFF7700, 0xFFFF00, 0xFFFF77};//収斂したときの色 int cType=1; 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= 4) return (i%256); // 発散判定(発散したとき正の数) DA = A - AA; DB = B - BB; // 収斂判定(収斂したとき負の数) if((DA * DA + DB * DB) < 0.00001) return -(i %256); } 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); } int setColor(int ID){ if(ID==0)return 0; else if(ID<0){ ID=-ID; if(ID<64)return RGB(0,ID*4, 0); if(ID<128)return RGB(ID*4-256, 255, 0); if(ID<192)return RGB(255,767-ID*4, 0); return RGB(255,ID*4-768,0); } if(ID<64)return RGB(0,ID*4, 255); if(ID<128)return RGB(ID*4-256, 255,255); if(ID<192)return RGB(255,767-ID*4, 255); return RGB(255,ID*4-768,255); } void Mandelbrot(){ if(CST>CED) swap(double, CST,CED); double DR=CED-CST; SC = 400/DR;DED = DST + DR; DT = 1.0 / SC; 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; if(cType==0) CL=(ID==0)? 0:(ID>0 ? exID[ID % 6]: cnID[(-ID) % 6]); else if(cType==1) CL=setColor(ID%256); else CL=(abs(ID)%4096)*(4096/LOOP)-1; 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 procLButtonDown(HWND hw, WPARAM wp, LPARAM lp){ curX=LOWORD(lp); curY=HIWORD(lp); } void procLButtonUp(HWND hw, WPARAM wp, LPARAM lp){ int x=LOWORD(lp), y=HIWORD(lp), XX=x-curX, YY=y-curY; if(abs(XX)<5 && abs(YY)<5) return; if(abs(XX)> abs(YY)) { double DC = (CED-CST); if(XX<0) CST+=DC*0.1; else CST-=DC*0.1; CED=CST+DC; } else{ double DD = (DED-DST); if(YY<0) DST-=DD*0.1; else DST+=DD*0.1; } Mandelbrot(); InvalidateRect(hw,NULL,FALSE); } void procLButtonDblClk(HWND hw, WPARAM wp, LPARAM lp){ int x=LOWORD(lp), y=HIWORD(lp); double c=(double)(x-XST)/SC, d=(double)(YST-y)/SC; CST=(c+CST*4)/5; CED=(c+CED*4)/5; DST=(d+DST*4)/5; Mandelbrot(); InvalidateRect(hw,NULL,FALSE); } void procRButtonDblClk(HWND hw, WPARAM wp, LPARAM lp){ cType=cType++;if(cType>2)cType=0; Mandelbrot(); InvalidateRect(hw,NULL,FALSE); } void procRButtonDown(HWND hw, WPARAM wp, LPARAM lp){ curX=LOWORD(lp); curY=HIWORD(lp); } void procRButtonUp(HWND hw, WPARAM wp, LPARAM lp){ int x=LOWORD(lp), y=HIWORD(lp), XX=x-curX, YY=y-curY; if(abs(XX)<5 && abs(YY)<5) return; double DC = (CED-CST); CST -= DC*0.1; CED += DC*0.1; DST -= DC*0.1; 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; case WM_LBUTTONDOWN : procLButtonDown (hw, wp, lp); return 0; case WM_LBUTTONUP : procLButtonUp (hw, wp, lp); return 0; case WM_RBUTTONDOWN : procRButtonDown (hw, wp, lp); return 0; case WM_RBUTTONUP : procRButtonUp (hw, wp, lp); return 0; case WM_LBUTTONDBLCLK : procLButtonDblClk (hw, wp, lp); return 0; case WM_RBUTTONDBLCLK : procRButtonDblClk (hw, wp, lp); return 0; } return DefWindowProc(hw, msg, wp, lp); }