Aller au contenu

Diviser/Mesurer 3D


Messages recommandés

Posté(e)

Suite à ce sujet et à mes récentes découvertes sur les matrices de transformation, j'ai essayer d'un peu mieux aboutir le LISP que j'y proposais.

 

Au delà du fait que la routine répare certains dysfonctionnements des commandes Diviser et Mesurer en 3D, elle répond à certains souhaits émis dans sujet cité.

 

La longueur de l'objet sélectionné s'affiche sur la ligne de commande.

Avec l'option bloc,

- le choix du bloc se fait dans une liste déroulante

- une option supplémentaire permet de choisir si le bloc est inséré par rapport au plan du SCU ou par rapport à celui de l'objet (SCO pour les objets 2D, plan défini par les dérivées première et seconde au point d'insertion pour les spline 3D, les hélices). Cette option n'est pas accessible pour les lignes et polylignes 3D (dérivée seconde = vecteur nul).

 

Nouvelle version de getblock :

- Possibilité de choisir un bloc non inséré dans le dessin à partir de la boite de dialogue standard d'AutoCAD

- Réparé un bug avec l'insertion de points sur les lignes et polylignes 3D (25/08/06 10h50)

- Pour lancer l'option "Bloc", taper ENTER, Espace ou clic droit à la place de "b" + ENTER

- Possibilité d'entrer le nom du bloc (25/08/06 21h20)

 

Version 1.1 (11/04/07)

- affiche par défaut le dernier bloc inséré (INSNAME)

 

Le fichier DCL à enregistrer sous getblock.dcl dans un dossier du chemin de recherche des fichiers de support.

 

getblock:dialog{
 label="Choisir un bloc";
 initial_focus="bl";
 :boxed_column{
   :row{
     :column{
       spacer;
       :text{
         label="Nom :";
         alignment=left;
       }
     }
     :column{
       :button{
         label="Parcourir...";
         key="wbl";
         alignment=right;
         fixed_width=true;
       }
       spacer;
     }
   }
   :edit_box{
     key="tp";
     edit_width=25;
   }
   :popup_list{
     key="bl";
     edit_width=25;
   }
   spacer;
 }
 ok_cancel;
}

 

Le LISP,les sous routines sont communes aux deux commandes DIV3D et MES3D

 

;;; DIV3D et MES3D - Gilles Chanteau - 25/08/06
;;;
;;; Fonctionnement similaire aux commandes DIVISER (_DIVIDE) et MESURER (_MEASURE)
;;; Les plus :
;;; - L'option "Bloc" permet l'insertion de bloc sur des objets "mesurables" quels que
;;;   soient le SCO de l'objet et le SCU courant.
;;; - Une option supplémentaire : "Plan de référence pour l'insertion du bloc ?"
;;;   permet de choisir si le bloc est inséré par rapport au plan XY du SCU courant
;;;   [scu] ou par rapport à l'objet [Objet].
;;; - Le choix du bloc se fait dans la liste déroulante d'une boite de dialogue.
;;; - La longueur de l'objet sélectionnée est affichée sur la ligne de commande.


;;; Getspace Retourne l'espace courant (Modèle ou Papier)

(defun getSpace	()
 (if (= (getvar "CVPORT") 1)
   (vla-get-PaperSpace
     (vla-get-ActiveDocument (vlax-get-acad-object))
   )
   (vla-get-ModelSpace
     (vla-get-ActiveDocument (vlax-get-acad-object))
   )
 )
)

;;; Getblock (version 1.1)
;;;  Retourne le nom du bloc entré ou choisi par l'utilisateur 
;;; dans une liste déroulante de la boite de dialogue ou depuis la boite
;;; de dialogue standard d'AutoCAD
;;; Argument : le titre (string) ou nil (défaut : "Choisir un bloc")

(defun getblock	(titre / bloc n lst what_next dcl_id nom)
 (while (setq bloc (tblnext "BLOCK" (not bloc)))
   (setq lst (cons (cdr (assoc 2 bloc)) lst)
   )
 )
 (setq	lst (acad_strlsort
      (vl-remove-if '(lambda (n) (= (substr n 1 1) "*")) lst)
    )
 )
 (setq dcl_id (load_dialog "Getblock.dcl"))
 (setq what_next 2)
 (while (>= what_next 2)
   (if	(not (new_dialog "getblock" dcl_id))
     (exit)
   )
   (start_list "bl")
   (mapcar 'add_list lst)
   (end_list)
   (if	titre
     (set_tile "box" titre)
   )
   (or
     (and
(setq n	(vl-position
	  (strcase (getvar "INSNAME"))
	  (mapcar 'strcase lst)
	)
)
(setq nom (nth n lst))
     )
     (setq nom	(car lst)
    n	0
     )
   )
   (set_tile "bl" (itoa n))
   (action_tile "bl" "(setq nom (nth (atoi $value) lst))")
   (action_tile "wbl" "(done_dialog 3)")
   (action_tile "tp" "(setq nom $value) (done_dialog 4)")
   (action_tile
     "accept"
     "(setq nom (nth (atoi (get_tile \"bl\")) lst)) (done_dialog 1)"
   )
   (setq what_next (start_dialog))
   (cond
     ((= what_next 3)
      (if (setq nom (getfiled "Sélectionner un fichier" "" "dwg" 0))
 (setq what_next 1)
 (setq what_next 2)
      )
     )
     ((= what_next 4)
      (cond
 ((not (read nom))
  (setq what_next 2)
 )
 ((tblsearch "BLOCK" nom)
  (setq what_next 1)
 )
 ((findfile (setq nom (strcat nom ".dwg")))
  (setq what_next 1)
 )
 (T
  (alert (strcat "Le fichier \"" nom "\" est introuvable."))
  (setq	nom nil
	what_next 2
  )
 )
      )
     )
     ((= what_next 0)
      (setq nom nil)
     )
   )
 )
 (unload_dialog dcl_id)
 nom
)

;;; V^V Retourne le produit vectoriel (vecteur) de deux vecteurs

(defun v^v (v1 v2)
 (if (inters '(0 0 0) v1 '(0 0 0) v2)
   (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
  (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
  (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
   )
 )
)

;;; NORM_3PTS retourne le vecteur normal du plan défini par 3 points

(defun norm_3pts (org xdir ydir / norm)
 (foreach v '(xdir ydir)
   (set v (mapcar '- (eval v) org))
 )
 (mapcar '(lambda (x) (/ x (distance '(0 0 0) norm)))
  (setq norm (v^v xdir ydir))
 )
)

;;; Transpose une matrice -Doug Wilson-

(defun trp (m)
 (apply 'mapcar (cons 'list m))
)

;;; Ang
(defun ang  (if (and (    ang
   (ang  )
)

;;; DivMesInsert Insère le bloc (ou le point) suivant les options choisies

(defun DivMesInsert (/ norm deriv2 ang mat ydir)
 (if (/= scu "Scu")
   (cond
     ((member (vla-get-ObjectName obj)
       '("AcDbArc"	     "AcDbCircle"
	 "AcDbEllipse"	     "AcDbPolyline"
	 "AcDb2dPolyline"
	)
      )
      (setq
 norm (vlax-safearray->list
	(vlax-variant-value (vla-get-Normal obj))
      )
      )
     )
     ((not (member (vla-get-ObjectName obj)
	    '("AcDbLine" "AcDb3dPolyline")
    )
      )
(setq
  deriv2
   (vlax-curve-getSecondDeriv
     obj
     ins_par
   )
)
(setq ang
       (ang	       )
)
(if
  (	   (setq norm (norm_3pts '(0 0 0) deriv1 deriv2))
   (setq norm (norm_3pts '(0 0 0) deriv2 deriv1))
)
     )
   )
 )
 (if nom
   (progn
     (if (= scu "Scu")
(progn
  (if (= algn "Non")
    (setq
      ang
       (angle '(0 0 0)
	      (trans (getvar "UCSXDIR") 0 ucszdir)
       )
    )
    (setq ang
	   (angle '(0 0 0) (trans deriv1 0 ucszdir))
    )
  )
  (setq
    mat	(mapcar
	  '(lambda (v) (trans v 0 ucszdir))
	  (list	(list (cos ang) (- (sin ang)) 0)
		(list (sin ang) (cos ang) 0)
		'(0 0 1)
	  )
	)
  )
)
(if (= algn "Non")
  (setq	ydir (norm_3pts '(0 0 0) norm (getvar "ucsxdir"))
	mat  (trp
	       (cons
		 (norm_3Pts '(0 0 0) ydir norm)
		 (cons
		   ydir
		   (cons norm mat)
		 )
	       )
	     )
  )
  (setq
    mat
     (trp
       (list (mapcar '(lambda (x)
			(/ x (distance '(0 0 0) deriv1))
		      )
		     deriv1
	     )
	     (norm_3pts '(0 0 0) norm deriv1)
	     norm
       )
     )
  )
)
     )
     (vla-TransformBy
(vla-InsertBlock
  (getspace)
  (vlax-3d-point '(0 0 0))
  nom
  1
  1
  1
  0
)
(vlax-tmatrix
  (append
    (mapcar
      '(lambda (v1 v2)
	 (append v1 (list v2))
       )
      mat
      ins_pt
    )
    (list '(0 0 0 1))
  )
)
     )
   (setvar "INSNAME" nom)
   )
   (vla-addPoint (getspace) (vlax-3d-point ins_pt))
 )
)

;;; Std_vl_err Redéfinition de *error*

(defun std_vl_err (msg)
 (if (= msg "Fonction annulée")
   (princ)
   (princ (strcat "\nErreur: " msg))
 )
 (vla-EndUndoMark
   (vla-get-ActiveDocument (vlax-get-acad-object))
 )
 (setq	*error*	m:err
m:err nil
 )
 (princ)
)

;;;******************************************************************;;;
;;; Div3D

(defun c:div3D (/	AcDoc	ucszdir	ent	obj	pick	long
	nb	nom	algn	scu	dist	ins_pt	ins_par
	deriv1
       )
 (vl-load-com)
 (setq	m:err	*error*
*error*	std_vl_err
 )
 (setq	AcDoc	(vla-get-ActiveDocument (vlax-get-acad-object))
ucszdir	(trans '(0 0 1) 1 0 T)
 )
 (sssetfirst nil nil)
 (if (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-getEntity
  (list	(vla-get-Utility AcDoc)
	'obj
	'pick
	"\nChoix de l'objet à diviser: "
  )
)
     )
   (prompt "*Incorrect*")
   (progn
     (if (vl-catch-all-error-p
    (vl-catch-all-apply 'vlax-curve-getEndParam (list obj))
  )
(prompt "\nL'objet ne peut pas être divisé.*Incorrect*")
(progn
  (setq	long (vlax-curve-getDistAtParam
	       obj
	       (vlax-curve-getEndParam obj)
	     )
  )
  (prompt (strcat "\nLongueur de l'objet: " (rtos long)))
  (while (not (> 3268 nb 1))
    (setq
      nb
       (getint "\nEntrez le nombre de segments ou : ")
    )
    (if	nb
      (if (not (> 3268 nb 1))
	(prompt
	  "\nNécessite un entier entre 2 et 32767, ou une option."
	)
      )
      (progn
	(setq nom (getblock nil))
	(if nom
	  (setq nb 2)
	  (setq nb 0)
	)
      )
    )
  )
  (if nom
    (progn
      (initget "Oui Non")
      (setq algn
	     (getkword
	       "\nAligner le bloc avec l'objet ? [Oui/Non] : "
	     )
	    nb 0
      )
      (if (not (member (vla-get-ObjectName obj)
		       '("AcDbLine" "AcDb3dPolyline")
	       )
	  )
	(progn
	  (initget "Objet Scu")
	  (setq	scu
		 (getkword
		   "\nPlan de référence pour l'insertion du bloc ? [Objet/Scu] : "
		 )
	  )
	)
	(setq scu "Scu")
      )
      (while (not (> 3268 nb 1))
	(setq nb (getint "\nEntrez le nombre de segments: "))
	(if (not (> 3268 nb 1))
	  (prompt
	    "\nNécessite un entier entre 2 et 32767."
	  )
	)
      )
    )
  )
  (setq dist (/ long nb))
  (vla-StartUndoMark AcDoc)
  (repeat (setq nb (1- nb))
    (setq ins_pt  (vlax-curve-getPointAtDist obj (* nb dist))
	  ins_par (vlax-curve-getParamAtDist obj (* nb dist))
	  deriv1  (vlax-curve-getFirstDeriv
		    obj
		    ins_par
		  )
    )
    (DivMesInsert)
    (setq nb (1- nb))
  )
  (if (vlax-curve-isClosed obj)
    (progn
      (setq ins_pt  (vlax-curve-getStartPoint obj)
	    ins_par (vlax-curve-getStartParam obj)
	    deriv1  (vlax-curve-getFirstDeriv
		      obj
		      ins_par
		    )
      )
      (DivMesInsert)
    )
  )
  (vla-EndUndoMark AcDoc)
)
     )
   )
 )
 (setq	*error*	m:err
m:err nil
 )
 (princ)
)

;;;******************************************************************;;;
;;; Mes3D

(defun c:mes3D
       (/ AcDoc	ucszdir	obj pick long dist nom algn scu	nb rest
	ins_pt deriv1)
 (vl-load-com)
 (setq	m:err	*error*
*error*	std_vl_err
 )
 (setq	AcDoc	(vla-get-ActiveDocument (vlax-get-acad-object))
ucszdir	(trans '(0 0 1) 1 0 T)
 )
 (sssetfirst nil nil)
 (if (vl-catch-all-error-p
(vl-catch-all-apply
  'vla-getEntity
  (list	(vla-get-Utility AcDoc)
	'obj
	'pick
	"\nChoix de l'objet à mesurer: "
  )
)
     )
   (prompt "*Incorrect*")
   (progn
     (if (vl-catch-all-error-p
    (vl-catch-all-apply 'vlax-curve-getEndParam (list obj))
  )
(prompt "\nL'objet ne peut pas être mesuré.*Incorrect*")
(progn
  (setq	pick (vlax-curve-getClosestPointToProjection
	       obj
	       (trans (vlax-SafeArray->list pick) 1 0)
	       (mapcar '-
		       (trans (getvar "viewdir") 1 0)
		       (trans '(0 0 0) 1 0)
	       )
	     )
	long (vlax-curve-getDistAtParam
	       obj
	       (vlax-curve-getEndParam obj)
	     )
  )
  (prompt (strcat "\nLongueur de l'objet: " (rtos long)))
  (while (and (not (numberp dist)) (not nom))
    (if	(not (setq dist
		    (getint
		      "\nSpécifiez la longueur du segment ou : "
		    )
	     )
	)
      (setq nom (getblock nil))
    )
  )
  (if nom
    (progn
      (initget "Oui Non")
      (setq algn
	     (getkword
	       "\nAligner le bloc avec l'objet ? [Oui/Non] : "
	     )
      )
      (if (not (member (vla-get-ObjectName obj)
		       '("AcDbLine" "AcDb3dPolyline")
	       )
	  )
	(progn
	  (initget "Objet Scu")
	  (setq	scu
		 (getkword
		   "\nPlan de référence pour l'insertion du bloc ? [Objet/Scu] : "
		 )
	  )
	)
	(setq scu "Scu")
      )
      (initget 7)
      (setq
	dist (getdist "\nSpécifiez la longueur du segment: ")
      )
    )
  )
  (if (	    (prompt "\nL'objet n'est pas assez long.")
    (progn
      (setq nb (fix (/ long dist)))
      (if
	(		 (setq rest (rem long dist))
	 (setq rest nil)
      )
      (vla-StartUndoMark AcDoc)
      (repeat nb
	(setq ins_pt (if rest
		       (vlax-curve-getPointAtDist
			 obj
			 (+ (* (1- nb) dist) rest)
		       )
		       (vlax-curve-getPointAtDist obj (* nb dist))
		     )
	      ins_par (if rest
		       (vlax-curve-getParamAtDist
			 obj
			 (+ (* (1- nb) dist) rest)
		       )
		       (vlax-curve-getParamAtDist obj (* nb dist))
		     )
	      deriv1 (vlax-curve-getFirstDeriv obj ins_par)
	)
	(DivMesInsert)
	(setq nb (1- nb))
      )
      (vla-EndUndoMark AcDoc)
    )
  )
)
     )
   )
 )
 (setq	*error*	m:err
m:err nil
 )
 (princ)
)

[Edité le 24/8/2006 par (gile)][Edité le 25/8/2006 par (gile)][Edité le 25/8/2006 par (gile)][Edité le 26/8/2006 par (gile)]

 

[Edité le 11/4/2007 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut (gile) ...

Une (petite) amélioration qui je suis sûr t'amuserais de faire ;) :

le choix du bloc à insérer n'est pas forcément déjà insérer dans le dessin, mais le choix peut se faire aussi par rapport à un répertoire de bibliothèque ....

 

.... je suis persuadé que tu n'es pas assez bon pour faire ça .... :P :P :P

(... ou comment jouer sur la fierté d'un gars pour demander un service sans en avoir l'air ...)

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut Bred,

 

Je pense que ça serait un excellent exercice pour toi. ;)

 

Tu pourrais ajouter un bouton dans la boite de dialogue de getblock qui lancerait la fonction (getfiled ...)

 

Jusqu'à quand veux tu que je te laisses chercher avant de donner une solution ?

 

[Edité le 24/8/2006 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

... touché !!! ...

j'avoue que je le chercherais volontier, mais j'ai vraiment du boulot par dessus la tête en ce moment...

de plus les boite de dialogue dcl sont de domaine de l'inconnu pour moi, et je passe tellement de temps à déjà décortiqué de "simple" lisp que je met les boites de dialogues dcl de côté...

 

Et puis c'est ta faute aussi, avec tous les cours/rxplications de lisp que tu donnes (fonctions récursives, matrices, ....) et les lisps que tu proposes (ainsi que Patrick_35) je suis balader dans tous les sens !!!

 

donc je ne pense vraiment pas m'y pencher de si-tôt...

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Alors je ne te fais pas attendre plus longtemps, je modifie getblock (lsp et dcl) dans le premier message.

 

Tu as raison, la gestion des boites de dialogue avec le DCL est plutôt ingrate, mais avec ObjectDCL ça devrait être plus facile.

 

Sinon, si ça peut te rassurer, je suis largué par certains codes de Patrick_35 (et d'autres).

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut (gile),

 

Suggestion :

Lors de la demande sur la ligne de commande

Entrez le nombre de segments ou [bloc]:

je comprends que tu ais voulu retrouver le même fonctionnement que la commande standard d'autocad, mais personnellement j'aime bien lorsqu'il y a des options à choisir d'avoir une option par "défaut en validation" , c'est à dire que ici, si tu valides sans rentrer de nombre de segment, il comprends que tu veux rentrer un nom de bloc...

 

je ferait :

 (if (equal nb nil)
(setq nb "Bloc"))

 

-----------------------------------------------------------

Demande :

N'y a t'il pas moyen, en plus de la posibilité d'aller chercher un fichiers que tu viens de rajouter, d'avoir une zone de texte "libre" où l'on taperait le nom d'un bloc existant (pas forcément dans la liste déroulante, donc déjà inséré) et en l'insérant ensuite avec (commande "-insert" ...) ou plûtot j'imagine que tu préfereras en vl du genre

  (vla-insertblock (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))		;
(vlax-3d-point (trans pt 1 0)) Nom 1 1 1						;
(angle '(0 0 0) (trans (getvar "UCSXDIR") 0 (trans '(0 0 1) 1 0 T))))

 

 

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut,

 

J'ai effectivement cherché à reproduire le fonctionnement des commandes originelles en ce qui concerne la saisie des données.

 

Mais comme je pense comme toi que c'est aussi une amélioration, je modifie le code, de toute façon, si l'utilisateur tapait Enter, espace ou faisait un clic droit par mégarde, l'option "Annuler" de la boite de dialogue getblock permet de ré-entrer dans la boucle pour spécifier le nombre de segments ou le la longueur des segments.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

J'avais oublié la deuxième remarque :

 

pas forcément dans la liste déroulante, donc déjà inséré

 

La liste déroulante contient tous les blocs de la collection qu'ils soient insérés ou non, donc je ne vois pas l'intérêt de la "case vide", la boite dialogue est faite pour éviter d'avoir à taper le nom du bloc.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut,

 

Si ils sont dans "la collection", cela veut dire qu'ils ont été déjà inséré à un moment ou à un autre... même si il ne sont pas "dans" le plan, il font parti de ce plans parceque insérer au moins une fois... (ou créé dedans)

si par contre, je veux insérer un bloc qui n'a jamais été inséré dans le plan (donc ne faisant pas partie de la collection), que ce bloc fait parti d'un des repertoire déclaré comme tel dans les fichiers supports (ces blocs je peux les appeler au clavier en faisant

 

-inserer

(nomdubloc)

(echx)

(echy)

(echz)

(rot)

 

(... en sachant que la plupart du temps les echelles sont à 1 ....)

 

Avec ta routine, si je veux insérer un bloc il faut qu'il soit dans la collection,ou que j'aille le chercher dans un repertoire (ce qui est trés utile si je ne me souvient plus du nom du bloc)...

 

mais si je connais le nom, et que je veux éviter de passer par l'étape de recherche dans les repertoires, je n'aurais qu'à taper le nom afin qu'il s'insert (il irait chercher le bloc dans mon fichier support de biblio...)

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Tu deviens un peu exigent...

... mais j'espère ne pas être désobligeant ... :exclam:

 

dans tout les cas merci !!!!

 

... mais je vais encore exagerer ....

 

afin de comprende ce lisp, en parrallèle de tes explication sur les vecteurs et matrices, pourrais-tu m'expliquer quel est la logique (et la raison) dans ton lisp pour que tu utilises :

 

 le produit vectoriel (vecteur) de deux vecteurs
puis
le vecteur normal du plan défini par 3 points

(en fait je pense que c'est pour définir le sens ET direction 3D, mais je ne suis pas certain de mon raisonnement)

 

et

 

 Transpose une matrice

 

... ça, malgré ton explication sur les matrices dans un précedent post ça me laisse "pantois"...

 

double merci

 

 

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

mais j'espère ne pas être désobligeant ...

 

Bien sûr que non, c'était une taquinerie ;)

 

À la première question, je n'utilise pas le produit vectoriel puis le vecteur normal du plan défini par trois points, c'est pour calculer le vecteur normal du plan que j'utilise le produit vectoriel.

En fait, j'ai décomposé la routine Norm_3pts en deux routines (pensant que c'était plus clair):

- v^v qui retourne le produit vectoriel de deux vecteurs, soit un vecteur perpendiculaire aux deux vecteurs passés comme argument.

- Norm_3pts dont les arguments sont des points, calcule les vecteurs du premier au deuxième et du premier au toisième point, puis appelle v^v pour trouver le vecteur normal à ces deux là et en calcule le vecteur unitaire (de norme 1).

 

À la deuxième question, la transposition d'une matrice (faire passer les rangées en colonnes) appliquée à une matrice de transformation permet de trouver la matrice de transformation inverse :

 

Matrice de rotation de 30° sur l'axe Z au point 0,0,0 :

((0.866025 -0.5 0.0 0.0) (0.5 0.866025 0.0 0.0) (0.0 0.0 1.0 0.0) (0 0 0 1)) ou :

 

0.866 -0.5 0.0 0.0

0.5 0.866 0.0 0.0

0.0 0.0 1.0 0.0

0.0 0.0 0.0 1.0

 

 

La fonction trp (transpose) appliquée à la matrice précédente :

 

(trp '((0.866025 -0.5 0.0 0.0) (0.5 0.866025 0.0 0.0) (0.0 0.0 1.0 0.0) (0 0 0 1)))

 

retourne :

((0.866025 0.5 0.0 0.0) (-0.5 0.866025 0.0 0.0) (0.0 0.0 1.0 0.0) (0 0 0 1)) ou :

 

0.866 0.5 0.0 0.0

-0.5 0.866 0.0 0.0

0.0 0.0 1.0 0.0

0.0 0.0 0.0 1.0

 

qui est la matrice de transformation inverse : rotation de 330° (ou -30°) sur l'axe Z au point 0,0,0

 

C'est là un des intérêts de l'utilisation des matrices.

 

[Edité le 26/8/2006 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Petite précision tout de même, dans l'exemple précédent, la transposition fonctionne sur la matrice complète parceque le déplacement (translation) est nul : vecteur 0,0,0 (trois premiers termes de la quatrième colonne) et peut être transposé avec la dernière rangée (0 0 0 1).

 

Si le déplacement n'est pas nul, pour trouver la matrice de transformation inverse, on transpose la matrice de dimension 3X3 constituée des 3 premiers termes des trois première rangées (échelle et rotations) et on applique cette nouvelle matrice au vecteur de déplacement (3 premiers termes de la dernière colonne) avec la fonction mxv (voir la fonction ReverseMatrix dans le sujet sur les matrices).

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

  • 2 semaines après...
Posté(e)

Suite à une suggestion de Bonuscad ici, en remplaçant la routine DivMesInsert donnée dans le premier message de ce sujet, par celle ci-dessous, on peut insérer le bloc "BLK_MEASURE_CURVE" avec attribut incrémenté.

 

Il faut toutefois que ce bloc existe dans la collection du dessin (ou gabarit) ou comme fichier .dwg (wbloc) pour pouvoir le récupérer avec la fonction getblock.

Pour créer ce bloc il suffit de lancer la routine make_blk_measure qui se trouve au début du lien donné ci dessus.

 

;;; DivMesInsert Insère le bloc (ou le point) suivant les options choisies

(defun DivMesInsert (/ norm deriv2 ang mat ydir ref)
 (if (/= scu "Scu")
   (cond
     ((member (vla-get-ObjectName obj)
       '("AcDbArc"	     "AcDbCircle"
	 "AcDbEllipse"	     "AcDbPolyline"
	 "AcDb2dPolyline"
	)
      )
      (setq
 norm (vlax-safearray->list
	(vlax-variant-value (vla-get-Normal obj))
      )
      )
     )
     ((not (member (vla-get-ObjectName obj)
	    '("AcDbLine" "AcDb3dPolyline")
    )
      )
      (setq
 deriv2
  (vlax-curve-getSecondDeriv
    obj
    ins_par
  )
      )
      (setq ang
      (ang	      )
      )
      (if
 (	  (setq norm (norm_3pts '(0 0 0) deriv1 deriv2))
  (setq norm (norm_3pts '(0 0 0) deriv2 deriv1))
      )
     )
   )
 )
 (if nom
   (progn
     (if (= scu "Scu")
(progn
  (if (= algn "Non")
    (setq
      ang
       (angle '(0 0 0)
	      (trans (getvar "UCSXDIR") 0 ucszdir)
       )
    )
    (setq ang
	   (angle '(0 0 0) (trans deriv1 0 ucszdir))
    )
  )
  (setq
    mat	(mapcar
	  '(lambda (v) (trans v 0 ucszdir))
	  (list	(list (cos ang) (- (sin ang)) 0)
		(list (sin ang) (cos ang) 0)
		'(0 0 1)
	  )
	)
  )
)
(if (= algn "Non")
  (setq	ydir (norm_3pts '(0 0 0) norm (getvar "ucsxdir"))
	mat  (trp
	       (cons
		 (norm_3Pts '(0 0 0) ydir norm)
		 (cons
		   ydir
		   (cons norm mat)
		 )
	       )
	     )
  )
  (setq
    mat
     (trp
       (list (mapcar '(lambda (x)
			(/ x (distance '(0 0 0) deriv1))
		      )
		     deriv1
	     )
	     (norm_3pts '(0 0 0) norm deriv1)
	     norm
       )
     )
  )
)
     )
     (setq ref
     (vla-InsertBlock
       (getspace)
       (vlax-3d-point '(0 0 0))
       nom
       1
       1
       1
       0
     )
     )
     (if (= nom "BLK_MEASURE_CURVE")
(progn
  (vla-put-TextString
    (car (vlax-invoke ref 'getAttributes))
    (if	rest
      (rtos (- long (vlax-curve-getDistAtPoint obj ins_pt)))
      (rtos (vlax-curve-getDistAtPoint obj ins_pt))
    )
  )
  (vla-ScaleEntity
    (car (vlax-invoke ref 'getAttributes))
    (vlax-3d-point '(0 0 0))
    (* 0.1 dist)
  )
)
     )
     (vla-TransformBy
ref
(vlax-tmatrix
  (append
    (mapcar
      '(lambda (v1 v2)
	 (append v1 (list v2))
       )
      mat
      ins_pt
    )
    (list '(0 0 0 1))
  )
)
     )
   )
   (vla-addPoint (getspace) (vlax-3d-point ins_pt))
 )
) 

 

[Edité le 7/9/2006 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

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é