IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Rotation avec les quaternions [Python 2.X]


Sujet :

Python

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 7
    Par défaut Rotation avec les quaternions
    Bonsoir,

    Pour un projet, je souhaite faire des rotations en utilisant les quaternions sous Python. Je connais la théorie, je sais a priori l'appliquer, c'est juste un petit problème "d'échelle" lorsque je fais différents tests.

    Pour me faire comprendre, voici 2 images :
    Une rotation de 45 degrés autour de l'axe ascendant :
    Nom : 45.png
Affichages : 1452
Taille : 28,2 Ko
    Une autre de 90 degrés autour de ce même axe :
    Nom : 90.png
Affichages : 1345
Taille : 25,1 Ko

    On voit, avec les graduations sur les axes, qu'il y a un problème d'échelle lorsque je change l'angle.. A priori, le cube est dessiné sur la région de l'espace [-10,10], comme vu ici (rotation réalisée avec les angles d'Euler) :
    Nom : phi 25, theta 180, psi 35.png
Affichages : 1311
Taille : 26,8 Ko

    Je ne vois pas d'où viens l'erreur..
    Je mets ici le code à disposition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    import time
    from numpy import sin,cos
    import matplotlib.pyplot as plt
    import numpy as np
    from itertools import product, combinations
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.set_aspect("auto")
    ax.set_autoscale_on(True)
     
    def q_conj(q):
        ''' Renvoie le conjugué d'un quaternion '''
        w, x, y, z = q
        return (w, -x, -y, -z)
     
    def normalise(v, tolerance=0.00001):
        ''' Normalise un quaternion'''
        mag2 = sum(n * n for n in v)
        if abs(mag2 - 1.0) > tolerance:
            mag = np.sqrt(mag2)
            v = tuple(n / mag for n in v)
        return v
     
    def axeangle_to_q(v, theta):
        ''' Renvoie le quaternion associé à une rotation d'un angle theta et autour de l'axe v '''
        v = normalise(v)
        x, y, z = v
        theta /= 2
        w = cos(theta)
        x = x * sin(theta)
        y = y * sin(theta)
        z = z * sin(theta)
        return w, x, y, z
     
    def q_to_axeangle(q):
        ''' Renvoie l'axe et l'angle de rotation associé à un quaternion '''
        w, v = q[0], q[1:]
        theta = np.arccos(w) * 2.0
        return normalise(v), theta
     
    def q_mult(q1, q2):
        ''' Multiplie 2 quaternions ensemble (attention à la non-commutativité) '''
        w1, x1, y1, z1 = q1
        w2, x2, y2, z2 = q2
        w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2
        x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2
        y = w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2
        z = w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2
        return w, x, y, z
     
    def qv_mult(q1, v1):
        ''' Applique le procédé de conjugaison pour réaliser une rotation '''
        q2 = (0.0,) + v1
        return q_mult(q_mult(q1, q2), q_conj(q1))[1:]  
     
    def dessiner_cube_quaternion(q):
        r = [-10, 10]
        theta=q_to_axeangle(q)[1]
        for s, e in combinations(np.array(list(product(r,r,r))), 2):
                if np.sum(np.abs(s-e)) == r[1]-r[0]:
                    a=axeangle_to_q(e,theta)[1:]
                    b=axeangle_to_q(s,theta)[1:]
                    e_rotated=qv_mult(q,a)
                    s_rotated=qv_mult(q,b)
                    ax.plot3D(*zip(s_rotated,e_rotated), color="b")
     
     
    theta=np.radians(45)
    q=axeangle_to_q((0,0,1),theta) #Rotation de theta autour de l'axe ascendant
    dessiner_cube_quaternion(q)
     
    plt.show()

  2. #2
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 7
    Par défaut
    J'ai finalement trouvé. J'avais fait une erreur en prenant les composantes tri-dimensionnelles de mon cube et en les transformant en quaternion à l'aide d'un axe imaginaire...

    Il faut bien sûr prendre que les composantes, et les laisser telles quelles pour faire la multiplication.
    Le seul problème est que ce ne sont pas des tuples à la base, mais c'est assez vite contourné avec une fonction qui les transforme en tuple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    def array_to_tuple(v):
        x = v[0]
        y = v[1]
        z = v[2]
        return x,y,z
     
    def dessiner_cube_quaternion(q):
        r = [-10, 10]
        for s, e in combinations(np.array(list(product(r,r,r))), 2):
            if np.sum(np.abs(s-e)) == r[1]-r[0]:
                s_rotated=qv_mult(q,array_to_tuple(s))
                e_rotated=qv_mult(q,array_to_tuple(e))
                ax.plot3D(*zip(s_rotated,e_rotated), color="b")
     
    theta=np.radians(45)
    q=axeangle_to_q((0,0,1),theta)
    dessiner_cube_quaternion(q)
    Nom : 45 uz.png
Affichages : 1237
Taille : 24,4 Ko

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. rotation avec des quaternions
    Par tiloup367 dans le forum Mathématiques
    Réponses: 2
    Dernier message: 09/11/2010, 13h17
  2. Orientation avec les quaternions
    Par Whyzix dans le forum Physique
    Réponses: 1
    Dernier message: 31/12/2009, 15h37
  3. Problème avec une caméra utilisant les quaternions
    Par Bakura dans le forum Développement 2D, 3D et Jeux
    Réponses: 17
    Dernier message: 15/12/2007, 19h26
  4. [Moteur3D perso]Probleme avec les Quaternions
    Par Ramboofp dans le forum Moteurs 3D
    Réponses: 2
    Dernier message: 08/09/2007, 22h40
  5. [ANIMATION] problème avec les rotations
    Par backfire dans le forum DirectX
    Réponses: 3
    Dernier message: 22/02/2007, 21h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo