プロデルでマンデルブロ集合を描画する

プロデルでマンデルブロ集合を描画するプログラムを作ってみました。

サンプルプログラム

ポイント

マンデルブロ集合では、複素数を扱います。そこで複素数を表現する「複素数」種類を定義します。

集合を図にした画像は、ピクチャー部品に表示します。「画像」種類に点を設定した後にその画像をピクチャー部品に表示する方法と、「図形描画」種類によってピクチャー部品に点を直接描画する方法を書きました。

処理のパフォーマンスとしては、前者の「画像」種類が早いですが、計算の過程を見られる点では後者の直接描画する方法も良いと思います。

プログラム

C実数=-0.2
C虚数=0.5
最大カウント=4096
表示幅=400
メイン画面を表示する

描画する
待機する

描画する手順
cという複素数を作る
サイズは、400
ステップは、サイズ/4
写真という画像(サイズ,サイズ)を作る
0からサイズ-1まで横に繰り返す
	cの実数=横/ステップ-2.0
	0からサイズ-1まで縦に繰り返す
		cの虚数=縦/ステップ-2.0
		【z:複素数】
		zという複素数を作る
		カウント=0
		繰り返す
			z=zの二乗にcを足したもの
			値=zの絶対値の二乗
			カウントを増やす
			カウントが最大カウントより大きければ
				カウント=-1
				繰り返しから抜け出す
			そして
			値が4以上なら
				繰り返しから抜け出す
			そして
		そして
		カウントが0以上なら
			写真にて{横,縦}へ[カウントと64で、色変換する]を設定する
			//図形描画によってメイン画面のピクチャー1の{横,縦}へ[カウントと64で、色変換する]色で点を描く
		そして
	そして
そして
メイン画面のピクチャー1の画像は、写真

終わり

【カウント:整数】と、【基数:整数】で、色変換する手順
	カウントが0未満なら黒を返す
	【d:整数】=カウント%基数
	d=d*(256/基数)
	【m:整数】=d/42.667
	mについて分岐
	0の場合
		r=0。g=6*d。b=255
	1の場合
		r=0。g=255。b=255-6*(d-43)
	2の場合
		r=6*(d-86)。g=255。b=0
	3の場合
		r=255。g=255-6*(d-129)。b=0
	4の場合
		r=255。g=0。b=6*(d-171)
	5の場合
		r=255-6*(d-214)。g=0。b=255
	他の場合
		r=0。g=0。b=0
	そして
	rが0未満ならr=0
	rが256以上ならr=255
	gが0未満ならg=0
	gが256以上ならg=255
	bが0未満ならb=0
	bが256以上ならb=255
	【C:色情報】は{r,g,b}
	Cを返す
終わり

複素数とは
	+実数=0.0
	+虚数=0.0
	はじめの手順
	終わり
	はじめ(実数,虚数)の手順
		この実数は、実数
		この虚数は、虚数
	終わり
	自分に【相手:複素数】を足す手順
		複素数(実数+相手の実数,虚数+相手の虚数)を作って返す
	終わり
	自分に【相手:複素数】を掛ける手順
		複素数(実数*相手の実数-虚数*相手の虚数,実数*相手の虚数+虚数*相手の実数)を作って返す
	終わり
	共役を求める手順
		複素数(実数,-虚数)を作って返す
	終わり
	二乗を求める手順:複素数
		複素数(実数*実数-虚数*虚数,2*実数*虚数)を作って返す
	終わり
	三乗を求める手順
		複素数(実数*(実数*実数-3*虚数*虚数),虚数*(3*実数*実数-虚数*虚数))を作って返す
	終わり
	絶対値の二乗を求める手順:整数
		実数*実数+虚数*虚数を返す
	終わり

終わり


メイン画面とは
	ウィンドウを受け継ぐ
	+ピクチャー1
	
	はじめの手順
	初期化する
	ーー貼り付けた部品に対する操作をここに書きます
終わり
	初期化する手順
		ーー自動生成された手順です。ここに書き加えたプログラムは消える可能性があります
		初期化開始する
		この実質大きさは{678,644}
		この内容は「マンデルブロ集合」
		この文字色は「標準の文字」
		ピクチャー1というピクチャーを作る
		ピクチャー1を初期化開始する
			その位置と大きさは{0,0,678,644}
			その文字色は「標準の文字」
			そのドッキング方向は「全体」
		ピクチャー1を初期化終了する
		初期化終了する
		この設計スケール比率は{144,144}
	終わり
終わり

処理スピードの改善

ランタイム環境とコンパイラ

プロデルは、ランタイム環境とコンパイラを選べる形態を採用しています。プロデルデザイナで実行すると、ランタイム環境として実行されます。計算時間がかかる処理は、コンパイラでコンパイルした実行可能ファイルで実行するのが最短です。

変数宣言でのデータ型の明示

フルコンパイルした場合でも、型宣言を必須としないプロデルの言語的な特徴により、十分に早く実行されないケースがあります。

処理スピードが求められるプログラムでは、変数宣言で、変数のデータ型を明示して宣言してください。特に、手順の仮引数では、型推論できず変数の型が未定のままコンパイルされますので、仮引数にデータ型を明示して宣言することでスピード改善が期待できます。(サンプルプログラムでは「色変換する手順」などが該当します)

また、手順の戻り値のデータ型を明示することで、呼び出し元で代入する変数の型推論が働き、同様にスピード改善が期待できます。

「画像」種類でメモリ上に描画する

点を打つたびにそれをピクチャー部品へ描画すると、全体を描画するまでに時間がかかります。ピクチャー部品に直接描画せずに、メモリ上の「画像」種類に画像を描いてから、最後にピクチャー部品に表示すると、描画のための時間が省かれて、全体の処理時間が短くなります。

まとめ

今回のプログラムを通じて、プロデルのパフォーマンス改善を実施しました。サンプルプログラムを試す時には、最新のプロデルをインストールしてお試しください。プロデルは熱狂的なユーザが少ないこともあり、今回のパフォーマンス改善のような明らかになっていない改善の余地がたくさん残されています。

ぜひプロデルで色々なプログラムを作ってフィードバックをお願いいたします。

  • いいね (3)
  • 続編を読みたい (0)

“プロデルでマンデルブロ集合を描画する” への1件の返信

  1. こんにちは。アークです。

    早速やってみました。
    10年以上も前の私のマシン(iCoreの第四世代)でも1分7秒で完了しました。

    尚、正確な時間計測を行う為に冒頭部分を下記のように変更しています。

    C実数=-0.2
    C虚数=0.5
    最大カウント=4096
    表示幅=400
    メイン画面を表示する

    開始時刻は、今の時刻
    描画する
    情報音を鳴らす
    終了時刻は、今の時刻
    エンドという日時期間形式(「[終了時刻]」)を作る
    スタートという日時期間形式(「[開始時刻]」)を作る
    経過時間は、エンドからスタートを引く
    「[終了時刻]ー[開始時刻]:[経過時間]」を「[プログラムの位置]経過時間.txt」へ保存する
    待機する
    メイン画面を閉じる

コメントを残す