物理エンジンでオブジェクトの「飛び出し」やジッターを修正するにはどうすればよいですか?


11

速度を変更したりインパルスを適用したりするのではなく、重なり合うボディ(現時点では円のみ)の位置を直接修正することで衝突を解決する単純な物理エンジンを持っています。速度は、影響がすでに解決された後、または統合部分の間にのみ変更されます。

オブジェクトのヒープで、上位のオブジェクトがヒープの下部にあるオブジェクトに過度の圧力をかけている(これは暗黙的に存在し、アルゴリズムには圧力モデリングがない)という問題がありました。等

オブジェクトをy座標で並べ替えることでこれを修正したかったので、衝突はボトムアップで解決されました。しかし今、エンジンは実際に静止しているはずのオブジェクトの奇妙な飛び出し動作を示しています(gifを参照)

ここに画像の説明を入力してください

ソースコードを提供するだけでなく、これは何でしょうか?


5
全体として、これは、方程式の線形システムを反復的に解くことと似ています(または、制約/条件などに応じて、非線形システム)。どちらの場合も、これらのアーティファクトは数値的に見て正しいものなので、これらのアーティファクトが表示されています。収束プロセスの中間状態です。これを回避することは非常に難しく、多くの厄介なハックを意味する可能性があります(とにかく、これは分子レベルで実際の生活で発生します。それが、実際の生活の中で最もよく似ているものです:))。おそらく、box2dを調査して、インパルスベースのダイナミクスのソリューションを確認することをお勧めします。
teodron 2013

@TravisGどのようにして問題を解決しましたか?非常に単純な物理エンジンを実装しようとするとき、私は同様の問題を見ています。
cheesusは13:12の

1
@cheeesus作業して久しぶりですが、タイムステップを小さくして反復回数を増やしたと思います。
TravisG

回答:


5

位置補正を使用するときに私が見つけた1つの解決策は、数回の反復を行い、反復ごとに強度を変えることです。

doPhysics();

int num_iterations = 5;
for(int iteration=0; iteration<num_iterations; ++iteration)
{
    float strength = float(iteration+1)/num_iterations;
    correctPositions(strength);
}

したがって、最初の反復の強度は1 / num_iterationsで、最後の反復の強度は1です。これにより、一定の強度で同じ回数の反復を使用するよりもシミュレーションがよりスムーズで安定します。


2
素晴らしい解決策ですが、なぜうまくいくのでしょうか?
Gustavo Maciel

5

あなたの問題は、あなたの体に「休息」状態がないという事実にあります。物理システムには、運動、熱などのエネルギー量があります。実際には、固体オブジェクトはわずかに変形し、運動エネルギーを熱に変換しますが、測定は困難です。また、実際には完全に固体のオブジェクトなどは存在しないことにも注意してください。ダイヤモンドのような密度の高い材料でも、原子間に空間があり、原子構造に屈曲の余地があり、運動エネルギーを吸収します。

これを関連づけるために、静止しているボディは、有効な力が「通常の力」、つまりボディが互いに浮き上がるのを防ぐ力だけである状態にあります。その法線力の大きさは、オブジェクトの密度、およびオブジェクトが相互に浸透した距離に比例します。

物理エンジンはこの値を「スロップ」と呼びます。

トリックは次のとおりです。傾斜を計算し、ボディの位置を修正し、2つのボディの相対速度に基づいて垂直力を適用します。ボディ自体の更新中に、各ボディの運動エネルギーを計算します。最小値を下回っている場合は、十分な大きさの力が加えられるまで、身体をスリープ状態にします。(通常、最小値の2倍)。


0

それらに「粘着性のある」表面を追加し、それらを徐々に静止位置に固定させて、別のオブジェクトがそれにぶつかると、エネルギーをそこに移動させて移動させますが、粘着性の表面は、このエネルギーの一部を失って停止します安静時。gifは摩擦がないように見えます。

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