2010-11-30 33 views
7

J'expérimente l'utilisation de vecteurs d'angle d'axe pour les rotations dans mon moteur de jeu amateur. C'est un vecteur à trois composantes le long de l'axe de rotation avec une longueur de rotation en radians. Je les aime parce que:Combiner les vecteurs d'axe de rotation

  • Contrairement à matrices quats ou rotation, je peux réellement voir les chiffres et visualiser la rotation dans mon esprit
  • Ils sont un peu moins de mémoire que escouades ou matrices.
  • Je peux représenter des valeurs en dehors de la plage de -Pi à Pi (Ceci est important si je stocke une vitesse angulaire)

Cependant, j'ai une boucle serrée qui met à jour la rotation de tous mes objets (des dizaines de milliers) en fonction de leur vitesse angulaire. Actuellement, la seule façon que je connaisse de combiner deux vecteurs d'axe de rotation est de les convertir en quaternions, de les multiplier, puis de convertir le résultat en un axe/angle. Grâce au profilage, j'ai identifié cela comme un goulot d'étranglement. Est-ce que quelqu'un sait une approche plus directe?

+0

Est-ce que cela signifie que 3 valeurs représentent des rotations séquentielles sur 3 axes orthogonaux? Fondamentalement, les angles euler tels que «[phi, psi, thêta]» peuvent représenter «RX (phi) * RY (psi) * RZ (thêta)». Si c'est le cas, vous devez trouver un moyen de construire la matrice de rotation 3x3 et en tirer l'angle d'axe. – ja72

+0

Non, je n'utilise pas les angles euler. C'est l'angle d'axe où la longueur du vecteur est l'angle. – Dwayne

Répondre

2

Votre représentation est équivalente à quaternion rotation, à condition que vos vecteurs de rotation soient de longueur unitaire. Si vous ne voulez pas utiliser une structure de données de quaternion en conserve, assurez-vous simplement que vos vecteurs de rotation ont une longueur unitaire, puis calculez l'équivalent quaternion multiplications/reciprocal computation pour déterminer la rotation globale. Vous pourriez être en mesure de réduire le nombre de multiplications ou d'ajouts.

Si votre angle est la seule chose qui change (c'est-à-dire que l'axe de rotation est constant), alors vous pouvez simplement utiliser une mise à l'échelle linéaire de l'angle, et, si vous le souhaitez, mod. intervalle [0, 2 π). Donc, si vous avez un taux de rotation de α raidans par seconde, à partir d'un angle initial de θ à l'instant t , l'angle de rotation finale à l'instant t est donnée par:

θ (t) = 0 θ + α (tt) mod 2 π

Vous appliquez ensuite seulement que la rotation à votre collection de vecteurs. Si rien de tout cela n'améliore vos performances, vous devriez envisager d'utiliser une bibliothèque de quaternions en conserve car ces éléments sont déjà optimisés pour les types d'applications que vous êtes en train de modifier.

+0

1. Mes vecteurs ne sont pas des unités de longueur. Leur longueur est l'angle de rotation en radians. 2. J'utilise une structure de données quaternion. 3. Dans de nombreux cas, mon angle n'est pas la seule chose qui change, mais ce serait un bon contrôle d'optimisation. – Dwayne

+0

"Calculer les multiplications de quaternions équivalentes/calcul réciproque pour déterminer la rotation globale" Est-ce la même chose que la conversion de l'angle d'axe en quaternion et vice versa? Ma mise en œuvre actuelle est à partir de la FAQ Matrix et Quaternion (http://www.j3d.org/matrix_faq/matrfaq_latest.html) – Dwayne

1

Vous devez utiliser des quaternions unitaires plutôt que des vecteurs mis à l'échelle pour représenter vos rotations. On peut montrer (pas par moi) que toute représentation de rotations utilisant trois paramètres rencontrera des problèmes (c'est-à-dire est singulier) à un certain point. Dans votre cas, il se produit lorsque votre vecteur a une longueur de 0 (c'est-à-dire l'identité) et à des longueurs de 2pi, 4pi, etc. Dans ces cas, la représentation devient singulière. Les quaternions unitaires et les matrices de rotation n'ont pas ce problème. D'après votre description, il semble que vous mettiez à jour votre état de rotation à la suite de l'intégration numérique. Dans ce cas, vous pouvez mettre à jour votre état de rotation en convertissant votre taux de rotation (\ omega) en un taux de quaternion (q_dot).Si nous représentons votre quaternion comme q = [q0 q1 q2 q3] où q0 est la partie scalaire alors:

q_dot = E*\omega 

[ -q1 -q2 -q3 ] 
E = [ q0 -q3 q2 ] 
    [ q3 q0 -q1 ] 
    [ -q2 q1 q0 ] 

Ensuite, votre mise à jour devient

q (k + 1) = q (k) + q_dot * dt

pour une intégration simple. Vous pouvez choisir un intégrateur différent si vous le souhaitez.

+0

Qu'est-ce que cela signifie pour que la rotation devienne singulière, et quel genre de problème cela va-t-il apporter? – Dwayne

+1

Il peut ou ne peut pas causer un problème. Cela signifie qu'à ces endroits, vous perdez un certain degré de liberté. Cela signifie que si vous souhaitez transformer les taux entre votre représentation et un autre (disons quaternions), la matrice de transformation (c'est-à-dire jacobienne) est singulière (ne peut pas être inversée). – Commodore63

2

Vous pouvez les conserver en tant que valeurs d'axe d'angle.

Construire une matrice de produits croisés (anti-symmetric) en utilisant les valeurs de l'axe des angles (x,y,z) et de pondérer les éléments de cette matrice en les multipliant par la valeur de l'angle. Résumez maintenant toutes ces matrices inter-produits (one for each angle axis value) et trouvez la matrice de rotation finale en utilisant l'exponentielle matricielle.

Si la matrice A représente cette matrice produit croisé (construit à partir de la valeur d'angle d'axe) puis,

exp(A) est équivalente à la matrice de rotation R(i.e., equivalent to your quaternion in matrix form).

Par conséquent,

exp (A1 + A2) = R1 * R2 

probablement un calucation plus cher à la fin ...