SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

.NETでマンデルブロ集合を描く

リアルタイム描画のシンプルなサンプル

計算と描画のからくり

 黄ばんだプリントアウトに触発されて腕試しを兼ねてマンデルブロ集合作図アプリケーションをこしらえました(図2)。添付したソリューションには.NET三大言語:C#, VB.NET そして C++/CLI によるプロジェクトを納めてあります。

図2 マンデルブロ集合作図アプリケーションの実行結果
図2

 それではマンデルブロ集合を計算機内に住むコビトさんに描いてもらうための道具を用意しましょう、方眼紙と色鉛筆のセットです。

 まず方眼紙。ディスプレイ上の平面はpixelと呼ばれる小さなマス目を縦横にみっちり並べた、まさに方眼紙です。座標の取り方がちょいとヘンテコで左上隅を起点(0,0)とし、右方向/下方向がそれぞれX軸/Y軸の増加方向となります。幅W,高さHの方眼紙の左上隅が(0,0)、右下隅が(W-1,H- 1)となりますね。この方眼紙上の点(X,Y)を、その点と対応する複素数 x+yiに変換しなくてはなりません。加えて点(X,Y)を塗り潰す機能、方眼紙全体を画面に描画する機能を与えることにします。

 そして色鉛筆のセット。今回は贅沢にも512色の色鉛筆を用意します。色鉛筆それぞれに0~511の番号を振り、与えられたn番目の色(ただしn < 0 のときは必ず"黒")を返します。

 コビトさんは方眼紙の各点についてひとつずつ前章の疑似コードで述べた計算を行い、その結果に応じた色を色鉛筆セットから手に入れて方眼紙に打点します。

 このアプリケーションの中では二人のコビトさんが仕事をします。一人は電卓片手に黙々と計算する計算コビト。もう一人は計算コビトの求めた結果に基づいて方眼紙を塗り潰す絵描きコビトです。絵描きコビトは一定期間ごとに発せられるタイマーのアラームを契機に方眼紙全体を画面に描画する役目も持っています。二人のコビトさんと方眼紙、色鉛筆セット相互の関係をユースケースっぽく描いてみました(図3)。

図3 計算コビト・絵描きコビト・方眼紙・色鉛筆セットの関係
図3

 二人のコビトさんはひとつの方眼紙にアクセスします。計算コビトは方眼紙の目盛を読むし、絵描きコビトは方眼紙を画面に表示しますからね。このとき二人のアクセスが衝突しないよう排他制御を行いましょう。

オブジェクトの同期/排他制御

 MandelbrotPlotter と MainForm は SectionPaper 内の Bitmap に非同期にアクセスします。このとき一方がアクセスしている最中に他方がアクセスすることがないよう排他制御を行わなければなりません。C# では lock、VB.NET では SyncLock 構文で排他制御が可能となります:

// C#
lock ( target ) {
  targetに対するアクセス
}
' VB.NET
SyncLock target
  targetに対するアクセス
End SyncLock

 C++/CLI は lock, SyncLock に相当する構文を持ち合わせていません。lockを用いたC#コードをコンパイルし、ildasmでILレベルで逆アセンブルしてみると、 System.Threading.MonitorのEnter/Exitメソッドで実現していることが判明したので、同機能の小さなクラス MonitorLock を作りました:

class MonitorLock {
private:
    gcroot<System::Object^> target_;
public:
    MonitorLock(System::Object^ t) : target_(t)
      { System::Threading::Monitor::Enter(target_); }
    ~MonitorLock()
      { System::Threading::Monitor::Exit(target_); }
};

 MonitorLockはコンストラクト時にEnter/デストラクト時にExitしてくれるので、これを使えば以下のようなコードで排他制御ができます。

// C++/CLI
{
  MonitoLock lock(target);
  targetに対するアクセス
}

次のページ
実装

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4650 2009/12/10 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー