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)」などのロジックを節約できます。