船の構成は動的に変化するため、船を時計回りまたは反時計回りに回転させたいときに、どのスラスタをオンにするかを決定する必要があります。スラスタは常に船と軸が揃っており(角度を付けない)、オンまたはオフです。可能なセットアップの1つを次に示します。
これまでに試したことは、発砲ベクトルと船の重心への方向ベクトルを視覚化することです。
残念ながら、私はそれでそれほど遠くに行きませんでした。
船の構成は動的に変化するため、船を時計回りまたは反時計回りに回転させたいときに、どのスラスタをオンにするかを決定する必要があります。スラスタは常に船と軸が揃っており(角度を付けない)、オンまたはオフです。可能なセットアップの1つを次に示します。
これまでに試したことは、発砲ベクトルと船の重心への方向ベクトルを視覚化することです。
残念ながら、私はそれでそれほど遠くに行きませんでした。
回答:
成功!ここにあり、必要に応じて回転しています:
私がやったことは次のとおりです。各スラスタについて、重心に関連してトルクの大きさを計算します。
private function thrustTorque():Float
{
// distToCom is the distance vector between the thruster and center of mass
// fire angle is a unit vector representing the direction of the thruster
var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
var fireAngle = Math.atan2(dir.y, dir.x);
var theta = fireAngle - distAngle;
var torque = distToCOM.length * Math.sin(theta);
return torque;
}
ウィキペディアによると、トルクの大きさの式はT = rF sin(theta)
であり、ここで:
プレイヤーが左を押すと、そのスラスタのトルクの兆候を確認します。ゼロよりも小さい場合は、スラスタを発射します。時計回りに回すのは逆です。
これはおそらく、ドット積を使用してベクトル間の角度のコサインを計算することで改善できますが、明日まで待たなければなりません。
最後に、ライブデモがあります。
トルクのための一般的な3D表現は、変位と力の外積である:T = R ⨯ F。2次元では、トルクのスカラー値で十分であり、スラスタの直交方向が4つしかない場合、区分形式で記述できます。
ここで、Fはスラスタによって生成される力の大きさ、rxとryはピボットポイントからスラスタまでのベクトルのxおよびy成分です。正のトルクは、船を反時計回りに回転させる傾向があります。上記の4つの式を使用すると、各スラスタが生成するトルクの符号を推測するのは簡単です。
物理学を適度に正確に表現するには、推力の符号だけでなく、その合計の大きさと回転慣性も知る必要があります。さらに、回転を行うために適切に配置されたすべてのスラスタを単にアクティブにしたくない場合があります。
描かれているように、スラスタB、D、およびEへのフルパワーは回転を最大化しますが、船を右に加速します。Dをシャットダウンすると、これを防ぎます。代わりに、右への加速が意図されているが、時計回りの回転が意図されていない場合、最も効率的な方法は、CとFの両方をDとともにフルパワーの3分の2で有効にすることです。
これがあなたがやろうとしていることの範囲を超えていなければ、明らかに単純なタスクではなく、運動方程式用のある種のソルバーを書く必要があります。
いくつかの異なるもの。まず、これが制約の少ない問題であることを認識する必要があります。すなわち、同じ方向に回転するために発火できるスラスタの多くの異なる組み合わせがあります。あなたの状況では、スラスタには「オン」と「オフ」の2つの状態しかなく、すべてのスラスタが等しい力を出力すると仮定しています。
第二に、モデルを目で見てみると、「重心」は実際には重心ではないように見えます。幸いなことに、これはトルクの計算には影響しません。ただし、重心変位の計算には影響します。あなたの「重心」は、少なくとも真の重心に最も近い正方形であるため、そのレベルの精度を気にするかどうかはわかりません。
第三に、特定のスラスタが回転にどのように影響するかを計算する場合、非効率的な式を使用しているにもかかわらず、それは正しいことです。トルクは、のように計算することができるr x F
大きさを有しています、r*F*sin(theta)
。ただし、この場合の角度の計算は非効率的な方法です。代わりに、トルクのクロス積定義を直接使用する必要があります。これは、使用している表現を使用するとはるかに簡単になるためです。すべてのベクトルにはzコンポーネントがないため、外積の式は大幅に簡素化されます。
計算結果をまったく変更せずに、コードを更新するだけです
private function thrustTorque():Float
{
var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
return torque;
}
それははるかに優れています(そしてより高速です)。
あなた自身の答えで、あなたの解決策はすべてのスラスタを正しい方向のトルクで発射することだと提案しています。さて、それはあなたが尋ねた質問をほぼ解決します。ただし、ユーザーが「回転」ボタンを押したまま、正のトルクを持つすべてのスラスタが回転し、潜在的にそれらを上に移動すると、線に沿ったある点で、戦略がそれほど満足できないことがわかります。スラスタからの力を実際に計算する場合や、発射を視覚的に表示してから一定の加速度などでモデルを回転させる場合、シミュレーションの詳細レベルがわかりません。方法として、スラスタを少なくともほぼ正確に発火させる必要があります)。
船にかかる正味の力は考慮しません。任意のスラスター量がある場合、これはかなり複雑な問題になる可能性があります。ただし、スラスタの状態は2つしかないため、分析は非常に簡単です。ここでの目標が正確に定かではないので、2つの異なる目標を想像できます。まず、必要な方向のトルクを維持しながら、総力を最小限に抑えたい。第二に、総力に対するトルクの比率を最大化します。
余談ですが、すべてのスラスタの出力に同時に影響する追加の「スラスタボリューム」コントロールを想像できる場合は、2つのソリューションのトルクが等しくなるようにこのコントロールを設定できます。最初よりも小さい変位。ただし、回転するだけでまったく動かないようにスラスタを発射できる場合は、両方のソリューションが同じであることを覚えておく必要があります。
したがって、前の段落の引数に基づいて、2番目のソリューションを使用します。さて、総力を分析するとき、エンジンが指すことができる方向は4つしかないことに簡単に注意できます。したがって、x方向の合計力は、左を指しているスラスタの数から右を指している数を差し引いただけで、y方向についても同様です。
ここまで書いた後、私はそれを最適化するアルゴリズムについてもう少し考えなければなりません。投稿の残りの部分はそのまま役立つと思うので、投稿していますが、この構成を最適化する最適な方法を見つけたときに更新します(おおよその答えを得るためのいくつかの方法を考えましたが、それらのどれも正確ではありません)。