Aller au contenu

liste de points (polyligne)


Messages recommandés

Posté(e)

Bonjour,

 

Je bosse sur une routine dans laquelle il me faudrait pouvoir retrouver les coordonnées des différents point d'une polyligne en cliquant simplement sur la polyligne. Ce que je n'arrive pas à comprendre, c'est que l'indice des différents points est toujours le même, soit "10". Existe-t'il donc une fonction pour ressortir ces différents points dans une liste?

 

Bien à Vous

Denis

Posté(e)

Salut,

 

Il n'existe pas de fonction LISP native pour faire ça.

Mais c'est un classique, plusieurs routines (parfois très anciennes) permettent de récupérer toutes les entrées d'un même code dans une liste d'association.

Souvent les routines qui font ça sont nommées massoc pour multiple assoc.

Elles s'utilisent comme assoc mais au lieu de retourner la première entrée, elle retournent la liste de toutes les valeurs pour la clé spécifiée.

 

Ci-dessous, quelques implémentations de massoc qui retournent la liste des valeurs.

(massoc 10 (entget (car (entsel "\nSélectionnez une polyligne: "))))

Retourne la liste des points 2d (coordonnées SCO) des sommets de la polyligne sélectionnée.

 

D'après les test que j'ai fait, c'est la dernière (récursive) la plus rapide.

 

;; foreach
(defun massoc (key alst / ret)
 (foreach p alst
   (if	(= (car p) key)
     (setq ret (cons (cdr p) ret))
   )
 )
 (reverse ret)
)

;; while
(defun massoc (key alst / ret)
 (while alst
   (if	(= (caar alst) key)
     (setq ret (cons (cdar alst) ret))
   )
   (setq alst (cdr alst))
 )
 (reverse ret)
)

;; vl-remove-if-not
(defun massoc (key alst)
 (mapcar 'cdr
   (vl-remove-if-not
     '(lambda (x)
        (= (car x) key)
      )
     alst
   )
 )
)

;; append + mapcar
(defun massoc (key alst)
 (apply 'append
 (mapcar '(lambda (x)
	    (if	(= (car x) key)
	      (list (cdr x))
	    )
	  )
	 alst
 )
 )
)

;; repeat
(defun massoc (key alst / ret)
 (repeat (length alst)
   (if	(= (caar alst) key)
     (setq ret (cons (cdar alst) ret))
   )
   (setq alst (cdr alst))
 )
 (reverse ret)
)

;; récursive
(defun massoc (key alst)
 (if (setq alst (member (assoc key alst) alst))
   (cons (cdar alst) (massoc key (cdr alst)))
 )
)

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

Posté(e)

Ok, c'est bien ce que je cherchais. Merci!

 

Le problème maintenant c'est que je ne sais pas à quelles extrémités s'apparentent ces points. Il me faudrait savoir laquelle des informations est un coin supérieur droit, inférieur gauche etc... Le plus facile ne serait pas de décomposer/recomposer, du coup?

Posté(e)
Le problème maintenant c'est que je ne sais pas à quelles extrémités s'apparentent ces points.

 

Ce sont les points dans l'ordre de la saisie ou dans l'ordre provoqué par tel ou tel processus à l'origine de la création.

"Coin supérieur droit " n'a aucune signification réelle dans une liste de points sur polyligne quelconque.

 

Regarde du côté de :

 (vla-GetBoundingBox vlobjet 'MINP 'MAXP)

 

Ce code permet de récupérer ces extrêmes dans les 2 variables. MINP et MAXP.

 

Attention à convertir ta polyligne en objet VLA, je ne sais pas comment tu travailles.

Au cas où :

(setq vlobjet (vlax-ename->vla-object objet))

Permet de passer d'une entité renvoyée par (car(ENTSEL)) à une entité en VLA.

 

Hop

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Pour l'équivalent de BoundingBox (qui retourne les points inférieur gauche et supérieur droit du rectangle orienté suivant le SCG englobant la polylinge), on peut le faire sans Visual LISP à partir de la liste de points :

 

(setq pts (massoc 10 (entget pl)))
(setq inf_gauche (apply 'mapcar (cons 'min pts)))
(setq sup_droit (apply 'mapcar (cons 'max pts)))

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

Posté(e)

D'accord. Mais si je veux sélectionner un rectangle qui n'est pas aligné au scu, il me faudrait une sélection supplémentaire pour pouvoir aligner le scu aux points du rectangle et ensuite décomposer...?

Posté(e)

Salut,

 

Inférieur gauche et supérieur droit n'ont vraiment de sens que dans un rectangle dont les côtés sont parallèles aux axes d'un système de coordonnée.

En programmation, excepté pour les entrées utilisateur (getpoint, etc.) et l'utilisation de command, seuls le SCG et le SCO de certains objets sont pris en considération. Par exemple, les points contenus dans la liste DXF d'une polyligne sont définis dans le SCO de celle-ci qui n'a de commun avec le SCU qui a servi à la construire que l'axe Z.

 

Pour ta demande, avec un rectangle, on peut définir 4 SCU différents (8 en fait) dont les axes sont parallèles aux cotés, donc autant de possibilités de coins inférieur droit et supérieur gauche. Dans tous les cas, les points retournés par massoc seraient les même et il faudrait les traduire dans le SCU nouvellement défini avec trans pour en déterminer les coins inférieur gauche et supérieur droit.

 

Tout ça me semble bien compliqué là ou la saisie de deux points avec getpoint donnerait directement ces points.

Mais ne sachant pas ce que tu veux faire, je ne peux dire si c'est la meilleure solution.

Si tu décrivais un peu plus avant ce que tu veux faire, on pourrais peut-être t'indiquer un autre chemin à suivre. assez souvent on ne fait pas dans un programme la même chose qu'on ferait "manuellement" pour arriver au même résultat, par exemple, tu parles de décomposer/recomposer et c'est quelque chose qu'il n'est généralement pas nécessaire en programmation.

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é