Ich zeichne eine flache Festplatte mit gluDisk()
in meiner Szene. gluDisk()
zeichnet die Scheibe mit Blick auf die positive Z-Achse, aber ich möchte, dass es einige willkürliche Normale habe ich habe.
Klar muss ich glRotate()
verwenden, um die Festplatte richtig angezeigt zu bekommen, aber was sollte die Rotation sein? Ich erinnere mich, dass dies mit Quaternions berechnet werden kann, aber ich kann mich nicht an die Mathematik erinnern.Quaternion Mathematik für die Rotation?
Antwort
Die Lösung sollte ziemlich unkompliziert sein und sollte keine Quartalszahlen erfordern.
Die Rotationsachse von Normal1 zu Normal2 muss orthogonal zu beiden sein, nehmen Sie einfach ihre Vektor Cross-Produkt.
Die Menge an Rotation wird leicht von ihrem Punktprodukt abgeleitet. Dieser Wert ist | A |. | B | .cos (Theta), aber da die beiden Normalenvektoren normalisiert werden sollten, ergibt sich cos (Theta), also nehmen Sie einfach den inversen Kosinus, um den Rotationsbetrag zu erhalten.
Der resultierende Vektor und Winkel sind die erforderlichen Parameter für glRotate()
- Sie müssen die tatsächliche Rotationsmatrix nicht selbst berechnen.
p.s. Vergiss nicht, dass glRotate()
den Winkel in Grad benötigt, aber die normalen C-Trig-Funktionen funktionieren im Bogenmaß.
Quaternionen beschreiben eine Rotation um eine Achse. <w,x,y,z>
wird um die Achse <x,y,z>
eine gewisse Menge abhängig von der Balance zwischen der Größe von w
und der Größe des Vektors drehen.
<cos θ/2, x*sin θ/2, y*sin θ/2, z*sin θ/2>, where |<x, y, z>| = 1
beispielsweise Drehen der positiven Y-Achse statt zugewandt sind, müssen Sie sie 90 ° um die X-Achse drehen. Der Vektor wäre <0, 1, 0>
, und die Quaternion wäre <cos 90°, 0, sin 90°, 0>
= <0, 0, 1, 0>
.
Um die Figur von der positiven Z-Achse zum Vektor <x,y,z>
zu drehen, müssen Sie den Rotationsvektor und den Rotationswinkel finden. Um die Rotationsachse zu finden, können Sie das Kreuzprodukt eines aktuellen Vektors nehmen, und wo Sie es haben möchten.
Wenn es der positiven Z-Achse zugewandt ist, wäre der aktuelle Vektor <0, 0, 1>
. Wenn Sie möchten, dass es auf <x,y,z>
zeigt, wäre die Rotationsachse <0, 0, 1> x <x, y, z> = <-y, x, 0>
, und der Winkel wäre arctan(sqrt(x^2+y^2),z)
. Die Quaternion
<cos(θ/2), -y*sin(θ/2), x*sin(θ/2), 0>, where θ = arctan(sqrt(x^2+y^2), z)
Drehung um eine beliebige Achse wird: gegebener Winkel R in Radian und Einheitsvektor u = ai + bj + ck oder [a, b, c], definieren:
q0 = cos(r/2)
q1 = sin(r/2) a
q2 = sin(r/2) b
q3 = sin(r/2) c
und konstruiert aus diesen Werten die Rotationsmatrix:
(q0^2+q1^2 - q2^2 - q3^2 | 2*(q1*q2 - q0*q3) | 2*(q1*q3 + q0*q2) )
Q =(2*(q2*q1 + q0*q3) | (q0^2 - q1^2 + q2^2 - q3^2) | 2*(q2*q3 - q0*q1) )
(2*(q3*q1 - q0*q2) | 2*(q3*q2 + q0*q1) | q0^2 - q1^2 - q2^2 + q3^2)
um die Drehung, die Sie tun müssen, um zu finden, können Sie das Kreuzprodukt zwischen dem Stromvektor und dem Zielvektor zu berechnen. Sie erhalten den orthogonalen Vektor (der Ihr Rotationsvektor ist, um die Quaternion zu erzeugen) und die Länge dieses Vektors ist die Sünde des Winkels, den Sie kompensieren müssen, so dass sich der Start- und der Zielvektor überlappen.
Vielen Dank. das hat perfekt funktioniert. – shoosh