Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 14:26

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Matrix -> glRotate / glTranslate
BeitragVerfasst: So Jan 04, 2009 07:14 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Hi,

kann ich wenn ich eine Matrix habe aus den einzelnen werten wieder die werte rausbekommen die ich für glRotate/glTranslate angeben müßte um die gleiche matrix zu bekommen?

Für Translate ist das ja kein problem.. aber bei rotate hab ich keinen plan wie das geht :/

Ich bräuchte in meinem fall die rotationswerte als Euler-Rotation, so das ich via:

Code:
  1. glRotate(x, 1, 0, 0);
  2. glRotate(y, 0, 1, 0);
  3. glRotate(z, 0, 0, 1);


rotieren kann.


Nochmal zusammengefasst in pseudocode:

Code:
  1. glMultMatrix(myMatrix);


soll dasselbe ergeben wie:

Code:
  1. extractDataFromMatrix(myMatrix, tx, ty, tz, rx, ry, rz);
  2. glTranslate(tx, ty, tz);
  3. glRotate(rx, 1, 0, 0);
  4. glRotate(ry, 0, 1, 0);
  5. glRotate(rz, 0, 0, 1);


geht das? und wenn ja, wie? :)

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 04, 2009 10:27 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
Du kannst das Problem zumindest ein Stück weit vereinfachen indem du erst rotierst und zuletzt verschiebst (in deinem Code machst du es andersrum). Damit entspricht deine Translation der 4. Spalte deiner Matrix.

Ist der verbleibende Teil von myMatrix ohne die Translation eine reine Rotationsmatrix oder enthält sie auch andere Anteile wie z.B. Skalierungen?

In jedem Fall kannst du ein Gleichungssystem aufstellen und nach den Unbekannten auflösen. Das Ganze wird allerdings extrem aufwändig und auch nicht sehr performant. Eine bessere Lösung fällt mir aber im Moment nicht ein.

Was genau hast du denn vor? Ist es möglich die einzelnen Winkel zu speichern wenn du myMatrix generierst? Oder liegt myMatrix wirklich nur in der Matrixform vor weil du sie z.B. aus einer Datei lädst?

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 04, 2009 10:30 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Magellan hat geschrieben:
Du kannst das Problem zumindest ein Stück weit vereinfachen indem du erst rotierst und zuletzt verschiebst (in deinem Code machst du es andersrum). Damit entspricht deine Translation der 4. Spalte deiner Matrix.

Oh, so meinte ich es auch, sorry.. vertauscht :)

Magellan hat geschrieben:
Ist der verbleibende Teil von myMatrix ohne die Translation eine reine Rotationsmatrix oder enthält sie auch andere Anteile wie z.B. Skalierungen?

Ist eine reine rotations matrix, ohne shear, scale etc.

Magellan hat geschrieben:
Was genau hast du denn vor? Ist es möglich die einzelnen Winkel zu speichern wenn du myMatrix generierst? Oder liegt myMatrix wirklich nur in der Matrixform vor weil du sie z.B. aus einer Datei lädst?

Ich lade die Matrix aus einer Datei.. hab leider keine möglichkeit an die werte von der generierung ranzukommen :(

Das performance problem wäre nicht so wild, würde ja nur einmal berechnet werden, aber wie würde denn so eine gleichung aussehen? :oops:

Aya~


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 04, 2009 11:00 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 27, 2005 12:44
Beiträge: 393
Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo Aya,

wenn man die drei Rotationsmatrizen in deiner Reihenfolge multipliziert, kommt
man ( falls ich mich nicht verrechnet habe ) auf die Matrix :

Code:
  1.  
  2. cos(ry)*cos(rz)                         -sin(rz)*cos(ry)            sin(ry)             0
  3. sin(rx)*sin(ry)*cos(rz)                 cos(rx)*cos(rz)             -sin(rx)*cos(ry)    0
  4. +cos(rx)*sin(rz)                        -sin(rx)*sin(ry)*sin(rz)
  5. sin(rx)*sin(rz)                         cos(rx)*sin(ry)*sin(rz)     cos(rx)*cos(ry)     0
  6. -cos(rx)*sin(ry)*cos(rz)                +sin(rx)*cos(rz)
  7. 0                                       0                           0                   1
  8.  


In der ersten Zeile und dritten Spalte kannst du direkt sin(ry) ablesen.
Wenn du ry hast und etwas Glück, dass cos(ry) nicht 0 ist, kannst du aus der ersten oder zweiten Spalte rz und aus der dritten Spalte und zweiten oder dritten Zeile rx ausrechnen.
Falls cos(ry) doch 0 ist, weißt du wenigstens, dass sin(ry) gleich 1 oder -1 ist.
In diesem Falle reduziert sich die Untermatrix von (2,1) bis (3,2) auf

Code:
  1.  
  2. sin(rx)*cos(rz)+cos(rx)*sin(rz) cos(rx)*cos(rz)-sin(rx)*sin(rz)
  3. sin(rx)*sin(rz)-cos(rx)*cos(rz) cos(rx)*sin(rz)+sin(rx)*cos(rz)
  4.  


bzw.

Code:
  1.  
  2. cos(rx)*sin(rz)-sin(rx)*cos(rz) cos(rx)*cos(rz)+sin(rx)*sin(rz)            
  3. sin(rx)*sin(rz)+cos(rx)*cos(rz) sin(rx)*cos(rz)-cos(rx)*sin(rz)
  4.  


Wenn man genau hinsieht, erkennt man die beiden Additionstheoreme und du kannst auf

Code:
  1.  
  2. sin(rx+rz)  cos(rx+rz)
  3. -cos(rx+rz) sin(rx+rz)
  4.  


bzw.

Code:
  1.  
  2. sin(rz-rx)  cos(rz-rx)
  3. cos(rz+rx)  sin(rx-rz)
  4.  


reduzieren.

rx und rz bekommst du dann leider nicht mehr eindeutig heraus, aber du kannst
einen der beiden Winkel frei wählen, und erhältst dann automatisch den
anderen.

Viele Grüße
dj3hut1

_________________
Wenn Gauß heute lebte, wäre er ein Hacker.
Peter Sarnak, Professor an der Princeton University


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 04, 2009 12:59 
Offline
DGL Member

Registriert: Sa Aug 09, 2008 09:07
Beiträge: 112
Wenn du eine Matrix-Klasse hast die gut mit einer Vektor-Klasse verknüpft ist, dann sollte das nicht so ein großes Problem werden:

Nimm eine Vektor, irgendeinen der als Komponente keine 0 hat. (Mathematisch: Vectoren = { (x, y, z, w) e R^4 | x, y, z, w != 0 } )
Dann manipulierst du diesen Vektor mit der angegebenen Matrix (Achtung: OpenGL Matrizen sind in einem Array gespeichert und zwar Spaltenorientiert).
Und dann rechnest du die Winkel aus zum vorherigen Vektor.

Das geht mittels Skalarprodukt:
Def.: a * b = |a| * |b| * cos PHI

=> cos PHI = (a * b) / (|a| * |b|)

(alles nur noch 2D:)
Wenn du den Winkel auf der X-Achse haben willst, dann setzt du für a und b das ein:
a = (y, z) ... jeweils die anfangs Werte
b = (y', z') ... jeweils die neuen Werte
Ab in die Formel und schon bekommst du den Winkel.

Y-Achse:
a = (x, z)
b = (x', z')

Z-Achse:
a = (x, y)
b = (x', y')


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jan 05, 2009 23:51 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
Du hast deine Rotationsmatrix M. Diese soll der Form RX * RY * RZ entsprechen, wobei RX, RY, und RZ hier den Rotationsmatrizen um die Einheitswinkel entsprechen.
Auf den homogenen Anteil kannst du verzichten, da dieser sowieso gleich bleibt.

Letztlich steht dort dann RX * RY * RZ = M

Die Matrix hat dir dj3hut1 bereits angegeben.
Dieses Gleichungssystem musst du dann lösen. Das kannst Du Dir z.B. mit einem Programm wie Maple umstellen lassen. Wir haben an der Uni Maple zur Verfügung, d.h. ich könnte Dir die umgestellte Formel zuschicken, wenn Du Interesse hast.
Allerdings wird das vermutlich eine ziemlich üble Lösung werden und ich bezweifle, dass das nicht effizienter geht.

Die Idee von Andreas erscheint mir da wesentlich eleganter. Hast Du diese Lösung ausprobiert? Funktioniert sie? Er bestimmt letztlich die Winkel zwischen den Achsen in den beiden Koordinatensystemen. Meiner Meinung nach müsste man aber beachten, dass die einzelnen Rotationen von glRotate diese Achsen auch wieder verändern können.

Wenn Du einen Vektor v = (1, 1, 1) mit deiner Matrix M multiplizierst v' = M * v und den Winkel zwischen den beiden Vektoren bestimmst erhältst Du den Rotationswinkel phi.
Die Rotationsachse r bestimmst du dann mit dem Kreuzprodukt zwischen v und v' (normiert).

Dann müsstest du mittels glRotatef(phi * 180 / PI, r[0], r[1], r[2]) deine Rotation reproduzieren können. Die Frage ist, wie man diese Informationen in die Eulerwinkel überführt.

Ich werde damit morgen Abend selbst etwas rumspielen. Vielleicht erbarmt sich ja auch ein Mathematiker wie Nico und weiht uns in eine simple Lösung ein. Oder aber Andreas Lösung hat funktioniert. In diesem Fall sollte jeder meinen Beitrag ignorieren ;).

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 06, 2009 10:24 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
Also ich sehe das so... Zuerst wirst Du die Translation los, darüber sind wir uns ja schon einig, daß die nur stört und kein Problem ist und wir beschränken uns auf Rotationsmatrizen M... Dann..

Zitat:
Wenn Du einen Vektor v = (1, 1, 1) mit deiner Matrix M multiplizierst v' = M * v und den Winkel zwischen den beiden Vektoren bestimmst erhältst Du den Rotationswinkel phi.

Nein so leicht gehts leider nicht... Mit einem Vektor alleine wirst Du nicht schlau - was wenn die Rotationsachse gerade R(1,1,1) ist.. Dann kann ich um beliebige Winkel drehen, v bleibt immer der gleiche. Wenn ich das wirklich so machen will muss v senkrecht zum 1er Eigenvektor der Matrix sein, also in der Rotationsabene liegen. Den Eigenvektor bestimmen ist ein lineares gleichungssystems: (M-Id)e=0 . Wobei e der gesuchte Eigenvektor ist. Wenn M schon die Identität ist, sollte ich rechtzeig aufhören zu rechnen, aber dann ist von der Rotation auch nicht viel über..

Wenns Dir irgendwie genügt, deine Daten klein abzulegen, dann kannst Du auch Quaternionen verwenden.. Wie man von Matrizen zu Quaternion kommt steht z.B. hier http://cache-www.intel.com/cd/00/00/29/ ... 293748.pdf . Habs jetzt aber nicht durchgecheckt, ob alles so auch seine Richtigkeit hat...

Wenns unbedingt Eulerwinkel sein müssen, dann musst Du natürlich erst die Reihenfolge deiner Eulerwinkel bestimmen und dann alle miteinander multiplizieren und dann kommt eine ganz scheussliche Matrix heraus... Das Ding hier kommt mir sehr bekannt vor, so ähnlich schaun die immer aus. Irgendwo taucht ein einsamer cos oder sinus eines winkels auf (hier rechts unten), daraus kommst du an Winkel theta ran. Wenn der sinus von theta jetzt nicht gerade 0 ist, dann kommst du aus der letzten zeile auch sofort an sinus und cosinus psi heran, und kennst den nächsten winkel... naja und wenn das mal geklappt hat, kannst dich an eine der zeilen darüber machen und phi ausrechnen, weil du theta und psi ja schon kennst.. ist in dem thread auch beschrieben.
blöd ist der fall, wenn cos theta gerade eins war, dann ist nämlich sinus theta gerade 0 und dann kannst du aus der untersten zeile nicht auf psi schliessen. selbes für die letzte spalte, die bringt dir auch nix weiter... ehrlich gesagt ist die situation dann sau blöd, weil psi und phi dann nicht mehr so ganz eindeutig sind (Gimbal Lock!)... Ehrlich gesagt, so eine richtig gute Idee habe ich da nicht, aber du kannst sehen, daß das die 2x2 Matrix links oben dann eine 2D Rotationsmatrix beschreibt, bei der Du den Drehwinkel bestimmen kannst (hat ja nur eine Achse). Dann musst Du ganz scharf deine Euler-Winkel ansehen, den einen (theta) in den GimbalLock drehen, den anderen 0 setzen (meinetwegen psi) und phi=+- beta setzten, so daß halt stimmt.. So und weil ich so ein aufmerksamer leser bin, hab ich natürlich bemerkt, daß dj3hut1 das auch schon beschrieben hat.... *grummelgrummel*


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 16 Queries | GZIP : On ]