système de coordonnées en rotation par l'intermédiaire d'un quaternion
Nous avons une foule de coordonnées spatiales (x, y et z) représentant les atomes dans l'espace 3d, et je suis de la construction d'une fonction qui va traduire ces points à un nouveau système de coordonnées. Déplaçant les coordonnées d'une origine arbitraire est simple, mais je ne peut pas envelopper la tête autour de la prochaine étape: le point 3d de la rotation des calculs. En d'autres termes, je suis en train de traduire les points de (x, y, z) à (x', y', z'), où x', y' et z' sont en termes de i', j' et k', le nouvel axe des vecteurs, je suis en train de faire avec l'aide de la euclide module python.
Je pense tout ce que je besoin est un euclid quaternion pour ce faire, c'est à dire
>>> q * Vector3(x, y, z)
Vector3(x', y', z')
mais pour faire ce QUE je crois que j'ai besoin d'un vecteur de l'axe de rotation et l'angle de rotation. Mais je n'ai aucune idée de la façon de calculer ces de i', j' et k'. Cela semble être une procédure simple de code à partir de zéro, mais je soupçonne que quelque chose comme ceci nécessite d'algèbre linéaire de la figure sur mon propre. Un grand merci pour un coup de pouce dans la bonne direction.
- juste pour clarifier, vous voulez une transformation linéaire d'un euclidienne 3-espace à un autre euclidienne 3-l'espace?
- Voici un indice: Quelles seraient les vecteurs
(0, 0, 1)
,(0, 1, 0)
et(1, 0, 0)
être traduite? - Matrice de Rotation est le meilleur choix ici. La matrice de rotation relative de coordonner les images est facile à obtenir et efficace d'appliquer. L'obtention et l'application d'un quaternion ici aurait essentiellement pour effet d'exiger la conversion de matrice de rotation et de le convertir ensuite retour à la matrice de rotation. Évidemment, il est préférable de simplement utiliser la matrice de rotation. Les Quaternions ont leurs forces ailleurs. Leurs points forts sont qu'ils sont seulement 4 numéros peuvent être composés et appliquée sans trig, sont simples et les contraintes (amplitude de l'unité), et sont bien adaptés pour l'interpolation.
Vous devez vous connecter pour publier un commentaire.
En utilisant les quaternions pour représenter la rotation n'est pas difficile de partir d'un algébriques point de vue. Personnellement, je trouve ça dur à raison visuellement quaternions, mais les formules à utiliser pour les rotations sont assez simples. Je vais vous fournir une base de référence fonctions ici.1 (Voir aussi cette belle réponse par hosolmaz, dans laquelle il a des paquets de créer une pratique de Quaternions de la classe.)
Vous pouvez penser de quaternions (pour nos besoins) comme un scalaire, plus un 3-d vecteur, de façon abstraite,
w + xi + yj + zk
, ici représenté par une simple tuple(w, x, y, z)
. L'espace de la 3-d des rotations est représenté dans son intégralité par un sous-espace des quaternions, l'espace de unité quaternions, de sorte que vous voulez vous assurer que votre quaternions sont normalisés. Vous pouvez le faire dans juste la façon dont vous serait de normaliser toutes les 4-vecteurs (magnitude devrait être proche de 1; si elle n'est pas, à l'échelle des valeurs par l'ampleur):Veuillez noter que pour des raisons de simplicité, les fonctions suivantes supposent que les quaternions valeurs sont déjà normalisé. Dans la pratique, vous aurez besoin d'effectuer une renormalisation de temps en temps, mais la meilleure façon de traiter avec qui dépendent du domaine du problème. Ces fonctions fournissent juste la base, à des fins de référence seulement.
Chaque rotation est représenté par une unité de quaternions, et les concaténations de rotations correspondent à multiplications de quaternions unitaires. La formule2 pour ce est comme suit:
Pour faire tourner un vecteur par un quaternion, vous devez le quaternion est conjugué trop. C'est simple:
Maintenant quaternion-vecteur de la multiplication est aussi simple que la conversion d'un vecteur dans un quaternion (par la mise en
w = 0
et en laissantx
,y
, etz
le même) et puis en multipliantq * v * q_conjugate(q)
:Enfin, vous devez savoir comment faire pour convertir à partir de l'axe de l'angle de rotations de quaternions. Aussi facile! Il convient donc de "nettoyer" d'entrée et de sortie ici en appelant
normalize
.Et de retour:
Voici un petit exemple d'utilisation. Une séquence de 90 degrés rotations sur les axes x, y et z axes sera de retour d'un vecteur sur l'axe des y à sa position d'origine. Ce code effectue ces rotations:
Gardez à l'esprit que cette séquence de rotations ne reviendra pas tous vecteurs de la même position; par exemple, pour un vecteur sur l'axe des x, elle correspond à une rotation de 90 degrés sur l'axe des y. (Gardez la droite de la règle à l'esprit; un positif de rotation autour de l'axe y pousse un vecteur sur l'axe des x dans le négatif z de la région.)
Comme toujours, s'il vous plaît laissez-moi savoir si vous trouvez des problèmes ici.
1. Ces sont adaptés à partir d'un tutoriel OpenGL archivé ici.
2. La multiplication de quaternions formule se présente comme un fou rat du nid, mais le calcul est simple (si pénible). Il suffit de noter d'abord que
ii = jj = kk = -1
; alors queij = k
,jk = i
,ki = j
; et, enfin, queji = -k
,kj = -i
,ik = -j
. Alors multipliez les deux quaternions, de distribuer les termes et les réarranger sur la base des résultats de chacun des 16 multiplications. Cela permet aussi d'illustrer pourquoi vous pouvez utiliser les quaternions pour représenter la rotation; les six derniers identités suivre la règle de droite, créer des bijections entre les rotations dei
àj
et les rotations autour dek
, et ainsi de suite.qv_mult
pour être utile, il doit retourner un vecteur, pas un quaternion, donc j'ai abandonné le premier composant (qui est nul de toute façon!).qv_mult
devrait êtreq1 = normalize(q1)
(pasv1
)?Cette question et de la réponse donnée par @senderle m'a vraiment aidé avec l'un de mes projets. La réponse est minime et couvre le noyau de la plupart des quaternions de calculs à effectuer.
Pour mon projet, je l'ai trouvé pénible à séparer les fonctions de toutes les opérations et importer un par un à chaque fois que j'en ai besoin, j'ai donc mis en place une version orientée objet.
quaternion.py:
Dans cette version, il est possible d'utiliser les opérateurs surchargés pour quaternion-les quaternions et les quaternions-vecteur multiplication
Je n'ai pas l'intention de mettre en œuvre un véritable quaternion module, donc c'est encore pour des raisons pédagogiques, comme dans @senderle de la grande réponse. J'espère que cela aide à ceux qui veulent comprendre et essayer de nouvelles choses avec les quaternions.
Noter que l'inversion de la matrice n'est pas trivial du tout! Tout d'abord, tous les n (où n est la dimension de votre espace), les points doivent être en position générale (c'est à dire pas de point particulier, peut être exprimé comme une combinaison linéaire de repos des points [mise en garde: ce qui peut sembler être une simple exigence en effet, mais dans le domaine de l'algèbre linéaire numérique, il est non trivial; final decision si une telle configuration existent vraiment ou pas, sera finalement basé sur le " domaine spécifique de la connaissance]).
Également la "correspondance" de la nouvelle et l'ancienne points peuvent ne pas être exactes (et alors vous devriez utiliser le mieux possible approximator de la "vraie correspondance", c'est à dire:). Pseudo-inverse (au lieu d'essayer d'utiliser la plaine inverse) est recommandé de toujours lors de votre lib fournit.
La pseudo-inverse de a, l'avantage est que vous serez en mesure d'utiliser plus de points pour votre transformation, et donc à augmenter la probabilité qu'au moins n points en position générale.
Voici un exemple, la rotation de l'unité de la place de 90 degrés. ccw en 2D (mais, évidemment, cette détermination fonctionne dans n'importe dim), avec
numpy
:P. S.
numpy
est également rapide. La Transformation de 1 million de points dans mon ordinateur modeste: