Hallo
ich beschäftige mich mit der Grafikprogrammierung mit DirectX
und C++. Jetzt bin ich neulich über das Konzept oder vielmahr
des Problems des sogennaten Gimballocks gestossen. In der
englischen Wikipedia habe ich auch einen Artikel gefunden, der
diese Problem sehr gut veranschaulicht. Da ich kein
Mathematiker bin, konnte ich mir das mit dem dort
dargestellten Models (ich glaub es war ein Gyroskop oder so
ähnlich) ganz gut nachvollziehen. Wenn man drei Achsen hat und
drei Eulerwinkel (für jede Achse einen…) dann gibt es
momente, wo eine der Achsen mit einer zweiten zusammenfällt…
ich glaube es war die z und x Achse, wenn man um die y Achse
um 90° drehte (wie gesagt bin kein Mathematiker und da nicht
so ganz firm… ich bitte das zu entschuldigen).
Ich glaube, das ist nicht das Problem. Du kannst
durch Kombination von Hauptachsenrotationen ei-
gentlich immer *in kleinen Schritten* zum ge-
wünschten Ergebnis kommen. Problematisch kann
es werden, wenn das Objekt um eine beliebige
Raumachse und um einen beliebigen Winkel
rotiert werden soll.
Jetzt habe ich ein wenig rumgelesen im Internet und bin auf
Quaternionen gestossen, welche angeblich sehr viel besser sein
sollen um Rotationen darstellen zu können.
Sind ok, aber meiner Meinung nach für 95% aller
Computergrafikaufgaben nicht nötig.
Ich habe auch bei DirectX die Möglichkeit aus Eulerwinkeln
Quaternionen berechnen zu lassen, aber habe auch gelesen, wenn
ich die Umrechnung mache, dann kann ich das Problem des Gimballocks
nicht umgehen. Habe ich das richtig verstanden? Und wenn ich
es falsch verstandenn haben sollte, gibt es denn eine
Möglichkeit mit Quaternionen Rotationen durchzuführen, ohne
auf Eulerwinkel zurückzugreifen?
Du solltest vielleicht bei Objektrotationen immer von
Raumachsen ausgehen, um die das Objekt rotiert wird.
Eine Raumachse ist z.B. {1,0,0}, also die X-Achse
(Ursprung immer 0,0,0). Oder eben {0.5,0.2,-0.3} usw.
Um diese Achse wird das Objekt „gedreht“ und zwar um
einen bestimmten Winkel. Das macht man ganz klassisch
z.B. mit einer 3x3-Rotationsmatrix. Hat man diese
für eine Rotation um eine beliebige Achse aufgebaut,
multipliziert man (Vektor x Matrix) einfach die
Koordinaten des Objekts damit.
Verschiedene Rotationen kann man verketten, in dem
man die Rotationsmatrizen miteinander multipliziert.
Siehe: http://en.wikipedia.org/wiki/Rotation_matrix
=>unten „Axis and angle“
Ich denke, der Rotationsmatrixalgorithmus wird
in den meisten Fällen schneller als der
Matrix-Quaternion-Algorithmus sein - und viel
einfacher zu implementieren ebenfalls.
(siehe auch: http://peds.oxfordjournals.org/cgi/reprint/16/10/717 )
Beispiel in C:
void make\_rotmatrix(double m[3][3], double ang, double axis[3]) {
double x = axis[0], y = axis[1], z = axis[2];
double c = cos(ang), s = sin(ang), t = 1.0 - c;
m[0][0] = t \* x \* x + c;
m[0][1] = t \* x \* y + s \* z;
m[0][2] = t \* x \* z - s \* y;
m[1][0] = t \* x \* y - s \* z;
m[1][1] = t \* y \* y + c;
m[1][2] = t \* y \* z + s \* x;
m[2][0] = t \* x \* z + s \* y;
m[2][1] = t \* y \* z - s \* x;
m[2][2] = t \* z \* z + c;
}
und später:
void rotate\_point(double point[3], double m[3][3]) {
double x = point[0], y = point[1], z = point[2];
point[0] = m[0][0]\*x + m[0][1]\*y + m[0][2]\*z;
point[1] = m[1][0]\*x + m[1][1]\*y + m[1][2]\*z;
point[2] = m[2][0]\*x + m[2][1]\*y + m[2][2]\*z;
}
usw.
Nicht zu vergessen:
- Rotationsachse auf L=1 normieren
- evtl. Translation der Punkte vor/nach der Rotation (Drehpunkt im Objekt)
- Winkel in rad
Grüße
CMБ