2009年7月28日火曜日

Haskellでレイトレーシング(第1回)〜導入

Haskellでレイトレーサを書き始めました。ベースにしているのは、「ANSI Common Lisp」という本に載っていたレイトレーサのサンプルです。Common Lispで書かれているものをHaskellで書いています。

Haskellで書いたコードはこれで、実行すると以下のようなpgm画像が得られます。

Common LispのコードをHaskellで書くにあたっては、次のようなところがポイントでした。

1.ループを使わない

Common Lispのコードでは、各ピクセルごとに手続き的にループを回すようになっていますが、Haskellではそれをループを使わずに記述します。どのように書くのかというと、全ピクセルをリストで表現し、それを関数に渡すのです。Haskellの遅延評価が活きてくるポイントです。

2.型による分岐にはパターンマッチを用いる

Common Lispのコードでは、物体の型を判別して処理を分岐しています。Haskellでは、引数のパターンマッチでこれをもっと自然に表現できます。

3.NilをMaybeモナドで表現する

レイが物体と衝突しない場合に、Commpn Lispのコードでは暗黙的にNilを返すように記述されています。それを、Maybeモナドを使いNothingで表現するようにしました。レイが物体に衝突するときにはその交点を返し、衝突しないときにはNothingを返します。

4.タプルを返せる

Common Lispのコードではmultiple-value-bindを使って値の組を返す部分があります。Haskellではそのままタプルを返すことができます。

5.衝突点の計算

Common Lispのコードでは、もっとも視点に近い衝突点を探すためにループが用いられています。Haskellでは、この衝突点の計算もループを使わずに表現します。foldrを使って、Haskellらしい形で表現しました。

次回以降の投稿で、これらのポイントを1つずつ説明していきます。

■他の記事
Haskellでレイトレーシング(第1回)〜導入
Haskellでレイトレーシング(第2回)〜ループは使わない
Haskellでレイトレーシング(第3回)〜型による分岐にはパターンマッチを用いる
Haskellでレイトレーシング(第4回)〜NilはMaybeモナドで表現する
Haskellでレイトレーシング(第5回)〜タプルを返せる

0 件のコメント: