Wie verwende ich das Skalarprodukt, um einen Winkel zwischen zwei Vektoren zu erhalten?

16

Ich lerne, normalisierte Vektoren in meinen Spielen zu verwenden.

Ich habe gelernt, dass ich das Skalarprodukt verwenden kann, um den Winkel zwischen zwei Vektoren zu bestimmen. Dies gibt mir einen Wert zwischen -1 und 1, wobei

  • 1 bedeutet, dass die Vektoren parallel sind und in dieselbe Richtung weisen (der Winkel beträgt 180 Grad).
  • -1 bedeutet, dass sie parallel sind und in entgegengesetzte Richtungen weisen (immer noch 180 Grad).
  • 0 bedeutet, der Winkel zwischen ihnen beträgt 90 Grad.

Ich möchte wissen, wie man das Punktprodukt zweier Vektoren in einen tatsächlichen Winkel in Grad umrechnet. Wenn zum Beispiel das Punktprodukt zweier Vektoren ist 0.28, wie groß ist der entsprechende Winkel zwischen 0 und 360 Grad?

user3150201
quelle
1
Beachten Sie, dass Ihre beabsichtigte Verwendung des Skalarprodukts nur funktioniert, wenn die Anfangsvektoren Einheitsvektoren sind.
Sam Hocevar
@SamHocevar Ja, das habe ich gemeint.
user3150201
1
@ user3150201 Alex 'Antwort ist richtig, aber Sie sollten auch überlegen, ob Sie den tatsächlichen Winkel überhaupt in Grad berechnen müssen. Der einzige Fall, in dem ich darüber nachdenken kann, wo dies wirklich notwendig ist, ist, etwas in Grad auf der Benutzeroberfläche anzuzeigen. Andernfalls gibt es wahrscheinlich nur wenige Anwendungen, in denen Sie nicht direkt mit Sinus und Cosinus arbeiten können.
TravisG

Antworten:

22

dot(A,B) = |A| * |B| * cos(angle)
die neu angeordnet werden kann
angle = arccos(dot(A,B) / (|A|* |B|)).

Mit dieser Formel können Sie den kleinsten Winkel zwischen den beiden Vektoren ermitteln, der zwischen 0 und 180 Grad liegt. Wenn Sie es zwischen 0 und 360 Grad brauchen, kann diese Frage Ihnen helfen.


Übrigens sollte der Winkel zwischen zwei parallelen Vektoren, die in dieselbe Richtung zeigen, 0 Grad und nicht 180 Grad betragen.

Alex
quelle
+1 für "Übrigens sollte der Winkel zwischen zwei parallelen Vektoren, die in dieselbe Richtung zeigen, 0 Grad und nicht 180 betragen."
Tara
8

Ich werde den Kommentar von TravisG etwas erweitern und eine andere Antwort geben, wobei ich die Tatsache ausnutze, dass Ihre Frage das "2D" -Tag hatte.

Sie können den Winkel zwischen zwei Vektoren mithilfe des Punktprodukts ermitteln, aber Sie können den vorzeichenbehafteten Winkel zwischen zwei Vektoren mithilfe des Punktprodukts nicht ermitteln . Anders ausgedrückt, wenn Sie einen Charakter mit der Zeit in Richtung eines Punktes drehen möchten, erhalten Sie mit dem Skalarprodukt, wie viel gedreht werden muss, nicht jedoch in welche Richtung. Es gibt jedoch eine andere einfache Formel, die in Kombination mit dem Skalarprodukt sehr nützlich ist. Das hast du nicht nur

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

Sie können auch eine andere Formel haben (deren Namen ich für politische Korrektheit entschädigt habe):

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

wobei, wenn A = (a, b), B = (x, y) ist, Pseudokreuz (A, B) als die dritte Komponente des Kreuzprodukts (a, b, 0) x (x, y, 0) definiert ist ). Mit anderen Worten:

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

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

Der volle vorzeichenbehaftete Winkel ist dann angle=atanfull(-b*x+a*y,a*x+b*y)(atanfull oder atan2 verzeihen Ihnen, wenn Sie nicht normalisierte Werte übergeben). Wenn A und B normalisiert sind, |A|=|B|=1sind dies einfach:

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

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


Beachten Sie zur genaueren Erläuterung, dass die obigen Gleichungen durch die Matrixgleichung ausgedrückt werden können:

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

Aber a und b können für einen bestimmten Wert als a=cos(ang1), ausgedrückt b=sin(ang1)werden ang1(nicht angle). Daher ist die linke Matrix eine Rotationsmatrix, die den Vektor (x, y) um den Betrag -ang1 dreht. Dies entspricht dem Umschalten in einen Referenzrahmen, in dem der Einheitsvektor "A" als Vektor / Achse (1,0) behandelt wird! Wenn Sie also nur den Einheitskreis / das rechtwinklige Dreieck in diesem Rahmen zeichnen, können Sie sehen, warum der resultierende Vektor dieses Produkts (cos (Winkel), sin (Winkel)) ist.

Wenn Sie (a, b) und (x, y) in Polarform schreiben und anwenden , um die Winkeldifferenz Formeln cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)und sin(l)*cos(m)-cos(l)*sin(m)=sin(l-m), Sie erneut Ausdruck bringen , dass die Sinus- / Cosinus dieses Produkt gegeben werden, da (lm) = Winkel. Alternativ könnten diese Identitäten verwendet werden, um zu sehen, warum das oben angegebene lineare Produkt einen Vektor dreht.

All diese Identitäten bedeuten, dass Sie selten Winkel benötigen. Da Winkel komisch sein können - Bogenmaß / Grad, Konventionen für inversen Sinus / Cosinus, die Tatsache, dass sie sich alle 2 * pi wiederholen - kann dies tatsächlich nützlicher sein und Ihnen eine Reihe von "if (ang <180)" usw. -Logik ersparen.


quelle