回答:
2Dクロス積を使用する方がはるかに高速です。高価なトリガー機能は含まれていません。
b2Vec2 target( ... );
b2Vec2 heading( ... );
float cross = b2Cross( target, heading );
if( cross == -0.0f )
// turn around
if( cross == 0.0f )
// already traveling the right direction
if( cross < 0.0f)
// turn left
if( cross > 0.0f)
// turn right
それでも実際の角度が必要な場合は、を使用することをお勧めしatan2
ます。 atan2
任意のベクトルの絶対角度を提供します。任意のベクトルとベクトル間の相対角度を取得するには、絶対角度を計算し、単純な減算を使用します。
b2Vec2 A(...);
b2Vec2 B(...);
float angle_A = std::atan2(A.y,A.x);
float angle_B = B.GetAngle(); // Box2D already figured this out for you.
float angle_from_A_to_B = angle_B-angle_A;
float angle_from_B_to_A = angle_A-angle_B;
arccos
。この方法では、トリガー関数を1つだけ使用しますが、実際の角度はそのままです。ただし、AI角度の追跡がゲームのパフォーマンスに顕著な影響を与えていることが確実になるまで、この最適化に反対することをお勧めします。
if( cross == -0.0f )
vs if( cross == 0.0f )
チェックは非常に脆弱です。
2Dクロス積のアークサイン(クロス積ベクトルのzコンポーネント)を使用します。-90から90になり、左に進むか右に進むかがわかります。
AクロスBはBクロスAとは異なるため、注意してください。
別の戦略(ただし、それほど単純ではないかもしれません)は、atan2を使用して2つのベクトルの「ヘディング」を計算し、X度を指すAがY度を指すBに進むために左または右に進む必要があるかどうかを計算します。
ベクトルを使用して船をリダイレクトします。これが「ステアリング動作」の仕組みです。角度を計算する必要はなく、ベクトルを使用するだけです。これは計算上はるかに安価です。
ベクトルw
(船舶1から船舶2へのベクトル)は、必要なすべての情報です。の加重バージョンを使用して、船1の速度ベクトルまたは船1の加速度ベクトル(または直接船首ベクトル)を変更しw
ます。
船1がコースからどれだけ離れているか(vがwとどれだけ一致しないか)の大きさは、(1 - dot(v,w)
)を使用して見つけることができます。
dot(v,w)
整列するv
と最大化w
されます)1 - dot(v,w)
)はときに0を与えるv
とw
完全に並んで設けられているv
とw
)正規化されています通常のジオメトリを介してベクトルの絶対角度を見つける簡単な方法があります。
例えば、ベクトルV = 2i-3j;
x係数の絶対値= 2;
y係数の絶対値= 3;
角度= atan(2/3); [角度は0から90の間です]
象限角に基づいて変更されます。
if(x係数<0およびy係数> 0)の場合、角度= 180角度。
(x係数<0およびy係数<0)の場合、角度= 180+角度。
(x係数> 0およびy係数<0)の場合、角度= 360角度;
if(x係数> 0およびy係数> 0)then angle = angle;
最初と2番目のベクトルの角度を見つけたら、2番目のベクトルから最初のベクトル角度を減算します。次に、2つのベクトル間の絶対角度を取得します。
Mathf.DeltaAngle()
。