粒子で圧力をシミュレートする方法は?


11

私が構築しているUnityゲームで球形の粒子のコレクションを使用して圧力をシミュレートしようとしています。問題に関するいくつかのメモ:

  • 目標は、常に変化する2Dスペース/ボイドを小さな摩擦のない球で埋めることです。ゲームは、このスペースに押し込まれるオブジェクトの増加する圧力をシミュレートしようとしています。
  • レベル自体は常に左から右にスクロールします。つまり、スペースの寸法がユーザーによって変更されない場合、自動的に小さくなります(スペースの左端の部分が画面外にスクロールし続ける)。

これらの問題に取り組むために私が取ることができるアプローチは何ですか?

  1. 塗りつぶすスペースがある場合にそれを検出し、そのスペースに球を追加するタイミングを知る。
  2. 縮小するときにスペースから球を削除します。
  3. より多くのスペースが作成されたときに球が「外側に爆発する」ように球への圧力をシミュレートする戦略。

この画像が示すように、私が考えている現在のアプローチは、画面の外にあり、画面と一緒に動く、絶えず動く壁を使用しています。

圧力!

この動く壁は、球を空間に押し込み、閉じ込めます。新しい球を追加する場合、私は(1)空きスペースを検出すると球を複製する、または(2)スペースの左側(壁がある場所)にスポーンする-残りの球をスペースを埋めます。これは実際には圧力を作成/シミュレートしない可能性が高いため、アイデア#1の問題を予測します。アイデア#2はより有望に思われますが、これらの新しい球のパーティクルがスポーンする場所を提供する方法(およびスペースがない場合にスポーンすることの影響)の問題を提起します。

あなたの知恵を前もってどうもありがとう!

回答:


6

あなたが何を達成したいのか正確にはわかりませんが、スペースが画面から転がり落ちるときに壁がパーティクルを押しているのはゲームメカニックですか?

あなたの3つの点については、粒子をそのように扱う場合、これらの動作はすべて現れると思います。各粒子に距離に反比例する他のすべての粒子を反発させ、それらを空間の壁に衝突させて停止させます。

粒子が互いに接近すると、互いに反発し合うため、障害物によって停止されるまで、空のスペースを埋めるために広がります。壁が移動してスペースが小さくなり、粒子が押し出されると、それらは他の粒子の近くに押し込まれ、より強く反発し、次に他の粒子を押して、全体の圧力を増加させます。

これは、負の引力を持つn体シミュレーションと非常に似ているため、パーティクルの数によっては、他のすべてのパーティクルを含むすべてのパーティクルの反発力を計算するのにかなりのコストがかかる可能性があります。パーティクルの質量の平均重心だけで各パーティクルを反発させることで、これを単純化しようとすることができますが、曲がりのある長く薄い領域で奇妙な動作が発生する可能性があります(ガスが、重心など)。

パーティクルの作成と削除(私が想定しているスペースを視覚的に埋めるために適切な量があることを確認するため)に関しては、密度が不足しているときに単にパーティクルを追加または削除しないでください。他の粒子を反発する粒子が増えると、圧力が増減します。

したがって、斥力計算に係数を導入したい場合があります。たとえば、1.0から始めて、x粒子を追加するときに、新しい係数n /(n + x)を作成します。nは、新しい粒子を追加する前の総粒子数です。


2

圧力(ガス中など)は、粒子間および粒子と壁の間の単純な弾性衝突の結果です。壁との時間あたりの衝突の量を測定するだけで、圧力の値を取得できます。

閉じたボリューム内の一定量の粒子と一定の温度で圧力が与えられるため、指定した2つのアイデアは圧力に直接関係しません(その結果、粒子の動きが速くなったり遅くなったりします)。

この閉じたシステムに粒子を追加すると、システム全体のエネルギーが増えるため、圧力が上昇するはずです(特定の温度<->速度で新しい粒子を追加しただけです)。


壁は+無限大に近い質量を持っていると想定されるため、粒子は弾性衝突のための質量を持つ必要があります
Aron_dc

私は「圧力は壁との時間当たりの衝突の量である」と言いました。それは100%正確です。弾性衝突では、その粒子のインパルスを取得し、壁に与えられたインパルスの量を測定します。したがって、1つの粒子が壁に対して垂直方向に衝突すると、壁は2mvのインパルスを取得します(m =粒子の質量、v =粒子の速度)。したがって、実際に壁に入るインパルスを測定します。パーティクルは反射されます(衝突前のv =衝突後の-v)。これは、異なるガスの混合物の圧力(粒子の場合は異なるm)の測定にも役立ちます。
Aron_dc 2012

0

各ループでは、すべてのパーティクルを反復処理してから、そのパーティクルに対する最終的な力を計算する必要があります。基本的に、壁が衝突している場合(粒子.x-粒子.r <= 0)、壁は常にx軸上に正の力ベクトルを与えます。

次に、それらが衝突している各パーティクルは、それらの間の角度に応じて、力ベクトルも与えます。すべての粒子についてこれらの角度を収集し、平均を計算して、そこに行きます!

ここでも使用できる最適化手法はたくさんあります。ボール物理のチュートリアルを調べてください。基本的に、パーティクルの各ペア1回だけ反復し、両方のフォースベクトルを計算してそれらに格納します。

これは基本的に気体をシミュレートするものであり、一定の力を与えると、液体も液体になると思います。

パーティクルの作成と削除については、ParticleEmitterクラスを実装します。このクラスには、位置、方向、その他の便利な機能があります。あなたの例は、特定の範囲の粒子を作成できるエミッタ、または長方形のほうがよいでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.