2D-Fall
So wie das Punktprodukt proportional zum Kosinus des Winkels ist, ist die Determinante proportional zu seinem Sinus. Sie können den Winkel also folgendermaßen berechnen:
dot = x1*x2 + y1*y2 # dot product between [x1, y1] and [x2, y2]
det = x1*y2 - y1*x2 # determinant
angle = atan2(det, dot) # atan2(y, x) or atan2(sin, cos)
Die Ausrichtung dieses Winkels entspricht der des Koordinatensystems. In einem linkshändigen Koordinatensystem , dh x zeigt nach rechts und y nach unten, wie es für Computergrafiken üblich ist, bedeutet dies, dass Sie ein positives Vorzeichen für Winkel im Uhrzeigersinn erhalten. Wenn die Ausrichtung des Koordinatensystems mit y nach oben mathematisch ist, erhalten Sie Winkel gegen den Uhrzeigersinn, wie es in der Mathematik üblich ist. Durch Ändern der Reihenfolge der Eingaben wird das Vorzeichen geändert. Wenn Sie mit den Vorzeichen nicht zufrieden sind, tauschen Sie einfach die Eingaben aus.
3D-Fall
In 3D definieren zwei beliebig platzierte Vektoren ihre eigene Rotationsachse senkrecht zu beiden. Diese Drehachse hat keine feste Ausrichtung, was bedeutet, dass Sie die Richtung des Drehwinkels auch nicht eindeutig festlegen können. Eine übliche Konvention besteht darin, Winkel immer positiv sein zu lassen und die Achse so auszurichten, dass sie zu einem positiven Winkel passt. In diesem Fall reicht das Punktprodukt der normalisierten Vektoren aus, um Winkel zu berechnen.
dot = x1*x2 + y1*y2 + z1*z2 #between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1*x1 + y1*y1 + z1*z1
lenSq2 = x2*x2 + y2*y2 + z2*z2
angle = acos(dot/sqrt(lenSq1 * lenSq2))
Ebene in 3D eingebettet
Ein Sonderfall ist der Fall, in dem Ihre Vektoren nicht willkürlich platziert werden, sondern in einer Ebene mit einem bekannten Normalenvektor n liegen . Dann liegt die Rotationsachse ebenfalls in Richtung n , und die Ausrichtung von n legt eine Ausrichtung für diese Achse fest. In diesem Fall können Sie die obige 2D-Berechnung, einschließlich n, in die Determinante anpassen , um ihre Größe 3 × 3 zu erhalten.
dot = x1*x2 + y1*y2 + z1*z2
det = x1*y2*zn + x2*yn*z1 + xn*y1*z2 - z1*y2*xn - z2*yn*x1 - zn*y1*x2
angle = atan2(det, dot)
Eine Bedingung dafür ist, dass der normale Vektor n eine Längeneinheit hat. Wenn nicht, müssen Sie es normalisieren.
Als dreifaches Produkt
Diese Determinante könnte auch als dreifaches Produkt ausgedrückt werden , wie @Excrubulent in einer vorgeschlagenen Bearbeitung hervorhob .
det = n · (v1 × v2)
Dies ist möglicherweise in einigen APIs einfacher zu implementieren und bietet eine andere Perspektive auf das, was hier vor sich geht: Das Kreuzprodukt ist proportional zum Sinus des Winkels und liegt senkrecht zur Ebene, also ein Vielfaches von n . Das Punktprodukt misst daher grundsätzlich die Länge dieses Vektors, jedoch mit dem richtigen Vorzeichen.
std::atan2()
?