6

私は現在、Farseer Physics ライブラリを使用して XNA でいくつかの物理玩具を試していますが、私の質問は XNA や Farseer に固有のものではなく、任意の 2D 物理ライブラリに固有のものです。

「ロケット」のような動きを追加したいと思います(ロケットである必要はないという意味でロケットのようなと言います-それは飛行機や水上のボート、または同様の状況の任意の数である可能性があります) 2D シーンの特定のオブジェクト。キネマティック シミュレーションを使用してこれを実装する方法は知っていますが、動的シミュレーションを使用して実装したいと考えています (つまり、時間の経過とともに力を適用します)。これを実装する方法については、ちょっと迷っています。

簡単にするために、ジオメトリを回転させるためのダイナミクスは必要ありません。体の速度に影響を与えるだけです。Farseer で回転しないように設定された円ジオメトリを使用しているため、オブジェクトの速度のみに関心があります。

最良の抽象化がどうあるべきかさえわかりません。概念的には、体が現在動いている方向 (単位ベクトル)、進みたい方向、速度を比較的一定に保ちながら方向を変える速さを表す値があります (小さな変動は許容されます)。

この抽象化を直接使用することも、オブジェクトが方向を変える速度 (時計回りまたは反時計回り) を制御する「ラダー」値のようなものを使用することもできます。

探している動きをシミュレートするには、どのような力を体に適用する必要がありますか? ロケットの「推力」をその場で調整できるようにしたいことも覚えておいてください。

編集:私が間違っている場合は修正してください。あなたには2つの力があります(今のところ主な推進力は無視しています):

1)常に体と同じ方向を向いている静的な「ひれ」があります。フィンが移動方向と一致しないようにボディが回転すると、移動方向とフィンの間の角度に比例して、フィンの長さに沿って空気抵抗が適用されます。

2) 指定された範囲内で自由に回転できる「ラダー」があり、ボディの重心 (この場合は円) から少し離れた位置に取り付けられています。繰り返しますが、この平面が移動方向と平行でない場合、空気抵抗により、舵の長さに沿って比例した力が生じます。

私の質問は、別の言い方をすれば、フィンとラダーに対する空気抵抗からこれらの比例力をどのように計算するのですか?

編集:参考までに、受け入れられた回答をテストするために私が書いたコードを次に示します。

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(string[] args)
    {
        float dc = 0.001f;
        float lc = 0.025f;
        float angle = MathHelper.ToRadians(45);
        Vector2 vel = new Vector2(1, 0);
        Vector2 pos = new Vector2(0, 0);
        for (int i = 0; i < 200; i++)
        {
            Vector2 drag = vel * angle * dc;
            Vector2 sideForce = angle * lc * vel;
            //sideForce = new Vector2(sideForce.Y, -sideForce.X); // rotate 90 degrees CW
            sideForce = new Vector2(-sideForce.Y, sideForce.X); // rotate 90 degrees CCW
            vel = vel + (-drag) + sideForce;
            pos = pos + vel;
            if(i % 10 == 0)
                System.Console.WriteLine("{0}\t{1}\t{2}", pos.X, pos.Y, vel.Length());
        }
    }

このプログラムの出力をグラフにすると、滑らかな円形の曲線が表示されます。これはまさに私が探していたものです!

4

3 に答える 3

2

私は突然それを「取得」します。

ロケット推進ミサイルが空を飛んでいる様子をシミュレートしたいのですが、OKです。これは、以下で詳しく説明する問題とは異なる問題であり、異なる制限を課します。航空宇宙オタクが必要です。または、単にパントすることもできます。


それを「正しく」行うには(スペースの場合):

シミュレートされたボディには、重心の周りに慣性モーメントが与えられている必要があります。また、ポインティング方向と角速度も必要です。次に、加えられたインパルスとCoMからの距離から角加速度を計算し、それを角速度に追加します。これにより、クラフトの現在の「ポインティング」を計算できます(ジャイロまたはペアの姿勢ジェットを使用しない場合は、(通常は非常に小さい)線形加速度も得られます)。

ターンを生成するには、クラフトを現在の移動方向から外し、メインドライブを適用します。

また、これを真剣に考えている場合は、総質量から燃焼燃料の質量を差し引き、各時間増分で慣性モーメントを適切に修正する必要があります。

ところで-これは価値があるよりも厄介かもしれません:自由落下でロケットを操縦するのは難しいです(ロシア人が数年前にISSでドッキング操縦をぶち壊したことを思い出すかもしれません;まあ、それは彼らが愚かだからではありません。 )。ユースケースを教えてくれない限り、それについてアドバイスすることはできません。

ここで何をしているのかを示唆する小さな擬似コード:

rocket {
  float structuralMass;
  float fuelMass;
  point position;
  point velocity;
  float heading;
  float omega;       // Angular velocity
  float structuralI; // moment of inertia from craft
  float fuelI;       // moemnt of inertia from the fuel load

  float Mass(){return struturalMass + fuelMass};
  float I(){return struturalI + fuelI};
  float Thrust(float t);
  float AdjustAttitude(float a);
}

結果は次のとおりです。「ゲーム物理」バージョンが必要な場合があります。


両方ともここに入るつもりはないので、「本物の」ロケットを実行する最も効率的な方法は、通常、緩やかな方向転換やゆっくりとした加速ではなく、方向を変えたいときに強く押すことですこの場合、現在のベクトルから目的のベクトル(単位ではなく完全なベクトル)を引くことにより、推力に対する角度を取得します。次に、その方向を指して、目的のコースに到達するまですべてを信頼します。

于 2010-07-12T19:41:47.300 に答える
2

力と質量を加速度と速度に統合するコードが既にある場合は、話している 2 つの要素のそれぞれの個々の部分を計算するだけで済みます。

簡単に言うと、フィンのことは少し忘れて、ロケットの本体が速度に対してある角度にあるときはいつでも、直線的に増加する横力と抗力が生成されるとだけ言っておきましょう。希望どおりの外観と感触になるまで、係数をいじってみてください。

Drag = angle*drag_coefficient*velocity + base_drag
SideForce = angle*lift_coefficent*velocity

ラダーの場合、生成される効果は一瞬ですが、ゲームが角度ダイナミクスに入る必要が絶対にない限り、より簡単な方法は、ラダー コントロールを使用して、時間ティックごとにロケット ボディの角度に一定量の変化を加えることです。ゲーム。

于 2010-07-12T20:52:38.667 に答える
0

あなたが何もない空間に浮かんでいると想像してみてください...そしてあなたは手に大きな石を持っています...あなたが石を投げると、石を投げたのとは正反対の方向に小さな衝撃があなたに加えられます. ロケットは、燃料の量子を、方向ベクトルに追加できる力 (ベクトル量) に急速に変換するものとしてモデル化できます。

于 2010-07-12T20:11:58.890 に答える