体があまりにも速くバタバタとぶつかると、領域の制約により物理シミュレーションが爆破されます
-
05-07-2019 - |
質問
物理シミュレーションがあり、領域の制約を設定できるため、内部のボディはその領域から出ません。ただし、原子が「壁」の1つを通過すると、エリア制約の物理シミュレーションを爆破します。なぜこれを行うのですか? 更新方法:
if (!atom.IsStatic)
{
Vector2 force = Vector2.Zero;
bool x = false, y = false;
if (atom.Position.X - atom.Radius < _min.X)
{
force = new Vector2(-(_min.X - atom.Position.X), 0);
if (atom.Velocity.X < 0)
x = true;
}
if (atom.Position.X + atom.Radius > _max.X)
{
force = new Vector2(atom.Position.X - _max.X, 0);
if (atom.Velocity.X > 0)
x = true;
}
if (atom.Position.Y - atom.Radius < _min.Y)
{
force = new Vector2(0, -(_min.Y - atom.Position.Y));
if (atom.Velocity.Y < 0)
y = true;
}
if (atom.Position.Y + atom.Radius > _max.Y)
{
force = new Vector2(0, atom.Position.Y - _max.Y);
if (atom.Velocity.Y > 0)
y = true;
}
atom.ReverseVelocityDirection(x, y);
if (!atom.IsStatic)
{
atom.Position += force;
}
}
解決 3
30分ほどの無謀なハッキングの後、私は単に位置補正を適用しないと思いましたか。それは魅力のようにそれを修正しました。興味のある方は、ここに更新されたコードがあります:
if (!atom.IsStatic)
{
if (atom.Position.X - atom.Radius < _min.X && atom.Velocity.X < 0)
{
atom.ReverseVelocityDirection(true, false);
}
if (atom.Position.X + atom.Radius > _max.X && atom.Velocity.X > 0)
{
atom.ReverseVelocityDirection(true, false);
}
if (atom.Position.Y - atom.Radius < _min.Y && atom.Velocity.Y < 0)
{
atom.ReverseVelocityDirection(false, true);
}
if (atom.Position.Y + atom.Radius > _max.Y && atom.Velocity.Y > 0)
{
atom.ReverseVelocityDirection(false, true);
}
}
他のヒント
一定の時間ステップTで計算しているようです。すべてのステップで衝突をモデリングする場合、原子が障害物に到達するまでの最小時間に等しい時間ステップを使用する必要があります。
タイムステップ変数を作成します。原子は決して「トンネル」しません。障害物。
PS衝突検出には多くの最適化があります。それらの情報についてはgamedevの論文を読んでください。
PSバグ?
force = new Vector2(-(_min.X - atom.Position.X), 0);
Forceは、XおよびY反射用に個別に作成されます。アトムがコーナーに入るとどうなりますか? 2番目の力のみが適用されます。
P.P.S:イプシロンを使用
もう1つの重要な注意:浮動小数点を使用する場合、エラーは累積されるため、epsを使用する必要があります。
abs(atom.Position.Y + atom.Radium - _max.Y) < eps
ここで、epsはタスクの通常のサイズよりもはるかに小さい数です。 0.000001。
あなたはすでに問題を解決しているようですが、「力」が気づきました。間違っているようです。原子が間違った側にある場合でも、境界から原子を離れさせます。アトムが_max.Xを過ぎて発射したと仮定します:
if (atom.Position.X + atom.Radius > _max.X) { force = new Vector2(atom.Position.X - _max.X, 0); ... }
今&quot; force&quot; + x方向になり、壁からの原子の距離は反復ごとに2倍になります。ブーム!
所属していません StackOverflow