Quaternion und Singularität

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
joggel

Quaternion und Singularität

Beitrag von joggel »

Hallo,

ich habe mal wieder ein mathematisches Problem.

Ich verwende ja Quaternionen für die Rotation. Nun geben ich über das GUI folgende Werte ein:
Rotation um X: 0°
Rotation um Y: 91°(!!! Problem bei >90° und <-90°)
Rotation um Z: 0°

Wenn ich mit diesen Werten ein Quaternion erstelle, und dieses Quaternion anschließend wieder in Euler-Winkel-Konvention überführe, dann erhalte ich folgende Werte:
Rotation um X: 180°
Rotation um Y: 89
Rotation um Z: 180°

Hier mal der Code:

Code: Alles auswählen

glm::vec3 rotVec{ glm::radians(0), glm::radians(91), glm::radians(0) };
glm::quat orientation( rotVec);
//und jetzt gleich wieder zurück
glm::vec3 euler = glm::eulerAngles(orientation);
glm::vec3 eulerInDegree(glm::degrees(euler.x), glm::degrees(euler.y), glm::degrees(euler.z));
//eulerInDegree.x = 180
//eulerInDegree.y = 89
//eulerInDegree.z = 180

Ich habe mal etwas gegoogelt und herausbekommen, dass sich dieser Effekt, oder Zustand, Singularität nennt.
Unter Anderem bin ich auch auf diese Seite herausgekommen, auf der beschrieben wird wie man diesen Effekt umgehen kann (etwas runterscrollen zu dem Abschnitt "Singularities").
Nur leider funktioniert das bei mir nicht, oder besser gesagt, ich mache dabei bestimmt etwas falsch.

Meine Frage nun:
Ist dieses Problem jemanden bekannt?
Bzw. weiß jemand wie ich das lösen kann?
Ich hätte also gerne genau die Werte nach dem glm::eulerAngles(orientation), die ich in der ersten Zeile angegeben habe.

Edit:
Hatte mich im Code bei der Angabe der Rotation um Y verschrieben. Es sollte nicht 90° sondern 91° heißen^^
Mirror
Establishment
Beiträge: 248
Registriert: 25.08.2019, 05:00
Alter Benutzername: gdsWizard
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Mirror »

Bei Quaternions entspricht der 3er Vektor nicht den eulerschen winkeln. Der Vektor stellt die Rotationsachse dar und die Länge dieses Vektors ist der Winkel um diese Achse.
Hat den StormWizard 1.0 und 2.0 verbrochen. http://www.mirrorcad.com
joggel

Re: Quaternion und Singularität

Beitrag von joggel »

Bei dem glm::quat-Typ kann man Eulerwinkel dem Konstruktor übergeben.
Es wird dann konvertiert.

type_quat.hpp Zeile 105.

Edit:
Oder? Ich schaue mal. Bisher funktioniert das aber ziemlich gut
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Jonathan »

Rotationen sind schwierig. Aber die richtige Sichtweise hilft:

Zunächst solltest du unterscheiden zwischen Orientierung/Ausrichtung und Rotation/Drehung. Wenn du ein Objekt drehst, änderst du seine Ausrichtung, das eine ist ein Zustand, das andere eine Operation. Ja, natürlich kann eine Ausrichtung durch eine Drehung von der ursprünglichen Ausrichtung beschrieben werden, aber prinzipiell sind das zunächst einmal komplett unterschiedliche Dinge.

Es ist immer möglich, Drehungen durch 'Euler-Winkel', zu beschreiben, d.h. z.B. "5-Grad um die globale X-Achse drehen". Das ist immer sinnvoll und wohldefiniert. Die resultierende Ausrichtung durch Euler-Winkel zu beschreiben geht aber prinzipiell nicht. In manchen Fälle ist es sinnvoll, in manchen Fällen nicht, insgesamt ist das kein tragbarer Kompromiss, also muss man schlussfolgern, dass es prinzipiell nicht geht. Lösung die nur manchmal taugen, taugen nie.

Ausrichtungen kann man jetzt durch viele Arten beschreiben. Quaternionen sind nett, aber ehrlich gesagt, ich benutze die nie. Denn in der 3D Grafik haben wir schon ein absolut fantastisches Mittel jegliche Art von Transformationen zu beschreiben, nämliche Matrizen. Fantastisch deshalb, weil man einfach die 3 Vektoren so wunderbar als Koordinatensystem im Raum darstellen kann und sofort total klar ist, was die Transformation macht. Quaternionen grafisch zu verstehen, nun, ich habs noch nicht geschafft.

Mathematisch gesehen, reden wir ja eigentlich von der "Speziellen orthogonalen Gruppe". Das ist deshalb wichtig, weil man dann schnell einsieht, dass es zwar unterschiedliche Parametrisierung gibt, die aber alle das selbe machen. Ob du jetzt Euler-Winkel, Quaternionen oder Rotationsmatrizen verwendest, du kannst mit allen dein Objekt auf die selbe Art rotieren. Nur manchmal (bei euler-winkeln) ist es den Schmerz einfach nicht wert^^.
Quaternionen sind jetzt auf zwei Arten nett: Jede gültige Quaternion (normalisiert und so) beschreibt eine Rotation (Matrizen können auch andere Transformationen abbilden) und sie besteht nur aus 4 Zahlen, anstatt der 16 für übliche Matrizen. Ist also ein klein wenig schneller, wenn man wirklich nur rotieren will. In der Praxis habe ich aber immer ganze Transformationsketten, also wird früher oder später eh alles eine Matrix.


Was jetzt die Lösung deines Problems angeht: Speicher die Ausrichtung deines Objektes als Matrix und verabschiede dich von dem Gedanken, die Ausrichtung in der GUI als Zahlen anzeigen zu können. Euler-Winkel funktionieren nicht so, wie man das vielleicht gerne hätte und es ist mathematisch nicht möglich, sie dazu zu bringen, das sie es tun. Rotationen sind auf eine gewisse Art inhärent kompliziert. Jedesmal wenn ein Objekt gedreht wird, drehst du halt die aktuelle Ausrichtung entsprechend, aber du solltest nicht versuchen, von der Ausrichtung wieder auf irgendwelche Drehwinkel umzurechnen.

Die vielleicht eingängigste Beschreibung ist noch die "Achse + Winkel" Darstellung, in der du einen beliebigen Vektor hast, um den das Objekt gedreht wurde (Es ist ein überraschendes Ergebnis, dass egal wie oft man ein Objekt um beliebige Achsen dreht, man am Ende durch eine einzige Drehung um eine einzige Achse immer wieder den Ausgangszustand erreichen kann). Aber selbst das finde ich nicht hilfreich. Kein Mensch kann sich so ein Zahlenpaar wirklich gut vorstellen.

Rotationen kann man IMO nur grafisch anzeigen. Man kann dem User Knöpfe geben um um die globalen oder lokalen Hauptachsen zu drehen. Darüber hinaus fällt mir nichts nützliches ein.
Du musst sie intern auch nicht als Matrix speichern. Du kannst auch Quaternionen nehmen. Du kannst auch Eulerwinkel in Matrizen umrechnen und anwenden. Es geht ja immer nur um Rotationen, die Formeln von jeder Darstellung in jede andere zu kommen findest du überall. Für mich ist nur wichtig: Drehungen kann man leicht intuitiv beschreiben (5 Grad um X-Achse), Ausrichtungen sind aber das Ergebnis von Drehungen, sind nicht trivial und lassen sich nur grafisch vernünftig darstellen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Mirror
Establishment
Beiträge: 248
Registriert: 25.08.2019, 05:00
Alter Benutzername: gdsWizard
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Mirror »

Naja, wenn du nur um eine orthogonale Achse drehst, dann entspricht der Vektor eben dem eulerschen Winkel. Mit Quaternions lässt sich aber viel Eleganteres machen, als mit eulerschen Winkeln. Man kann eine Rotation auf unterschiedlichen Weg erreichen, d.h. es gibt mehrere Kombinationen um eine Drehung zu erreichen (Gruppen).
Hat den StormWizard 1.0 und 2.0 verbrochen. http://www.mirrorcad.com
joggel

Re: Quaternion und Singularität

Beitrag von joggel »

Jonathan hat geschrieben: 26.09.2021, 14:04 Was jetzt die Lösung deines Problems angeht: Speicher die Ausrichtung deines Objektes als Matrix und verabschiede dich von dem Gedanken, die Ausrichtung in der GUI als Zahlen anzeigen zu können.
Uff... das wäre nicht schön! Aber vermutlich muss ich mich damit abfinden :/
Danke erstmal für die Erklärung. Ich werde mir da irgend etwas überlegen müssen...
Mirror hat geschrieben: 26.09.2021, 14:07 Naja, wenn du nur um eine orthogonale Achse drehst, dann entspricht der Vektor eben dem eulerschen Winkel.
Ja, die Achsen sind ja orthogonal und halt "global"... dann scheint das zu tun.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Jonathan »

joggel hat geschrieben: 26.09.2021, 14:16 Ja, die Achsen sind ja orthogonal und halt "global"... dann scheint das zu tun.
Nein, das Problem bei Eulerwinkeln ist ja gerade, dass sie die Achsen ändern (Nachdem man um die X-Achse gedreht hat, ist die Y-Achse nicht mehr die ursprüngliche Y-Achse). Wenn du dem Benutzer Euler-Winkel anzeigst, erwartet er, dass man 3 unabhängige Drehungen hat. Aber da die Reihenfolge wichtig ist (weil andere Reihenfolgen unterschiedliche Ergebnisse liefern), bedeutet das, dass der Wert den man in dem ersten Feld einträgt beeinflusst, wie der Wert im zweiten Feld interpretiert wird. Das genau ist der Grund, warum Euler-Winkel zunächst simpel aussehen, aber am Ende nie so funktionieren, wie man es gerne hätte. Und dem Benutzer eine Information zu geben, die er mit Sicherheit nicht richtig verstehen wird, halte ich für ziemlich nutzlos. Das funktioniert einzig, solange man nur triviale Fälle hat, z.B. wenn 2 der 3 Winkel 0 sind.

Wie gesagt: Intern ist es super angenehm und einfach, Rotationen einfach als Black-Box zu speichern. Ich habe irgendwie ein Objekt, dass meine Ausrichtung beschreibt, ich weiß, wie ich diese Ausrichtungen durch diverse Operationen manipulieren kann (wenn der Benutzer das Objekt in der GUI dreht) und ich weiß, wie ich ein Objekt mit dieser Ausrichtung rendern kann. Wie die interne Darstellung ist, kann dann egal sein, im Gegenteil, es hat eigentlich keinen Mehrwert (weder für den Programmierer noch den Benutzer), die konkrete Kodierung zu verstehen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
joggel

Re: Quaternion und Singularität

Beitrag von joggel »

Okay :-/
Bzw: Nicht okay^^
Aber danke für die Erklärung
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Jonathan »

joggel hat geschrieben: 26.09.2021, 16:49 Okay :-/
Bzw: Nicht okay^^
I feel you^^

Ich habe neulich an meinem Engine-Modelviewer weiter gebaut. Wollte, dass man die Lichtrichtung bequem per Maus anpassen kann (d.h. Knopf drücken und Maus in eine bestimmte Richtung ziehen). Jetzt könnte man einfach die X und Y Bewegung der Maus auf globale Achsen legen, aber man möchte das Licht eigentlich wirklich relativ zur Kamera bewegen und nicht absolute Winkel anpassen, das ist nämlich einfach furchtbar unintuitiv.
Also stellt man sich vor, dass die Maus eine virtuelle Kugel greift, die vor einem liegt, und die Bewegung dreht die Kugel entsprechend, und genau so wird auch die Lichtrichtung gedreht. Das ist super und intuitiv, solange das Licht ungefähr aus der Kamera-Richtung kommt. Maus nach links, Licht kommt von links. Wenn die Kamera jetzt aber gegen das Licht guckt, ist die Steuerung umgedreht. Noch schlimmer ist die Hoch-Runter-Bewegung, denn wenn das Licht genau von der Seite kommt, dreht es sich plötzlich um sich selber, und bewegt sich überhaupt nicht mehr.

Jetzt könnte man natürlich abfragen, ob man gegen das Licht schaut und dann die Steuerung entsprechend invertieren. Das geht nur leider kaputt, wenn man an die Übergänge kommt, wenn man die Maus weiter nach rechts bewegt, soll sich auch das Licht bitteschön weiter drehen und nicht einfach stoppen oder gar zurück kommen. Vielleicht könnte man sich irgendetwas cleveres überlegen, um das ganze doch noch gut hinzubekommen, mir ist aber bisher noch nichts eingefallen (aktuell drehe ich manchmal einfach die Kamera in die Lichtrichtung um dann das Licht besser ausrichten zu können). Aber diese unbefriedigende Lösung drückt eigentlich aus, was ich sagen möchte: Rotationen sind nicht so einfach, wie man denkt. Und ganz sicher sind sie um ein Vielfaches komplizierter, als Translationen / Verschiebungen. Und daran wird man nichts ändern können, sondern damit leben müssen.


Wenn man noch weiter über Rotationen nachdenken will, hier ist ein interessanter Blog-Eintrag:
Let's remove Quaternions from every 3D Engine
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
joggel

Re: Quaternion und Singularität

Beitrag von joggel »

Jonathan hat geschrieben: 26.09.2021, 18:58 Wenn man noch weiter über Rotationen nachdenken will, hier ist ein interessanter Blog-Eintrag:
Let's remove Quaternions from every 3D Engine
Dieser Artikel ist auch so ne Art Evergreen hier auf ZFX :D
Zähle schon zum dritten mal, das der hier verlinkt wurde^^
Werd' ihn mir mal ausgiebig zu Gemüte führen...wenn ich Zeit dafür habe.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Jonathan »

joggel hat geschrieben: 26.09.2021, 20:42
Jonathan hat geschrieben: 26.09.2021, 18:58 Wenn man noch weiter über Rotationen nachdenken will, hier ist ein interessanter Blog-Eintrag:
Let's remove Quaternions from every 3D Engine
Dieser Artikel ist auch so ne Art Evergreen hier auf ZFX :D
Zähle schon zum dritten mal, das der hier verlinkt wurde^^
Werd' ihn mir mal ausgiebig zu Gemüte führen...wenn ich Zeit dafür habe.
Oh, haha, vermutlich hab ich den dann auch von hier. Tatsächlich hab ich auch nur mal angefangen ihn zu lesen, aber nie ganz durchgearbeitet, da ich mich mittlerweile wie gesagt mit dieser Blackbox-Sichtweise ganz gut abgefunden habe. Und wen interessiert schon, wie die Formeln jetzt konkret funktionieren (die implementiert man eh in der Regel nicht selber), solange man mit den eher abstrakten Objekten intuitiv arbeiten kann? :D
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
mtorc1
Beiträge: 80
Registriert: 20.02.2021, 16:24

Re: Quaternion und Singularität

Beitrag von mtorc1 »

joggel hat geschrieben: 26.09.2021, 20:42
Jonathan hat geschrieben: 26.09.2021, 18:58 Wenn man noch weiter über Rotationen nachdenken will, hier ist ein interessanter Blog-Eintrag:
Let's remove Quaternions from every 3D Engine
Dieser Artikel ist auch so ne Art Evergreen hier auf ZFX :D
Zähle schon zum dritten mal, das der hier verlinkt wurde^^
Werd' ihn mir mal ausgiebig zu Gemüte führen...wenn ich Zeit dafür habe.
Ich habe ihn tatsächlich noch nicht gelesen und werde ihn mir definitiv zu Gemüte führen. Danke!
Letztes Projekt: Grave of the Pumpkin (ZFX Halloween Action 2021)
mtorc1
Beiträge: 80
Registriert: 20.02.2021, 16:24

Re: Quaternion und Singularität

Beitrag von mtorc1 »

Jonathan hat geschrieben: 26.09.2021, 14:04 Ausrichtungen kann man jetzt durch viele Arten beschreiben. Quaternionen sind nett, aber ehrlich gesagt, ich benutze die nie. Denn in der 3D Grafik haben wir schon ein absolut fantastisches Mittel jegliche Art von Transformationen zu beschreiben, nämliche Matrizen. Fantastisch deshalb, weil man einfach die 3 Vektoren so wunderbar als Koordinatensystem im Raum darstellen kann und sofort total klar ist, was die Transformation macht. Quaternionen grafisch zu verstehen, nun, ich habs noch nicht geschafft.
Mal aus Neugier... speicherst du bei deinen Objekten dann ausschließlich Matrizen zur Beschreibung der Transformation oder hältst du sowohl eine Matrix als auch nochmal Translationsvektor und Skalierungsvektor?
Ich beschäftige mich ja meist mit 2D-Grafik, da gibt es in der Regel ja nur eine Rotation um die Z-Achse und das Problem erübrigt sich. Dank des Halloween-Projekts komme ich aber nun in die Verlegenheit, mich mit 3D auseinanderzusetzen. Wenn man schaut, was quelloffene Engines so machen, dann hat man den Eindruck, dass sie oft alles gleichzeitig haben (Positionsvektor, Skalierunsvektor, Quaternion UND Transformationsmatrix). Dann sind sie immer viel beschäftigt, alles zu synchronisieren. Ich frage mich, ob das einfach nur die Benutzerfreundlichkeit erhöhen soll oder ob es einen tieferen Sinn gibt, den ich aktuell nicht sehe.
Gruß
Letztes Projekt: Grave of the Pumpkin (ZFX Halloween Action 2021)
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Quaternion und Singularität

Beitrag von Jonathan »

mtorc1 hat geschrieben: 05.10.2021, 09:36 Mal aus Neugier... speicherst du bei deinen Objekten dann ausschließlich Matrizen zur Beschreibung der Transformation oder hältst du sowohl eine Matrix als auch nochmal Translationsvektor und Skalierungsvektor?
Hm, ich würde sagen, das ist unterschiedlich. Prinzipiell habe ich in meiner Model-Klasse erstmal nur eine transformationsmatrix (4x4) gespeichert, die so direkt an den Shader übergeben wird. Im Entity-System wiederum speicher ich einen Winkel als Rotation um die Z-Achse. Für Spiele wie den Landvogt ist das nützlich, weil man Gebäude zwar ausrichten will, aber normalerweise nicht auf den Kopf stellen würde. Wenn ich irgendwann mal Objekte am Terrain ausrichten möchte (also leicht kippen, z.B.) würde ich glaube ich spontan einfach den Up-Vector (d.h. die Terrainnormale) speichern und zur Laufzeit daraus eine Matrix berechnen (d.h. eine Identitätsmatrix nehmen, den Z-Achsen Vektor darin austauschen und durch zwei Kreuzprodukte die anderen Achsen orthogonal dazu machen). Dann würde ich die Objekttransformation berechnen, indem ich zuerst die Matrix mit der Rotation um die Z-Achse anwende und dann die 'Kipp-Matrix' des Terrains (weil der Terrain-Normalvektor ja in globalen Koordinaten ist und nicht um die Z-Achse gedreht werden darf).
Um das zu verallgemeinern: Die komplette Transformation besteht aus mehreren Komponenten, und für jede davon würde ich mir eine Intuitive Darstellung überlegen, die ich leicht verstehen und mit der ich gut arbeiten kann.

Das Beispiel mit nur der Matrix war eher auf einen Viewer bezogen: Das Objekt wird halt irgendwie dargestellt, der User kann drehen und skalieren, das sind aber alles relative Aktionen, die man einfach in die aktuelle Transformation reinrechnen kann. So hat man nach einigem Umsehen zwar theoretisch eine super lange Transformationskette (bestehend aus allen Einzelaktionen), aber da die nicht weiter interessant ist, wird nur das Endergebnis als Matrix gespeichert und der Weg dorthin vergessen. Zusätzlich kann man natürlich noch Knöpfe wie "Anschauen aus X-Richtung" haben, die dann nicht auf die aktuelle Transformation hinzugerechnet werden, sondern sie komplett überschreiben.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
mtorc1
Beiträge: 80
Registriert: 20.02.2021, 16:24

Re: Quaternion und Singularität

Beitrag von mtorc1 »

Klar, dass es keine eine Lösung für alle Fälle gibt. Vielen Dank für die Auskunft.
Letztes Projekt: Grave of the Pumpkin (ZFX Halloween Action 2021)
Antworten