Heim > Backend-Entwicklung > C++ > Hauptteil

Wie kann ich den Winkel im Uhrzeigersinn zwischen zwei Vektoren sowohl im 2D- als auch im 3D-Raum effizient berechnen?

Patricia Arquette
Freigeben: 2024-11-21 07:44:09
Original
791 Leute haben es durchsucht

How can I efficiently calculate the clockwise angle between two vectors in both 2D and 3D space?

Effiziente Berechnung von Winkeln im Uhrzeigersinn zwischen Vektoren

Traditionell erforderte die Berechnung des Winkels zwischen zwei Vektoren die Verwendung des Skalarprodukts, das den Innenwinkel innerhalb bestimmt der Bereich von 0 bis 180 Grad. Dieser Ansatz birgt jedoch Herausforderungen bei der Bestimmung des geeigneten Ergebnisses zwischen dem Winkel und seinem Komplement.

Gibt es eine direktere Methode zur Berechnung des Winkels im Uhrzeigersinn?

2D-Fall

Ähnlich wie das Skalarprodukt mit dem Kosinus des Winkels zusammenhängt, ist die Determinante proportional zu ihrem Sinus. Durch Einbeziehung dieser Beziehung können wir den Winkel wie folgt 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)
Nach dem Login kopieren
Nach dem Login kopieren

Die Ausrichtung des berechneten Winkels stimmt mit der des Koordinatensystems überein. In einem linkshändigen Koordinatensystem, in dem x nach rechts und y nach unten zeigt, ergeben Winkel im Uhrzeigersinn positive Werte. Umgekehrt spiegelt das Ergebnis in einem mathematischen Koordinatensystem, in dem y nach oben zeigt, Winkel entgegen dem Uhrzeigersinn wider, wie es in der Mathematik üblich ist. Durch Vertauschen der Reihenfolge der Eingabevektoren wird das Vorzeichen geändert, was die Flexibilität bietet, das Vorzeichen des Ergebnisses zu ändern.

3D-Fall

In drei Dimensionen definieren beliebige Vektoren ihre eigene Achse von Drehung senkrecht zu beiden. Da diese Achse keine feste Ausrichtung hat, ist es nicht möglich, die Richtung des Drehwinkels eindeutig zu bestimmen. Eine gängige Konvention besteht darin, positive Winkel zuzuweisen und die Achse entsprechend dieser Konvention auszurichten. In diesem Zusammenhang reicht das Skalarprodukt normalisierter Vektoren zur Winkelberechnung aus:

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))
Nach dem Login kopieren
Nach dem Login kopieren

Ebene eingebettet in 3D

Für Vektoren, die auf eine Ebene mit bekannter Normale beschränkt sind Vektor n, es gibt einen bestimmten Fall, der berücksichtigt werden muss. Die Drehachse fällt mit n zusammen und die Ausrichtung von n legt die Ausrichtung der Achse fest. In diesem Szenario können wir die obige 2D-Berechnung modifizieren, um n in die Determinante einzubeziehen und sie in eine 3x3-Matrix umzuwandeln:

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)
Nach dem Login kopieren

Damit diese Berechnung gültig ist, muss der Normalenvektor n auf Eins normiert werden Länge.

Alternativ kann die Determinante als Dreifachprodukt ausgedrückt werden:

det = n · (v1 × v2)
Nach dem Login kopieren

Dieser Ansatz ist in einigen APIs möglicherweise einfacher zu implementieren und bietet Einblick in die zugrunde liegende Mechanik: Das Kreuzprodukt ist proportional zum Sinus des Winkels und liegt senkrecht zur Ebene, also ein Vielfaches von n. Das Skalarprodukt misst daher im Wesentlichen die Länge dieses Vektors mit dem richtigen Vorzeichen.

Bereich 0 – 360°

Die meisten atan2-Implementierungen geben Winkel innerhalb des Bereichs zurück [-π, π] im Bogenmaß oder [-180°, 180°] in Grad. Um positive Winkel innerhalb von [0, 2π] oder [0°, 360°] zu erhalten, kann die folgende Transformation angewendet werden:

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)
Nach dem Login kopieren
Nach dem Login kopieren

Alternativ vermeidet der folgende Ausdruck die Fallunterscheidung:

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))
Nach dem Login kopieren
Nach dem Login kopieren

Diese Korrekturtechnik ist nicht auf dieses spezielle Problem beschränkt, sondern kann auf jedes Szenario mit atan2 angewendet werden.

Das obige ist der detaillierte Inhalt vonWie kann ich den Winkel im Uhrzeigersinn zwischen zwei Vektoren sowohl im 2D- als auch im 3D-Raum effizient berechnen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage