2009年7月11日土曜日

粒子法のプログラム最終回(粒子の出力)


最終回となる今回は、計算した粒子の出力について説明します。

このプログラムでは、計算した粒子をpov-rayのフォーマットで出力しています。

第1回に載せたムービーは、このプログラムでタイムステップごとに出力した.povファイルをレンダリングし、さらにffmpegで動画にしたものです。

粒子を出力するコードは以下のようになっています。

void output_particles( Particles* ps )
{
static int num = 0;
std::string file_name = \
(boost::format( "result%08d.pov" ) % num++ ).str();
std::cout << "processing " << file_name << " ..." << std::endl;
std::ofstream f( file_name.c_str() );
if ( ! f )
{
std::cerr << "cannot open " << file_name << std::endl;
exit(1);
}

f << "#include ¥"colors.inc¥"¥n"
<< "camera {¥n"
<< "  location <10,>¥n"
<< "  look_at <10,>¥n"
<< "}¥n"
<< "light_source { <0,> color White }¥n";
FOR_EACH_PARTICLES( ps, p )
{
f << "sphere {¥n"
<< "  <" << r(0) << ", " << r(1) << ", " << r(2) << ">, 0.5¥n"
<< "  texture {¥n"
<< "    pigment { color Yellow }¥n"
<< "  }¥n"
<< "}¥n";
}
f << std::endl;
}
タイムステップごとに.povファイルを出力しています。

さらに、この投稿に載せたムービーでは、計算した粒子から求めた陰曲面をマーチングキューブでポリゴン化し、反射や屈折も考慮してレンダリングしています。

これでひととおりの説明が終わりました。このあとの発展としては、3次元にしたり、物体との相互作用を入れたり、GPUで処理したりといったことを考えています。

粒子法のプログラム
粒子法のプログラム第1回(概要)
粒子法のプログラム第2回(プログラムの大枠)
粒子法のプログラム第3回(データ構造)
粒子法のプログラム第4回(密度と圧力の計算)
粒子法のプログラム第5回(力の計算)
粒子法のプログラム第6回(境界条件と粒子位置の更新)
粒子法のプログラム最終回(粒子の出力)

その他の解説エントリ
SPHによる巻き波のシミュレーション1
SPHによる巻き波のシミュレーション2
SPHによる巻き波のシミュレーション3
このあとやりたいこと

固液連成シミュレーションに関するエントリ
粒子法による固液連成シミュレーション

流体シミュレーションに関するエントリ
【粒子法】粒子を流体としてレンダリング
3次元の粒子法シミュレーション
粒子法のシーンを2倍のサイズにしてみたが…
粒子法のシーンを2倍のサイズにしてみた
Haskell、OCamlでSPH法
カメラ位置を変えて流体をレンダリング
Bunny-shaped fluid simulation

剛体シミュレーションに関するエントリ
粒子ベース剛体シミュレーション(プレビュー)
粒子ベース多体衝突シミュレーション
引き続き、粒子ベース剛体シミュレーション
Falling Rigid Bunnies

動画
シミュレーションの結果をレンダリングして作った動画です。流体シミュレーションや剛体シミュレーションの動画を見ることができます。

動画の一覧


--

5 件のコメント:

Unknown さんのコメント...

「・・・計算した粒子から求めた陰曲面をマーチングキューブでポリゴン化し、反射や屈折も考慮してレンダリングしています。 」

具体的にこれを達成させる方法って、教えてもらえませんか?
粒子のままでしか可視化できないのですが、このように「ギラギラ」に見せる方法を教えてくださるとうれしいです!!

Unknown さんのコメント...

すいません、追記です。

マーチングキューブ法などの方法はわかるのですが、それを行うにはやっぱりプログラムで書かないとだめなんですかね?POV-Rayなどのソフトでは直接やってくれないのですかね??

kamonama さんのコメント...

今回は、自前でマーチングキューブ法で陰関数曲面をポリゴン化して、それをPov-Rayで描画しています。

Pov-Rayのパラメータでいい感じに光を反射させて奇麗に見えるようにしています。水の本当の屈折率とそのままではないですが。。

その辺のパラメータは、ソースに書いてあるので、見ていただければ再現できるはずです。

陰関数曲面を描画する方法としてPov-Rayにはブロッブを使う方法があるので、それを使ってみるのはありかもしれないですよ。

KASSI さんのコメント...

こんばんは,はじめまして!
私は今まで分子動力学法という方法をつかってシミュレーションをしていたのですが,粒子法にも興味があるので,大変参考にさせていただいています.
可視化するときに,粒子を流体に見せると,それだけでわかりやすくてすごくおもしろそうだと思いましたので,私も真似をしてやってみようと思ったのですが,いまいち粒子の座標から陰関数曲面を作り出す方法がわからず,自分で考えても空間をメッシュに切って粒子の直径を定義してその距離から点の位置を判別して面をつくってるのかな?くらいしか思いつきませんでしたが,粒子からまず陰関数を求めて,そこからマーチンぐキューブ法をつかってポリゴン化しているということなのでちがうのでしょうね...なにかアドバイスや,調べるべき方法など教えていただければありがたいです!

kamonama さんのコメント...

> KASSIさん
粒子表現した流体の表面をレンダリングする方法としては、マーチングキューブは考え方が簡単なのでよく使われます。「マーチングキューブ」で検索するとやり方が見つかりますよ。

アルゴリズムのイメージとしては、KASSIさんの考えたもので近いのではないでしょうか。非常に単純な話で、空間を3次元格子に切って、すべての立方体空間について8つの頂点が密度のしきい値を超えているかどうかでその立方体空間の中に表面ポリゴンをつくり、そのポリゴンをレンダリングするだけです。立方体空間を走査するのでマーチングキューブと呼ばれています。

ブログにも解説エントリ書きたいですね。