見出し画像

【LiquidFunでサイエンス】固液混相を簡単にシミュレートしてみよう~コード解説編2 液体(粒子)を定義する~

液体が、波打ったり、しぶきを上げる様子をシミュレートできるフリーのJSライブラリ、「LiquiFun(リキッドファン)」についての記事です。
 「LiquiFun」は本来はゲーム用途であり、2次元、基本粒子の性質(密度や半径)は1種類だけ、という制約はあり、また、現時点ではCDNという形態で配信されていないために、GAS(google Apps Script)に組み込んで使う事も困難です。
それでも「LiquiFun」は粒子法というシミュレート手法を使っている、数少ないフリーウェアであり、かつ、JavaScriptというアマチュアでも比較的平易に扱えるプログラムで操作できる利点もあり、これを日常の用途に役立てられないか?という事を探っていく記事です。
「LiquiFun」の導入については、こちらをご覧下さい。スタンドアロンでの作動方法のご紹介ですが、いつかGASに組み込めればいいなと思っています。



今回の記事は、以下のシミュレーションのコード解説になります。

前半の固体の生成は以下の記事で、その続きです。


液体(粒子)の作成

個別粒子の定義

LiquidFunでは、液体を粒子の集団で模して(離散化して)その挙動を計算します。ただし、この粒子は固体ではなく、圧力や粘性といった液体固有の物理法則に従う特別な粒子です。

まず、個別粒子(1つずつの粒子)を表すオブジェクト(ここでは psd という変数)を定義します。

「個別粒子」という言葉はこの記事でだけ使っている言葉で、筆者自身がしっくり来ると感じている言葉です。

 var psd = new b2ParticleSystemDef();

このオブジェクトのプロパティに、粒子半径、粒子密度といった、計算の前提になる諸元を定義します。

粒子半径というのは、粒子同士が影響しあうとみなす最大距離です。いわば、それより離れると互いに無関係だとして計算を省くための条件設定のことで、それにより計算量が増えすぎない様にしています。以下の図をイメージして頂ければと思います。

現実の液体は無限に細かい粒・・・そう考えると粒子を小さくするほど、現実の液体に近づきそうなものですが、計算量が増えて時間がかかりすぎたり、発散(計算を重ねる事での誤差の蓄積)が思わぬ形で起こったりするので、その加減が難しいところです。

また、粒子の密度は液体の重さとおおざっぱに考えてください。

その他、表面張力などの属性も設定できます。

それらのコードは以下の通りです。

  psd.radius = 0.017; 粒子系の半径
  psd.dampingStrength = 0.2; 粒子系の表面張力
  psd.density = 1; 粒子の密度

密度などは複数の個別粒子を設定したいろころですが、LiquidFunでは現在、1つしか設定出来ない様です。

var ground = world.CreateBody(bodyDef);


粒子団の定義

次に、個別粒子が集まった粒子団を設定します。(名前は pd としています)

var pd = new b2ParticleGroupDef();

この粒子団は複数設定でき、このそれぞれに初期形状や色が設定できます。今回は使いませんが個々の粒子団を弾性体、剛体に設定することもできます。

 pd.shape = shape; 粒子団の初期形状
 pd.color.Set(0, 0, 255, 255); 粒子団の色(R・G・B・濃さ)

「粒子団」という言葉はこの記事でだけ使っている言葉で、筆者自身がしっくり来ると感じている言葉です。

今回のシミュレーションでは、液体の初期状態は長方形ですが、形状は前もって以下のコードで設定しています。

  var shape = new b2PolygonShape;
  shape.SetAsBoxXYCenterAngle(0.8, 1, new b2Vec2(-1.2, 1.01), 0);

なお、粒子団は、この段階では、中身のない外皮だけの存在だとイメージしてください。

液体の生成

最後に液体を生成します。

以下の1行目で個別粒子( psd )が実体化され、2行目でその子関数 CreateParticleGroup の引数に粒子団(pd)を代入することで、粒子団に応じた液体が生成されます。

  var particleSystem = world.CreateParticleSystem(psd);
  var group = particleSystem.CreateParticleGroup(pd);

生成した液体は、ただちに動き始めます。

粒子半径の結果に対する影響

ここで、個別粒子で設定した粒子半径が、結果にどう影響するかお見せします。

以下が現状(psd.radius = 0.017;)です。

粒子半径を大きくして、 psd.radius = 0.05; としたのが以下です。

粒子半径を小さくして、 psd.radius = 0.01; としたのが以下です。

いかがでしょうか。

粒子半径が大きすぎ
⇒ 固体の隙間に液体が入り込まず、浮くはずの固体が沈んだままになる。

粒子半径が小さすぎ
⇒ 液体中に不自然な隙間が生じる。

その他、粒子半径が小さくなると、挙動がゆっくりになり、初期の形が小さくなる、という事も分かります。

実用に使う場合は、このあたりを考慮して、適当な粒子半径を決定した上で、再現したい内容は絞る必要がありそうです。


この記事が気に入ったらサポートをしてみませんか?