Aller au contenu

Angles d'Euler


(gile)

Messages recommandés

Salut,

 

La demande m'en a été faite par message privé et, comme à mon habitude, j'ai conseillé au demandeur de démarrer un sujet sur CADxp afin que toute la communauté bénéficie de la discussion.

Comme il n'y a toujours aucune demande à ce propos et que je mes suis penché sur la question, je démarre moi-même le sujet.

 

La demande concernait un équivalent en LISP des réponses données en C# dans cette discussion.

 

Rapidement pour le non-anglophones, il s'agissait de retrouver les angles d'Euler (lacet, tangage, roulis ou yaw, pitch, roll en anglais).

En faisant quelques recherche, j'ai trouvé que la demande concernait une forme particulière des angles d'Euler appelés aussi angles de Tait Bryan qui utilisait d'autres axes de rotation que la forme classique (appelée proper Euler par les anglo-saxons).

 

Pour faire court, les angles de Tait Bryan reflètent des rotations successives sur les axes X, Y puis Z et les angles d'Euler "propres" des rotations successives sur les axes Z, puis X, puis à nouveau Z. On peut noter que dans AutoCAD, la première rotation sur Z correspond à la rotation du bloc et les rotations sur X puis Z, au changement de plan.

 

;; gc:butLast
;; Retourne la liste privée du dernier élément
;;
;; Argument
;; l : une liste
(defun gc:butLast (l) (reverse (cdr (reverse l))))

;; gc:GetNormal
;; Retourne le vecteur unitaire d'un vecteur
;;
;; Argument
;; v : un vecteur
(defun gc:GetNormal (v)
 ((lambda (l)
    (if (/= 0 l)
      (mapcar (function (lambda (x) (/ x l))) v)
    )
  )
   (distance '(0. 0. 0.) v)
 )
)

;; TRP
;; Transpose une matrice -Doug Wilson-
;;
;; Argument
;; m : une matrice
(defun trp (m) (apply 'mapcar (cons 'list m)))

;; gc:acos
;; Retourne l'arc cosinus du nombre
;;
;; Argument
;; n : le cosinus de l'angle
(defun gc:acos (n)
 (cond
   ((equal n 1. 1e-9) 0.)
   ((equal n -1. 1e-9) pi)
   ((< -1. n 1.)
    (atan (sqrt (- 1. (expt n 2))) n)
   )
 )
)

;; gc:asin
;; Retourne l'arc sinus du nombre
;;
;; Argument
;; n : le sinus de l'angle
(defun gc:asin (n)
 (cond
   ((equal n 1. 1e-9) (/ pi 2.))
   ((equal n -1. 1e-9) (/ pi -2.))
   ((< -1. n 1.)
    (atan n (sqrt (- 1 (expt n 2))))
   )
 )
)

;; ProperEuler
;; Renvoie une liste contenant les angles d'Euler en radians (précession, nutation et rotation propre)
;;
;; Argument
;; m : une matrice de transformation telle que celle renvoyée par nentsel ou nentselp
(defun ProperEuler (m / theta psi phi)
   (setq m (mapcar
               'gc:GetNormal
               (if (= (length (car m)) 3)
                   (mapcar 'gc:butlast (trp m))
                   (gc:butlast (mapcar 'gc:butlast m))
               )
           )
   )
   (setq theta (gc:acos (caddr (caddr m))))
   (if (< (abs theta) 1e-7)
       (setq theta 0.
             psi   0.
             phi   (atan (car (cadr m)) (cadr (cadr m)))
       )
       (setq psi (atan (caddr (car m)) (- (caddr (cadr m))))
             phi (atan (car (caddr m)) (cadr (caddr m)))
       )
   )
   (list psi theta phi)
)

;; TaitBryan
;; Renvoie une liste contenant les angles de Tait-Bryan en radians (lacet, tangage, roulis ou yaw, pitch, roll)
;;
;; Argument
;; m : une matrice de transformation telle que celle renvoyée par nentsel ou nentselp
(defun TaitBryan (m / a b c)
   (setq m (mapcar
               'gc:GetNormal
               (if (= (length (car m)) 3)
                   (mapcar 'gc:butlast (trp m))
                   (gc:butlast (mapcar 'gc:butlast m))
               )
           )
   )
   (setq b (- (gc:asin (car (caddr m)))))
   (cond
       ((< (abs (- b (* pi 0.5))) 1e-7)
        (setq b (* pi 0.5)
              a   (atan (caddr (cadr m)) (cadr (cadr m)))
              c  0.
        )
       )
       ((< (abs (+ b (* pi 0.5))) 1e-7)
        (setq b (* pi -0.5)
              a   (atan (- (caddr (cadr m))) (cadr (cadr m)))
              c  0.
        )
       )
       (T
        (setq a   (atan (car (cadr m)) (car (car m)))
              c  (atan (cadr (caddr m))  (caddr (caddr m)))
        )
       )
   )
   (list a b c)
)

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Coucou

 

Quand (gile) se penche sur une question cette dernière tremble car elle sait qu'elle est en train de vivre ses derniers instants en tant que "question".

La magie de (gile) opère pour la transformer en réponse.

C'est un "Harry Potter" de la programmation sur AutoCAD.

 

J'aimerais lui exprimer mon admiration et mon respect au travers de ce message car je sais indubitablement qu'il n'y a rien de "magique", c'est de l'intelligence et du travail, et beaucoup des deux.

 

Sincèrement.

Lien vers le commentaire
Partager sur d’autres sites

Hello

 

+1 avec le Vieux Hibou Grincheux Maléfique Funeste etc...

 

Un seul mot: MAGIC Gilles en action !

 

Lacet, Tangage, Roulis, je vois à peu près !

Question: SVP plus concrètement cela sert à quoi ??

 

Humour: Gilles "attaque" l architecture navale et le Design de Coques de bateaux (Domaine particulièrement complexe) ?!

 

Bye, lecrabe "triste"

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Désolé je n'ai pas eu le temps de faire la demande car j'ai eu des soucis pour m'inscrire sur CADxp.

Merci pour la réponse, mais je n'ai pas réussi à utiliser les différentes routines.

 

En fait je cherche à retrouver les angles d'Euler et le point d’insertion d'un block ayant subi des rotations selon x, y et z.

 

J'ai rajouté le code suivant pour sélectionner un block et récupérer la matrice avec nentsel:

(defun c:euler ()

(setq m (nentsel "Choisir un block"))

(ProperEuler m)

)

 

Mais la routine plante dans "(defun ProperEuler (m).....)" au niveau de (length (car m))

 

Merci

 

IFJ

Lien vers le commentaire
Partager sur d’autres sites

Un exemple de commande qui affiche les résultats en ligne de commande dans les unités angulaires courantes.

 

(defun c:EULERANGLES (/ bloc matrice precession nutation lacet tangage roulis)
   (while
       (not
           (and
               (setq bloc (nentsel "\nSélectionnez une entité du bloc: "))
               (= (length bloc) 4)
           )
       )
   )
   (setq matrice (caddr bloc))
   (mapcar '(lambda (s v) (prompt (strcat "\n" s ": " (angtos v))))
           '("precession" "nutation" "rotation")
           (ProperEuler matrice))
   (mapcar '(lambda (s v) (prompt (strcat "\n" s ": " (angtos v))))
           '("lacet" "tangage" "roulis")
           (TaitBryan matrice))
   (princ)
)

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Merci beaucoup pour votre réponse rapide, effectivement votre routine marche.

Je vais prendre le temps de bien comprendre l'ensemble du code.

 

En fait j’insère des block dans AutoCAD à partir d'un fichier texte ou j'ai les points d'insertion et les angles de rotation en x, y, et z.

Je réarrange les block et doit les réexporter dans le même format texte.

 

A l'importation des block, AutoCAD transforme les angles de rotations en matrice de rotation, d'où ma question pour retrouver les angles d'Euler à partir de la matrice de rotation.

 

J'ai essayé votre routine en important et exportant un block sans rien changer pour voir si je retrouve les angles.

 

Les chiffres ne sont pas les mêmes, mais c'set peut-être une question de modulo ou sens, je reviendrai vers vous si je ne trouve pas la solution.

 

Merci encore et à bientôt.

 

IFJ

Lien vers le commentaire
Partager sur d’autres sites

Attention, l'ordre dans lequel les rotations sont effectué importe. Des rotations successives sur X, puis Y, puis Z ne donnent pas le me^me résultat que des rotations sur Z, puis Y, puis X.

 

La routine TaitBryan renvoie la liste des angles des rotations sur Z, Y et X d'un bloc qui a subit des rotations successives sur X, puis Y, puis Z.

 

La routine ProperEuler renvoie la liste des angles des rotations sur Z, X et Z d'un bloc qui a subit des rotations successives sur Z, puis X, puis Z. La dernière valeur retournée correspond à la première rotation sur Z, c'est la valeur de la propriété Rotation dans AutoCAD.

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité