ドット積を使用して2つのベクトル間の角度を取得するにはどうすればよいですか?


16

ゲームで正規化されたベクトルを使用することを学んでいます。

2つのベクトル間の角度を知るために、ドット積を使用できることを学びました。これにより、-1〜1の値が得られます。

  • 1は、ベクトルが平行で同じ方向を向いていることを意味します(角度は180度です)。
  • -1は、それらが平行で反対方向を向いていることを意味します(180度のまま)。
  • 0 それらの間の角度が90度であることを意味します。

2つのベクトルのドット積を実際の角度(度単位)に変換する方法を知りたい。たとえば、2つのベクトルの内積がの0.28場合、対応する角度は0〜360度ですか?


1
内積の使用目的は、初期ベクトルが単位ベクトルの場合にのみ機能することに注意してください。
サムホセヴァー14年

@SamHocevarはい、それは私が意図したことです。
user3150201 14年


1
@ user3150201 Alexの答えは正しいですが、実際の角度を度単位で取得する必要があるかどうかも考慮する必要があります。これが本当に必要な場所を思い浮かべることができる唯一のケースは、UIに何かを表示することです。それ以外の場合は、正弦波と余弦波を直接操作できないアプリケーションはおそらくほとんどありません。
TravisG

回答:


22

dot(A,B) = |A| * |B| * cos(angle)
これはに再配置できます
angle = arccos(dot(A,B) / (|A|* |B|))

この式を使用すると、2つのベクトル間の最小角度(0〜180度)を見つけることができます。0〜360度の範囲で必要な場合、この質問が役立ちます。


ところで、同じ方向を指す2つの平行なベクトル間の角度は、180度ではなく0度でなければなりません。


「ところで、同じ方向を指す2つの平行なベクトル間の角度は、180ではなく0度でなければなりません。」
タラ

8

TravisGのコメントを少し拡張して、あなたの質問に「2D」タグが付いているという事実を利用して、別の回答をします。

内積を使用して2つのベクトル間の角度を取得できますが、それを使用して2つのベクトル間の符号付き角度を取得することはできません。別の言い方をすれば、キャラクターを時間の経過とともにポイントに向けて回したい場合、ドット積はどのくらいの方向にではなく、どれだけ回すかを取得します。ただし、別の簡単な式があります。これは、ドット積と組み合わせると非常に便利です。あなただけではありません

dot(A,B) = |A| * |B| * cos(angle)

また、別の式を使用することもできます(その名前は、政治的に正しいことを確認しました)。

pseudoCross(A,B) = |A| * |B| * sin(angle)

ここで、A =(a、b)、B =(x、y)の場合、pseudoCross(A、B)は外積の3番目の成分(a、b、0)x(x、y、0 )。言い換えると:

a*x+b*y = |A| * |B| * cos(angle)

-b*x+a*y = |A| * |B| * sin(angle)

その場合、完全な符号付き角度はangle=atanfull(-b*x+a*y,a*x+b*y)(正規化されていない値を渡した場合、atanfullまたはatan2関数が許します)。AとBが正規化されている場合|A|=|B|=1、つまり、の場合、これらは単純です:

a*x+b*y = cos(angle)

-b*x+a*y = sin(angle)


より深い説明のために、上記の方程式は行列方程式で表現できることに注意してください。

[ a,b]   [x]   [cos(angle)]
[-b,a] * [y] = [sin(angle)]

しかし、bはのように表すことができるa=cos(ang1)b=sin(ang1)いくつかの値に対して、ang1(ありませんangle)。したがって、左側の行列は、ベクトル(x、y)を-ang1だけ回転させる回転行列です。これは、単位ベクトル "A"がベクトル/軸(1,0)として扱われる参照フレームに切り替えることに相当します!したがって、このフレームに単位円/直角三角形を描画するだけで、その製品の結果ベクトルが(cos(angle)、sin(angle))である理由を確認できます。

(a、b)および(x、y)を極形式で記述し、角度差の式cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)およびを適用するとsin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)、(lm)= angleであるため、サイン/コサインがこの製品によって与えられることを再表現します。あるいは、これらのIDを使用して、上記の線形積がベクトルを回転させる理由を確認できます。

これらのすべてのアイデンティティは、角度がほとんど必要ないことを意味します。ラジアン/度、逆サイン/コサインの規則、2 * piごとに繰り返すという事実は、角度が奇妙になる可能性があるため、これは実際にはより便利で、「if(ang <180)」などのロジックを節約できます。

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