×

[PR]この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。

ヒルベルト曲線

ヒルベルト曲線とは、ドイツの数学者ダフィット・ヒルベルトが考案したフラクタル図形の一つで、再帰的に定義できる空間充填曲線です。
ヒルベルト曲線は、コの字の形状を基本図形とし、以下の4つの基本描画ルールの再帰的組合せで描くことができます。
※ n が 0 の時には、何も描画しません。
描画ルールのアルファベットはそれぞれ、
L:Left , D:Down , R:Right , U:Up
の意味です。

Ldr(4) とすれば、4次のヒルベルト曲線を描画します。どんな図形なのかは、以下のボタンをクリックしてみてください。

UrdやRulなどから始めても良いのですが、ここでは、Ldr を元となる図形としました。
良く分からないって方は、以下のテキストボックスに、1から順に2,3,4と数値を入れて実行し、上の定義と見比べてみてください。(でも、8以上の値を入れるとなかなか終わらないのでご注意を)



■コードの簡易解説
Hirbertクラスが、ヒルベルト曲線を定義しています。やっていることは、上で示したヒルベルト曲線の定義をそのままC#のコードに落としたものです。
ただ、ここで線は引いていません。実際に描画するために、Hirbertクラスは、線を引く代わりに、その都度イベントを発行しています。

UIを受け持つMainPage クラスは、このイベントを受け取り(イベント引数には、線の始点と終点の情報が渡ってきます)、線を描いて行きます。

Silverlightで線を描くには、WritableBitmapを使う方法もありますが、このプログラムでは、Panelオブジェクト(具象クラスはCanvas)にLineオブジェクトを追加することで線を描いています。

なお、描画する際は、アルゴリズムの理解を助けるために、あえてウエイトを入れて描画を遅くしています。



MainPageクラスでは、BackgroundWorkerを使いHirbertクラスを呼び出しています。HirbertオブジェクトがDrawイベントが発生させてから、実際に描画するまでは、以下のような流れになっています。

1. HirbertオブジェクトがDrawイベントを発行
2. イベントハンドラhilbert_DrawLineが呼ばれる.
    ここは、UIスレッドとは別スレッドになるため、直接描画することはできない。
3. イベントハンドラhilbert_DrawLine内でBackgroundWorkerのReportProgressメソッドを呼び出す。
    第1引数は使わない。 第2引数にHilbertEventArgsオブジェクトを渡す。
4. BackgroundWorkerオブジェクトが、ProgressChangedイベントを発行する。
5. bw_ProgressChangedイベントハンドラが呼ばれる。
6. bw_ProgressChangedイベントハンドラ内で、HilbertEventArgsオブジェクトの内容を参照し、
    線を描画する。

なお、ここまで書いて思ったのですが、_DrawLineメソッドは、Right,Left, Up, Downの4つのメソッドに分割したほうが良かったかもしれません。

以下に、C#+Silverlightのコードを示します。


■Hirbert.cs

■MainPage.xaml.cs
 
■MainPage.xaml