/*************************/
/* マンデルブロー集合 */
/* Windows版 */
/*************************/
#include <stdio.h>
#include <windows.h>
#define XMAX 800 // ウィンドウ Xmax
#define YMAX 800 // ウィンドウ Ymax
HWND hWnd=NULL; // ウィンドウのハンドル
MSG msg; // ウィンドウメッセージ
int endFG=0; // 終了フラグ
double Cr1=-2.3; // 定数実部 始点
double Cr2= 0.7; // 定数実部 終点
double Ci1=-1.5; // 定数虚部 始点
double Ci2= 1.5; // 定数虚部 終点
double E=4.0; // 発散とする値
int imax=400; // 最大計算回数
void SETwindow(void); // ウィンドウ初期設定
void Display(void); // 図形描画
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); // ウィンドウプロシージャ
void main( )
{
SETwindow( ); // ウィンドウ初期設定
while ( 1 )
{
if ( PeekMessage(&msg,hWnd,0,0,PM_REMOVE)==0 ) // windowsメッセージ取得
continue; // メッセージなし
TranslateMessage(&msg); // メッセージ変換
DispatchMessage (&msg); // メッセージ送出
if ( endFG!=0 ) break;
}
DestroyWindow(hWnd); // ウィンドウ破棄
}
void SETwindow( )
/*------------------------*/
/* ウィンドウ 初期設定 */
/*------------------------*/
{
WNDCLASS wc; // ウィンドウ クラス
DWORD Wstyle; // ウィンドウ・スタイル
//--ウィンドウクラス--
wc.lpszClassName="マンデルブロー集合"; // ウィンドウ・クラス名
wc.lpszMenuName =NULL; // クラス・メニュー・リソース名
wc.hInstance =GetModuleHandle(NULL); // インスタンス・ハンドル
wc.lpfnWndProc =WndProc; // ウィンドウ・プロシージャ
wc.hCursor =LoadCursor(NULL,IDC_ARROW); // クラス・カーソル
wc.hIcon =NULL; // クラス・アイコン
wc.hbrBackground=GetStockObject(WHITE_BRUSH); // クラス背景ブラシ
wc.style =CS_OWNDC| // クラス・スタイル
CS_BYTEALIGNCLIENT|
CS_BYTEALIGNWINDOW;
wc.cbClsExtra =0; // 補足クラス・メモリ
wc.cbWndExtra =0; // 補足ウィンドウ・メモリ
RegisterClass(&wc); // ウィンドウ・クラス登録
//--ウィンドウ・スタイル--
Wstyle= WS_OVERLAPPED| // 自動表示位置
WS_SYSMENU| // 閉じる可能
WS_MINIMIZEBOX; // 最小化可
//--ウィンドウ生成--
hWnd=CreateWindow(wc.lpszClassName, // クラス名
wc.lpszClassName, // ウィンドウ名(実行ファイル)
Wstyle, // ウィンドウ・スタイル
0, // ウインドウ水平位置
0, // ウインドウ垂直位置
XMAX, // ウィンドウXサイズ(枠含む)
YMAX+18, // ウィンドウYサイズ(枠含む)
NULL, // 親ウィンドウ・ハンドル
NULL, // メニューハンドル
wc.hInstance, // アプリケーション・インスタンス・ハンドル
NULL); // ウィンドウ作成データ
ShowWindow(hWnd,SW_SHOWDEFAULT); // ウィンドウ表示状態設定
}
void Display( )
/*----------------------------------*/
/* マンデルブロ集合 図形描画 */
/* */
/* 漸化式が発散するまでの計算回数 */
/* によって、対応する画素の階調を */
/* を求め、画面に描画する */
/* 画素は 0〜255 のグレースケール */
/*----------------------------------*/
{
HDC hdc; // デバイスコンテキスト ハンドル
double Cr,Ci,dCr,dCi;
double zr,zi,zrN,ziN;
int i,ix,iy,cl,nc;
char c[128];
dCr=(Cr2-Cr1)/XMAX; // 実部(横)刻み幅
dCi=(Ci2-Ci1)/YMAX; // 虚部(縦)刻み幅
nc=imax/256; if ( nc<=0 ) nc=1; // 階調比率(256階調)
hdc=GetDC(hWnd); // ウィンドウのDC取得
for( Ci=Ci1,iy=YMAX; Ci<=Ci2; Ci+=dCi,iy-- ) // 定数虚部(縦)
{
for( Cr=Cr1,ix=0; Cr<=Cr2; Cr+=dCr,ix++ ) // 定数実部(横)
{
zr=0.0; zi=0.0;
//--収束検査--
for( i=0; i<imax; i++ ) // 漸化式計算
{
zrN=zr*zr-zi*zi+Cr; // 実部漸化式計算
if ( zrN>E ) break; // 発散する
ziN=2.0*zr*zi+Ci; // 虚部漸化式計算
if ( ziN>E ) break; // 発散する
zr=zrN; zi=ziN;
}
cl=i/nc; // 階調計算
if ( cl>255 ) cl=255; // 階調補正
SetPixelV(hdc,ix,iy,RGB(cl,cl,cl)); // カラー値で点を描画
}
}
sprintf(c,"Cr:%8.5lf,%8.5lf Ci:%8.5lf,%8.5lf",Cr1,Cr2,Ci1,Ci2);
TextOut(hdc,0,0,c,strlen(c)); // 文字列描画
ReleaseDC(hWnd,hdc); // ウィンドウのDC 解放
}
LRESULT CALLBACK WndProc(
/*---------------------------*/
/* ウィンドウ プロシージャ */
/*---------------------------*/
HWND hwnd, // ウィンドウ・ハンドル
UINT uMsg, // メッセージID
WPARAM wParam, // 第1メッセージ・パラメータ(無符号)
LPARAM lParam) // 第2メッセージ・パラメータ(有符号)
{
PAINTSTRUCT hpaint; // 描画情報
BOOL ir=0;
switch ( uMsg )
{
case WM_CLOSE://--ウィンドウ閉--
PostQuitMessage(0); // 実行を終了
endFG=1;
break;
case WM_PAINT://--ウィンドウ更新--
case WM_SETFOCUS://--フォーカス取得--
if ( GetUpdateRect(hWnd,NULL,FALSE)==NULL )
break; // 更新リージョンなし
BeginPaint(hWnd,&hpaint);
Display( ); // 図形描画
EndPaint(hWnd,&hpaint);
break;
default://--その他--
ir=DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return(ir);
}
|