Aller au contenu

Messages recommandés

Posté(e)

Bonjour à tous,

 

Est-il possible, à partir d'un lisp, de créer des points type nodal sur des blocs tels des plaques électriques ?

Les nodals doivent en fait s'insérer sur les 3 blocs points topo qui permettent d'insérer les plaques avec une échelle en X et en Y et une orientation.

 

Il suffit, je pense, de trouver les blocs points topo (avec attribut) proches du bloc par 3 point insérer dans le dessin puis d'insérer des nodals classiques autocad sur ces mêmes blocs points origines.

 

De plus, est il possible à partir d'un bloc par 3 points d'insérer un nodal simple mais au centre du bloc en question ? (un point au centre de gravité du bloc en fait)

 

Merci par avance de votre aide.

John.

 

Posté(e)

J'ai essayé un petit lisp que j'ai fait avec une fonction de Patrick RBL qui permet de remettre le point d'insertion d'un bloc au centre de celui-ci mais le bloc change de place. C'est pas bon et je n'ai pas assez de connaissance en vlisp pour adapter la fonction rbl à mes besoins.

 

 (defun c:cenblk (/ sel i pti x ent_b bl)
(if (not (tblsearch "LAYER" "semis"))
(command "_layer" "_N" "semis" "_CO" "7" "semis" ""))
(setvar "CLAYER" "semis")
(setvar "PDMODE" 3)
(setvar "PDSIZE" 0.0625)
(setq pti '(0.0 0.0 0.0))
(setq sel (ssget "X" (list (cons 0 "INSERT") (cons 8 "plaques"))))
(command "_copy" sel "" pti pti "")
(command "chprop" sel "" "ca" "semis" "")
(setq sel (ssget "X" (list (cons 0 "INSERT") (cons 8 "semis"))))

(setq x 0)
(if sel (progn
(repeat (sslength sel)
(setq ent_b (ssname sel x))
(command "_point" (trans (cdr (assoc 10 (entget ent_b)))  ent_b 1 ))
(setq x (+ x 1))
)
)
)
(setq sel (ssget "X" (list (cons 0 "INSERT") (cons 8 "semis"))))
(command "_erase" sel "")
(prin1)
)





(defun rbl (bl / dec_x dec_y ent ents mip map modif_ent)
 (vl-load-com)
 (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))
 (setq bl (tblnext "block" t))
 (while bl
   (if (/= (logand (cdr (assoc 70 bl)) 16) 16)
     (progn
       (setq Ent (vla-insertblock (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) (vlax-3d-point '(0.0 0.0 0.0)) (cdr (assoc 2 bl)) 1 1 1 0))
       (vla-getboundingbox Ent 'Mip 'Map)
       (setq Dec_x (/ (+ (car  (vlax-safearray->list Mip)) (car  (vlax-safearray->list Map))) 2)
             Dec_y (/ (+ (cadr (vlax-safearray->list Mip)) (cadr (vlax-safearray->list Map))) 2)
             Ents (vlax-safearray->list (vlax-variant-value (vla-explode Ent))))
       (vla-delete Ent)
       (entmake (list (cons 0 "block")
                      (cons 2 (cdr (assoc 2 bl)))
                      (cons 70 64)
                      (cons 10 '(0.0 0.0 0.0))))
       (foreach Ent Ents
         (vla-move Ent (vlax-3d-point (list Dec_x Dec_y 0.0)) (vlax-3d-point '(0.0 0.0 0.0)))
         (setq Modif_Ent (entget (vlax-vla-object->ename Ent))
               Modif_Ent (vl-remove (assoc  -1 Modif_Ent) Modif_Ent)
               Modif_Ent (vl-remove (assoc   5 Modif_Ent) Modif_Ent)
               Modif_Ent (vl-remove (assoc 330 Modif_Ent) Modif_Ent))
         (entmake Modif_Ent)
         (vla-delete Ent)
       )
       (entmake '((0 . "endblk")))
     )
   )
   (setq bl (tblnext "block"))
 )
 (vla-regen (vla-get-activedocument (vlax-get-acad-object)) acActiveViewport)
 (vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))
 (princ)
)

 

Merci par avance de votre aide.

John.

Posté(e)

Bonjour

 

tu n'es pas clair dans ta question et tu es exigeant, en plus.

on va t'aider, t'inqiète pas, mais fais un effort d'explications.

 

tout d'abord, pourquoi mettre un Point sur un bloc Point Topo ?

pas compris :(

 

ensuite tu parles de CENTRE d'un bloc,

à part le cercle qui a un centre les autres formes je ne vois pas

le centroïd sans doute

dans ce cas fais une recherche sur Cadxp une réponse en ce sens vient d'être publiée.

 

si tu n'y arrives toujours pas, il va falloir qu'on échange un fichier exemple

ou que tu mettes une image de ton souhait.

 

amicalement

Posté(e)

Je dois mettre un point type nodal au centre de mes blocs par 3 points pour répondre à une exigeance d'un client.

 

Il n'y a pas de probleme avec les blocs levés par un point mais par 3 points, je ne sais pas comment faire. Voilà tout. J'ai essayé par conséquent d'utiliser la fonction de Patrick avec le code ci-dessus mais le bloc change de place.

 

Merci par avance de ton aide.

John

Posté(e)

coucou

 

je vais une dernière fois te demander d'expliquer

 

tu veux quoi ?

 

je ne sais pas ce qu'est un point type nodal, désolé

c'est un point Autocad ou un bloc composé d'un Point Autocad ?

 

mettre un Point à l'intersection des diagonales d'un rectangle,

ce rectangle étant un bloc, c'est cà ?

 

à bientôt sans doute ...

 

amicalement

 

Posté(e)

Un point nodal est un point Autocad classique et non pas un bloc style point topo qui comprend matricule et altitude. Je ne vais pas mettre un bloc point par dessus un autre bloc. Ca n'a pas de sens.

UN POINT SIMPLE AUTOCAD C TOUT

 

Et, seulement un point au centre de gravité d'un bloc formé par 3 points levés sur le terrain d'où est calculé une echelle en x et en y.

 

J'espère t'avoir fourni une explication claire cette fois.

John.

Posté(e)

coucou

 

il me semble au ton que tu emploies que tu t'irrites

mais ce n'est vraiment pas la peine :(

 

il nous faut savoir des choses si tu ne veux pas envoyer de fichier ou coller d'image.

 

quel est le point d'insertion de ton bloc rectangulaire ?

est ce un point de la périphérie ou bien est ce déjà le centre de gravité ?

 

comment le bloc est il mis à l'échelle avec les points topo ?

sachant que le levé ne définit jamais une vraie perpendiculaire

 

dans un premier temps, tu peux essayer de redefinir ton bloc

en insérant déjà un point Autocad au centre voulu,

 

comme çà, le point est d'ores et déjà inséré,

ce sera bien plus simple à le retrouver par le lisp

pour utiliser ses coordonnées pour y dessiner un point Autocad.

 

une autre solution, par exemple :

tu peux toujours décomposer tes blocs sur un calque temporaire

transformer tes rectangles en régions,

et regarder ce que j'ai répondu pour les centres de gravité.

 

le tout se fera en quelques clics...

 

je te mets le lien, pour te prouver, si besoin est, ma bonne volonté. :)

 

Cliquer ICI

 

ami calmant

 

 

 

 

Posté(e)

Ne t'inquiètes pas, je ne m'énerve pas, je me répète un peu mais c'est pour que me faire comprendre, c'est tout. Pas de prob, no souci.

 

En effet, je pensais décomposer le bloc, transformer les rectangles en régions car le centre de gravité est une des propriétés de l'entité région mais comment effacer les entités des blocs qui ne servent à rien???

 

C'est pour cela, je pense qu'il est plus simple le modifier la fonction de Patrick rbl pour remettre le point d'insertion du bloc au centre de celui-ci sans changer la position géométrique de ce bloc.

 

Ou alors de repérer les blocs points topo qui définissent le bloc par 3 point, de calculer le barycentre de ces points puis d'insérer un point Autocad classique en question ???

 

Mais là, je bloque sérieusement.

Merci par avance de votre aide.

John.

Posté(e)

Salut,

 

Si j'ai bien compris (et ça, c'est pas sûr...), on a un bloc contenant 3 points inséré plusieurs fois dans le dessin avec des échelles X Y et des rotations différentes, et il s'agirait de placer un point au centre de gravité (CDG) de chacun de ces triangles.

 

Une méthode consisterait à trouver le vecteur du point de base au CDG de ces trois points dans un bloc aux échelles égales à 1 et rotation = 0.

Les coordonnées de ce vecteurs sont celles du CDG dans la définition du bloc, on peut donc calculer ce vecteur à partir du nom du bloc :

 

;; 3PointsBlocCentroid
;; Retourne le vecteur du point de base au centroid des 3 points
;; contenus dans la définition de bloc

(defun 3PointsBlocCentroid (name / bloc ent elst ptlst)
 (if (setq bloc (tblsearch "BLOCK" name))
   (progn
     (setq ent (cdr (assoc -2 bloc)))
     (while (and ent (not pt3))
(setq elst (entget ent))
(if (= (cdr (assoc 0 elst)) "POINT")
  (if (null pt1)
    (setq pt1 (cdr (assoc 10 elst)))
    (if	(null pt2)
      (setq pt2 (cdr (assoc 10 elst)))
      (setq pt3 (cdr (assoc 10 elst)))
    )
  )
)
(setq ent (entnext ent))
     )
   )
 )
 (if pt3
   (mapcar '(lambda (x1 x2 x3) (/ (+ x1 x2 x3) 3.0))
    pt1
    pt2
    pt3
   )
 )
)

 

Puis si pour chaque référence de bloc on récupère les échelles et la rotation, on pourra, avec un peu de calcul matriciel, appliquer ces échelles et cette rotation au vecteur.

Il suffira ensuite d'ajouter au point d'insertion de la référence (déplacement).

 

;; ScaleRotateVector
;; Applique des échelles en X, Y et Z et une rotation à un vecteur

(defun ScaleRotateVector (vec xscl yscl zscl rot / mat)
 (mxv
   (mxm
     (list (list (cos rot) (- (sin rot)) 0.)
    (list (sin rot) (cos rot) 0.)
    '(0. 0. 1.)
     )
     (list (list xscl 0. 0.)
    (list 0. yscl 0.)
    (list 0. 0. zscl)
     )
   )
   vec
 )
)

;; VXV
;; Retourne le produit scalaire (réel) de deux vecteurs
;;
;; Arguments : deux vecteurs

(defun vxv (v1 v2) (apply '+ (mapcar '* v1 v2)))

;; TRP
;; transpose une matrice -Doug Wilson-
;;
;; Argument : une matrice

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

;; MXV
;; Applique une matrice de transformation à un vecteur -Vladimir Nesterovsky-
;;
;; Arguments : une matrice et un vecteur

(defun mxv (m v)
 (mapcar (function (lambda (r) (vxv r v))) m)
)

;; MXM
;; Multiplie (combine) deux matrices -Vladimir Nesterovsky-
;;
;; Arguments : deux matrices

(defun mxm (m q)
 (mapcar (function (lambda (r) (mxv (trp q) r))) m)
)

 

Une commande.

L'utilisateur entre le nom du bloc et si la définition contient bien 3 points, place un point sur le CDG des 3 points de toutes les références insérées.

 

(defun c:test (/ name vec ss n ent elst)
 (if (setq name (getstring "\nNom du bloc: "))
   (if	(setq vec (3PointsBlocCentroid name))
     (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 name))))
(repeat	(setq n (sslength ss))
  (setq elst (entget (ssname ss (setq n (1- n)))))
  (entmake
    (list
      '(0 . "POINT")
      (cons 10
	    (mapcar '+
		    (cdr (assoc 10 elst))
		    (ScaleRotateVector
		      vec
		      (cdr (assoc 41 elst))
		      (cdr (assoc 42 elst))
		      (cdr (assoc 43 elst))
		      (cdr (assoc 50 elst))
		    )
	    )
      )
    )
  )
)
     )
     (princ
(strcat	"\nLe bloc \""
	name
	"\" n'est pas un bloc 3 points ou est absent du dessin."
)
     )
   )
 )
 (princ)
)

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

Posté(e)

Je crois que je comprends encore moins !

On parle de rectangle et de 3 points !

 

C'est pour cela, je pense qu'il est plus simple le modifier la fonction de Patrick rbl pour remettre le point d'insertion du bloc au centre de celui-ci sans changer la position géométrique de ce bloc

 

Le LISP de Patrick_35 modifie les définitions de bloc.

Il suffirait, après que le bloc ait été redéfini, de déplacer toutes les références de bloc avec le vecteur du point de base au CDG.

 

expression à placer après (entmake '((0 . "endblk"))) :

 

(if (ssget "_X" (list '(0 . "INSERT") (assoc 2 bl)))
 (progn
   (vlax-for ref (setq	ss (vla-get-ActiveSelectionSet
		     (vla-get-ActiveDocument
		       (vlax-get-acad-object)
		     )
		   )
	  )
     (vla-move	Ent
	(vlax-3d-point '(0.0 0.0 0.0))
	(vlax-3d-point (list Dec_x Dec_y 0.0))
     )
   )
   (vla-delete ss)
 )
)

 

ATTENTION, le LISP de Patrick_35 agit sur toute la collection de blocs du dessin. Il faut changer un peu le code pour que les changements n'affectent qu'une définition (tblsearch au lieu de tblnext).

 

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

Posté(e)

Bonjour Gile,

 

Le principe est plus difficile à expliquer qu'à faire.

Il n'y a pas de questions de rectangles.

En topo, certains objets comme des plaques ou des chambres edf gdf telecom sont levés par 3 points dans le sens horaire ou anti horaire selon la codification adopté par le géomètre.

 

En levant un objet par 3 point, Autocad insère le bloc avec comme point d'insertion le premier de ces points puis utilise les second et troisième point pour définir une orientation et une échelle en x et en y. Jusque là, pas de probleme je pense.

 

Le but de la manip est d'insérer un point nodal classique Autocad au centre du bloc.

Ce centre peut être défini par le centre de gravité des 3 points levés sur le terrain mais à ce moment, il faut que les points soient levés exactement perpendiculairement sur le terrain, ce qui est rarement le cas. On observe toujours des petits décalages de quelques mm ou cm entre les extremités du bloc et les points levés.

 

J'ai essayé les deux méthodes que tu as préconisé.

Pour la seconde, j'ai le retour suivant ; erreur: fonction incorrecte: 0, j'ai inséré ton code comme indiqué, et en vlisp je bloque pour trouver l'erreur dans la fonction.

 

Pour la première, elle insère le point au centre de gravité des 3 points mais pas au centre du bloc.

 

La méthode serait de ;

- sélectionner le bloc par 3 points

- déterminer l'emprise du bloc avec une région si possible

- insérer le point au centre de gravité de la région

- effacer le solide région

 

Je ne sais pas par contre si c'est possible de déterminer l'emprise d'un bloc avec une région mais ce serait à mon avis la solution la plus simple et la plus rapide.

 

La fonction de Patrick est bien mais je ne sais pas comment la modifier simplement.

En espérant avoir été assez explicité.

Merci par avance de votre aide.

John

Posté(e)

C'est bon j'ai pu m'en sortir avec ton code Gile

mais j'ai du le remanier et je fais le traitement un bloc après l'autre.

UN peu long mais ca se fait bien quand même.

 

John.

  • 1 mois après...
Posté(e)

Bonjour à tous,

 

J'ai peut être trouver une solution un peu plus simple pour déterminer les coordonnées des 3 points d'insertions d'un bloc par 3 points à partir des valeurs d"échelles en x et en y puis de l'angle de rotation.

 

La seule question est :

 

Peut on récupérer dans une variable les valeurs de ces paramètres en utilisant le bout de code suivant :

 

(setq echx (cdr (assoc 41 (entget (ssname sel (setq i (1- i)))))))
(setq echy (cdr (assoc 42 (entget (ssname sel (setq i (1- i)))))))
(setq rotb (cdr (assoc 50 (entget (ssname sel (setq i (1- i)))))))

 

car apparemment j'ai le retour suivant lentityp nil

et je ne comprend pas pourquoi.

 

Voici le lisp en cours de construction.

 

(defun c:3tps (/ sel i pt1 pt2 pt2x pt2y pt2z pt3 pt3x pt3y pt3z angx angy echx echy rotb)
(vl-load-com)

(setvar "CMDECHO" 0)
(setvar "AUPREC" 4)
(setvar "LUPREC" 4)


(setvar "PDMODE" 3)
(setvar "PDSIZE" 0.0625)

(setq sel (ssget "X" (list (cons 0 "INSERT") (cons 8 "plaque"))))

(repeat (setq i (sslength sel))

(setq pt1 (cdr (assoc 10 (entget (ssname sel (setq i (1- i)))))))

(setq echx (cdr (assoc 41 (entget (ssname sel (setq i (1- i)))))))
(setq echy (cdr (assoc 42 (entget (ssname sel (setq i (1- i)))))))
(setq rotb (cdr (assoc 50 (entget (ssname sel (setq i (1- i)))))))

(setq angx (/ (* (- 100 rotb) 200) 180))
(setq angy (- 100 angx))

(setq pt2x (+ (car pt1) (* echx (sin (/ (* pi angx) 200)))))
(setq pt2y (+ (cadr pt1) (* echx (cos (/ (* pi angx) 200)))))
(setq pt2z (caddr pt1))

(setq pt2 (list pt2x pt2y pt2z))

(setq pt3x (+ (car pt2) (* echy (sin (/ (* pi (- 400 angy)) 200)))))
(setq pt3y (+ (cadr pt2) (* echy (cos (/ (* pi (- 400 angy)) 200)))))
(setq pt3z (caddr pt1))
 
(setq pt3 (list pt3x pt3y pt3z))
 
(command "_point" pt1 pt2 pt3)

)


(setvar "CMDECHO" 1)
(princ)
) 

 

Merci par avance de votre aide.

John.

Posté(e)

Peut on récupérer dans une variable les valeurs de ces paramètres en utilisant le bout de code suivant :

 

(setq echx (cdr (assoc 41 (entget (ssname sel (setq i (1- i)))))))
(setq echy (cdr (assoc 42 (entget (ssname sel (setq i (1- i)))))))
(setq rotb (cdr (assoc 50 (entget (ssname sel (setq i (1- i)))))))

 

car apparemment j'ai le retour suivant lentityp nil

et je ne comprend pas pourquoi.

 

C'est normal, tu décrémentes à chaque expression à l'intérieur du repeat...

Quand tu entres dans la boucle repeat

pt1 = point d'insertion de la dernière entité du jeu de sélection,

echx = échelle en X de l'avant dernière entité

echy = échelle en X de l'avant avant dernière entité

etc.

Donc très vite, tu arrives à i = -1 pour lequel (ssname sel ...) retourne nil.

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

Posté(e)

Bonjour Gile

 

J'ai essayé de prendre exemple de ton code en mettant

 

(setq elst (entget (ssname ss (setq n (1- n)))))

 

mais j'ai le retour suivant

 

; erreur: type d'argument incorrect: lselsetp nil

 

Et sérieux je ne vois pas l'erreur.

Merci de ton aide.

John

Posté(e)

Salut,

 

Comme quoi, pour apprendre le LISP, il ne suffit pas de copier des bouts de code, il faut les analyser pour pouvoir les adapter à ses besoins.

 

Utilise les fonctions de l'éditeur Visual LISP :

- pour accéder directement à l'aide des fonctions que tu ne connais pas ou pas bien

- pour évaluer des expressions et comprendre comment elles fonctionnent

- pour t'habituer aux messages d'erreur et connaitre leurs significations.

 

Par exemple :

; erreur: type d'argument incorrect: lselsetp nil veut dire que le jeu de sélection (selset) est nil. Il s'agit ici de la variable ss.

 

Prenons l'expression :

(setq elst (entget (ssname ss (setq n (1- n)))))

L'interpréteur LISP la parcourt dans le sens de lecture en évaluant les expressions qu'elle contient. Si une de ces expression en contient une autre, il doit évaluer d'abord celle-ci pour retourner le résultat à celle-là

- setq requiert comme arguments un symbole et une valeur à attribuer à ce symbole

- elst est le symbole, il n'est pas évalué (setq n'évalue pas le symbole)

- (entget (ssname ss (setq n (1- n)))) est la valeur, là il faut évaluer...

-- entget requiert comme argument un nom d'entité (ENAME)

-- (ssname ss (setq n (1- n))) là encore, il faut évaluer...

--- ssname requiert comme arguments un jeu de sélection et un indice

--- ss est évalué et doit contenir un jeu de sélection (sinon message d'erreur du type de celui que tu as eu)

--- (setq n (1- n)) là encore, évaluation...

---- setq idem plus haut

---- n pas évalué

---- (1- n) évaluation...

----- 1- requiert un nombre entier comme argument

----- n est évalué, si c'est bien un nombre entier, sa valeur est passée à la fonction 1- (exemple n = 4)

----- (1- n) retourne 3

---- (setq n 3) attribue 3 à la variable n et retourne 3

--- (ssname ss 3) retourne le nom d'entité de l'entité à l'indice 3 dans le jeu de sélection ss (exemple

-- (entget ) retourne la liste dxf de l'entité ((-1 . ) ...)

- (setq elst ((-1 . ) ...)) la liste est attribuée à la variable elst

 

L'évaluation de cette expression modifie les valeurs de 2 variables elst et n, utilisée dans une boucle, où n est initialisé avec le nombre d'élément contenus dans le jeu de sélection (setq n (sslength ss)).

Elle retourne à chaque itération la liste dxf de l'entité précédente puisque la valeur de n passe à n - 1.

 

Dans le code que tu donnes plus haut tu utilises dans la boucle repeat :

(setq pt1 (cdr (assoc 10 (entget (ssname sel (setq i (1- i)))))))
(setq echx (cdr (assoc 41 (entget (ssname sel (setq i (1- i)))))))
(setq echy (cdr (assoc 42 (entget (ssname sel (setq i (1- i)))))))
(setq rotb (cdr (assoc 50 (entget (ssname sel (setq i (1- i)))))))

Où chacune des expressions contient la même expression :

(entget (ssname sel (setq i (1- i))))

Dans laquelle i est décrémenté, donc à chaque fois ssname retourne une entité différente et entget une liste DXF différente.

Imagine un jeu de sélection contenant 3 entités, i est initialisé à 3.

(setq pt1 (cdr (assoc 10 (entget (ssname sel (setq i (1- i)))))))

attribue à i 3 - 1 = 2 et retourne le point d'insertion de l'entité à l'indice 2 dans le jeu de sélection (la troisième).

 

(setq echx (cdr (assoc 41 (entget (ssname sel (setq i (1- i)))))))

attribue à i 2 - 1 = 1 et retourne l'échelle en X de l'entité à l'indice 1 dans le jeu de sélection (la deuxième).

 

(setq echy (cdr (assoc 42 (entget (ssname sel (setq i (1- i)))))))

attribue à i 1 - 1 = 0 et retourne l'échelle en Y de l'entité à l'indice 0 dans le jeu de sélection (la première).

 

(setq rotb (cdr (assoc 50 (entget (ssname sel (setq i (1- i)))))))

attribue à i 0 - 1 = -1 or il ne peut pas y avoir d'entité à l'indice -1 dans un jeu de sélection, l'indice du premier élément est toujours 0.

 

(ssname sel -1) retourne l'erreur :

; erreur: type d'argument incorrect: lentityp nil

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

Posté(e)

Merci pour ces explications détaillées.

Ca marche maintenant mais j'ai préféré le while au lieu du repeat avec un setq i (+ i 1) à la fin de ma boucle.

 

Par contre, ca ne m'insère que le premier point au lieu des 3 comme prévu.

Un problème dans ma définition des points je pense.

Je vais voir ca dans le détail.

 

John.

Posté(e)

coucou

 

las de chercher à comprendre le pourquoi du comment

mais j'ai quand même envie d'apporter ma contribution

 

est-il possible de m'envoyer un fichier pour juger sur pièce

car j'ai regardé avec des blocs perso mais je ne sais pas si c'est le bon cas de figure.

 

je te fais un message privé tout de suite pour te donner mon adresse.

 

amicalement

Posté(e)

Bonjour,

 

Il semblerait que j'ai un souci d'angle pour finaliser ce lisp.

Je m'explique.

A partir des coordonnées du point d'insertion du bloc, de l'échelle en x et en y puis de l'angle de rotation, je calcule les coordonnées des deux autres points qui permettent de tracer mon bloc.

 

Je récupère la valeur de l'angle de rotation avec

 

 (setq rotb (cdr (assoc 50 entit)))

(setq angx (/ (* pi rotb) 180))
(setq angy (- (/ pi 2) angx))

 

puis je calcule un angx pour l'axe des x et un angy pour l'axe des y comme l'indique le lisp précédent.

 

Une question :

 

Quand j'ouvre un dxf avec le bloc notes et que je regarde les paramètres de mon bloc, l'angle de rotation est enregistré en degrés. Est ce une norme autocad ou bien peut on configurer les unités d'angles ?

 

Attention je ne parle pas des paramètres d'affichages dans la fenêtre propriétes ou dans le contrôle des unités car en les modifiant en grades par exemple, le dxf enregistré avec AutoCAD et ouvert avec bloc notes indique toujours un angle en degrés.

 

Merci par avance de votre aide.

John

Posté(e)

Salut,

 

Tout d'abord, dans AutoCAD seules les entrées en ligne de commande se font dans l'unité angulaire courante (variable AUNITS). À l'intérieur, tous ce qui concerne concerne les angles (calculs, stockage) se fait en radians.

En LISP c'est respecté :

- command (qui utilise la ligne de commande) requiert des angles exprimés dans l'unité courante.

- getangle et getorient acceptent une entrée utilisateur dans l'unité courante mais retournent toujours une valeur en radians

- angle retourne toujours une valeur en radians

- polar requiert l'argument angle exprimé en radians

- les angles dans les listes dxf sont aussi exprimés en radians

- l'expression LISP (getvar "angbase") retourne l'angle en radians alors que ANGBASE entré directement à la ligne de commande affiche et requiert l'angle exprimé en unités courantes.

 

(cdr (assoc 50 entit)) retourne l'angle de rotation du bloc ee radians, cet angle est mesuré par rapport à l'axe X du Système de Coordonnées Objet (SCO) du bloc (tant que le plan de construction du bloc est parallèle au plan XY du SCG le SCO est identique au SCG) dans le sens trigonométrique.

 

Donc, si comme il m'a semblé comprendre, tu travaille avec les paramètres des géomètres (ANGBASE = 100g et ANGDIR = 1) pour utiliser l'angle récupéré avec la fonction command, il faut non seulement le convertir en grades mais aussi intégrer ANGDIR et ANGBASE (je t'avais donné un exemple ici)

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

Posté(e)

Merci Giel pour ces infos.

Je préfère conserver l'angle en radians

 

J'ai fait donc

 

(setq angx rotb)
(setq angy (+ angx (/ pi 2))) 

 

En échangeant le sinus des cosinus car sens trigonométrique, le lisp marche bien testé avec n'importe quel bloc saisi par 3 points et pour n'importe quel valeur de rotation.

 

Merci encore de votre aide.

John.

Posté(e)

coucou

 

à la suite de tes explications par messages privés j'ai enfin compris, enfin je crois !

je ne vois pas l'utilité de mettre des points sur les points levés mais je ne suis pas juge

je te colle une image du programme

ce n'est pas par sadisme, mais si tu veux progresser il faut TAPER les lignes de code

le copier-coller ne fait pas grandir.

je te laisse appliquer les filtres qui vont bien et la transformation de SCU le cas échéant.

 

tu nous tiens au courant.

http://images.imagehotel.net/uehzbkw4g8.png

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é