2009-04-18 11 views
8

Je dessine un disque plat en utilisant gluDisk() dans ma scène. gluDisk() dessine le disque face à l'axe Z positif, mais je veux qu'il soit confronté à une normale arbitraire que j'ai.
Il est clair que je dois utiliser glRotate() pour que le disque soit correctement orienté, mais quelle devrait être la rotation? Je me souviens que cela peut être calculé en utilisant Quaternions mais je n'arrive pas à me souvenir des maths.Math quaternion pour la rotation?

Répondre

16

La solution devrait être assez simple et ne devrait pas nécessiter de quarternions.

L'axe de rotation pour passer de Normal1 à Normal2 doit être orthogonal aux deux, il suffit donc de prendre le produit vectoriel.

La quantité de rotation est facilement dérivée de leur produit . Cette valeur est | A |. | B | .cos (thêta), mais comme les deux vecteurs normaux doivent être normalisés, cela donnera cos (thêta), il suffit donc de prendre le cosinus inverse pour obtenir la quantité de rotation.

Le vecteur et l'angle résultants sont les paramètres requis pour glRotate() - il n'est pas nécessaire de calculer vous-même la matrice de rotation réelle.

p.s. ne pas oublier que glRotate() a besoin de l'angle en degrés, mais les fonctions trigonométriques normales en C fonctionnent en radians.

+0

Merci. Cela a fonctionné parfaitement. – shoosh

3

Les quaternions décrivent une rotation autour d'un axe. <w,x,y,z> tournera autour de l'axe <x,y,z> une certaine quantité en fonction de l'équilibre entre l'amplitude de w et l'amplitude du vecteur.

<cos θ/2, x*sin θ/2, y*sin θ/2, z*sin θ/2>, where |<x, y, z>| = 1 

Par exemple, tourner pour faire face à la place de l'axe Y positif, vous devez le faire pivoter de 90 ° autour de l'axe X. Le vecteur serait <0, 1, 0>, et le quaternion serait <cos 90°, 0, sin 90°, 0> = <0, 0, 1, 0>.

Pour faire pivoter la figure d'en face de l'axe Z positif, pour faire face au vecteur <x,y,z> vous devez trouver le vecteur de rotation et l'angle de rotation. Pour trouver l'axe de rotation, vous pouvez prendre le produit croisé d'un vecteur courant, et où vous voulez qu'il soit. Si elle fait face à l'axe Z positif, le vecteur courant serait <0, 0, 1>. Si vous voulez faire face <x,y,z>, l'axe de rotation serait <0, 0, 1> x <x, y, z> = <-y, x, 0>, et l'angle serait arctan(sqrt(x^2+y^2),z). Le quaternion devient

<cos(θ/2), -y*sin(θ/2), x*sin(θ/2), 0>, where θ = arctan(sqrt(x^2+y^2), z) 
6

rotation autour d'un axe arbitraire: angle donné r en radians et vecteur unitaire u = ai + bj + ck ou [a, b, c], définis comme:

q0 = cos(r/2) 
q1 = sin(r/2) a 
q2 = sin(r/2) b 
q3 = sin(r/2) c 

et construire à partir de ces valeurs, la matrice de rotation:

(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) 

pour trouver la rotation que vous devez faire, vous pouvez calculer le produit croisé entre le vecteur courant et le vecteur cible. Vous obtiendrez le vecteur orthogonal (qui sera votre vecteur de rotation pour créer le quaternion) et la longueur de ce vecteur est le péché de l'angle que vous devez compenser pour que le vecteur de départ et le vecteur cible se chevauchent.