1989年開業 情報工学部門 文部科学省登録番号 第22082号 公益社団法人日本技術士会会員 東大阪商工会議所会員

≫サンプルプログラム一覧 

オープンソース/C言語サンプルプログラム  マンデルブロ集合を描画する

●マンデルブロ集合を256階調のグレースケールで描画するプログラムです。
●コマンドプロンプトではなく、ウィンドウを生成して描画します。
●描画した画面は、Alt + PrintScreenキーでクリップボードにコピーできます。
●マンデルブロ集合やwindowsプログラミングの詳細は、関係文献・資料等をご参照
 ください。
 ≫ソースファイルのダウンロード: mandelbrot01.c
【問題】
●画像を白黒反転させてみよう。
●描画範囲を変更してみよう。(拡大・移動)
●画像を大きく拡大したとき、画像の解像度にどのような影響が出るか。
●最大計算回数を増やすと、画像にどのような変化が出るか。
※2012.12.23 細部を若干変更しました。

≫カオス・フラクタルCG作品集 ../chaos-fractal/index.html

/*************************/
/*  マンデルブロー集合   */
/*             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);
}
   

※SSL暗号化通信対応

佐伯英子技術士事務所 〒542-0073 大阪市中央区日本橋 1-14-13 サンオフィス日本橋601  E-mail: info@saeki-pe.com