Aller au contenu

[Résolu] Comment décaler une polyligne ?


Messages recommandés

Posté(e)

Bonjour à tous.

 

Voilà, j'ai, dans un lisp, ceci :

...
 (princ "\nTournez dans le sens horaire ! !")
 (command "_.pline"
   (while (not (zerop (getvar "cmdactive"))) (command pause)) ;_ Fin de while
 ) ;_ Fin de command
 (setq ent (entlast))
...

Et dans ce même Lisp, j'aimerai utiliser "Select" pour décaler cette polyligne, à droite (ou vers l'intérieur), de 5 mètres par exemple. Sachant que cette polyligne est toujours construite dans le sens horaire.

 

Peut-être en passant par son centre, qui normalement sera toujours à l'intérieur de cette polyligne...

 

Si quelqu'un a une astuce, un conseil, une formule magique... Je suis preneur... ;)

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Salut,

 

Ce n'est pas la méthode la plus sûre, mais la plus "simple".

 

(setq pts nil)
(command "_.pline")
(while (not (zerop (getvar "cmdactive")))
 (command pause)
 (setq pts (cons (getvar 'lastpoint) pts))
)
(setq pts (reverse (cdr pts)))
(command "_.offset"
 5
 (entlast)
 (polar	(car pts)
	(- (angle (car pts) (cadr pts)) (/ pi 2))
	1
 )
 ""
)

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

Posté(e)

Salut (gile), et merci pour ce code, il fonctionne super... :D

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

J'ai ceci pour une méthode plus sûre

(vl-load-com)
;; CWCCW
;; checking if pline drawn CW or CCW
;; Arguments: object-pline
(defun cwccw (lw / LW LST MAXP MINP)
 (vla-GetBoundingBox lw 'MinP 'MaxP)
 (setq
    minp (vlax-safearray->list minp)
    MaxP (vlax-safearray->list MaxP)
    lst 
      (mapcar
        (function
        (lambda (x)
        (vlax-curve-getParamAtPoint
        lw
        (vlax-curve-getClosestPointTo lw x)
        ) ;_ vlax-curve-getParamAtPoint
        ) ;_ lambda
        ) ;_ function
        (list minp
          (list (car minp) (cadr MaxP))
           MaxP
          (list (car MaxP) (cadr minp))
        ) ;_ list
      ) ;_ mapcar
 ) ;_ setq
 (if 
   (or
     (<= (car lst) (cadr lst) (caddr lst) (cadddr lst))
     (<= (cadr lst) (caddr lst) (cadddr lst) (car lst))
     (<= (caddr lst) (cadddr lst) (car lst) (cadr lst))
     (<= (cadddr lst) (car lst) (cadr lst) (caddr lst))
   ) ;_ or
   "clockwise"
   "counter-clockwise"
 ) ;_ if
) ;_ defun


(defun c:decal (/ dist pl pls newpl)

(print)
(setq dist (getdist "Distance de decalage: "))
(if (/= dist 0) (progn
 (setq ent (car (entsel "Pointez le contour a decaler: ")))
 (if (/= ent nil) (progn
    (setq pl (vlax-ename->vla-object ent))
    (setq pls (cwccw pl))
    (if (= pls "clockwise")
      (setq newpl (vla-offset pl dist))
      (setq newpl (vla-offset pl (- dist)))
    ) ;_if
 )) ;_if
)) ;_if

) ;_defun

Aide au téléchargement du cadastre dgfip-download-helper
Insertion de photos géolocalisées exif https://www.dropbox.com/s/gkf6o9ac2hxen97/exifscr.zip?dl=0
Script correction BUG SPDC V2, propriétaire département 21 et 22 : https://greasyfork.org/scripts/442400-spdcv2/code/SPDCV2.user.js

Posté(e)

Salut

 

Un exemple qui décale une polyligne existante de 5.0

 

(setq poly (vlax-ename->vla-object (car (entsel))))
(vlax-invoke poly 'offset 5.0) ; Pour décaler d'un coté
(vlax-invoke poly 'offset -5.0) ; Pour décaler de l'autre coté

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

Salut à tous, et merci pour votre aide.

 

Vincent : merci pour ce code "trop" complexe à mes yeux.

 

Patrick_35 : J'ai tenté ça :

	   (setq poly (vlax-ename->vla-object (car (entlast))))
   (vlax-invoke poly 'offset 5.0) ;c'est le bon coté pour moi

Mais AutoCAD me répond ça :

type d'argument incorrect: consp <Nom d'entité: 22dc5cafe00>

 

Encore merci à vous...

 

EDIT : Patrick_35, j'ai trouvé :

(setq poly (vlax-ename->vla-object (entlast)))

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

vincentp010,

 

J'ai quelques doutes quant à la méthode que tu utilises pour déterminer si une polyligne court en sens horaire ou en sens anti-horaire.

En fait, c'est plus que des doutes j'ai fait un test avec un polyligne qui me donne le même résultat après avoir inversé le sens de la polyligne qu'avant de l'avoir fait...

 

La méthode utilisée ci-dessous avec l'aire algébrique (signée) d'une polyligne est fiable même avec des segments en arc.

 

Dans tous les cas, décaler "à l'intérieur" n'a de sens que si la polyligne fermée, comme décaler "à droite" n'a de sens que pour un polyligne ouverte.

 

;; PLINE-ALGEBRAIC-AREA (gile)
;; Returns the algebraic area of the polyline
;; the area is negative if the polyline is clockwise
;;
;; Argument: a polyline ename

(defun Pline-Algebraic-Area (pl / elst lst tot cen p0 area cen)
 (setq elst (entget pl))
 (while (setq elst (member (assoc 10 elst) elst))
   (setq lst  (cons (cons (cdar elst) (cdr (assoc 42 elst))) lst)
  elst (cdr elst)
   )
 )
 (setq	lst (reverse lst)
tot 0.0
p0  (caar lst)
 )
 (if (/= 0 (cdar lst))
   (setq tot (polyarc-algeb-area (cdar lst) p0 (caadr lst))
   )
 )
 (setq lst (cdr lst))
 (if (equal (car (last lst)) p0 1e-9)
   (setq lst (reverse (cdr (reverse lst))))
 )
 (while (cadr lst)
   (setq tot  (+ (triangle-algeb-area p0 (caar lst) (caadr lst)) tot))
   (if	(/= 0 (cdar lst))
     (setq tot	(+ tot (polyarc-algeb-area (cdar lst) (caar lst) (caadr lst))))
   )
   (setq lst (cdr lst))
 )
 (if (/= 0 (cdar lst))
   (setq tot (+ tot (polyarc-algeb-area (cdar lst) (caar lst) p0)))
 )
 tot
)

;; TRIANGLE-ALGEB-AREA (gile)
;; Returns the algebraic area of the triangle defined by three 2d points
;; the area is negative if points are clockwise
;;
;; Arguments: three 2d points

(defun triangle-algeb-area (p1 p2 p3)
 (/ (-	(* (- (car p2) (car p1))
   (- (cadr p3) (cadr p1))
)
(* (- (car p3) (car p1))
   (- (cadr p2) (cadr p1))
)
    )
    2.0
 )
)

;; POLYARC-ALGEB-AREA (gile)
;; Returns the algeraic area of a 'polyarc'
;;
;; Arguments
;; bu : polyarc bulge
;; p1 : start point
;; p2 : end point

(defun polyarc-algeb-area	(bu p1 p2 / ang rad)
 (setq	ang  (* 2 (atan bu))
rad  (/	(distance p1 p2)
	(* 2 (sin ang))
     )
 )
 (/ (* rad rad (- (* 2 ang) (sin (* 2 ang)))) 2.0)
)

 

Exemple d'utilisation pour décaler vers l'intérieur une polyligne fermée.

 

;; OffsetInside (gile)
;; Offset inside a closed polyline
;;
;; Arguments
;; pl: a polyline (ename or vla-object)
;; dist: offset distance
;;
;; Returns a variant
;; (an array of the newly created objects resulting from the offset).

(vl-load-com)
(defun OffsetInside (pl dist / obj)
 (if (= (type pl) 'ENAME)
   (setq obj (vlax-ename->vla-object pl))
   (setq obj pl
         pl  (vlax-vla-object->ename obj)
   )
 )
 (vla-offset obj
             (if (minusp (Pline-Algebraic-Area pl))
               dist
               (- dist)
             )
 )
)

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

Posté(e)

Dans tous les cas, décaler "à l'intérieur" n'a de sens que si la polyligne fermée

Elles devraient l'être toutes.

 

comme décaler "à droite" n'a de sens que pour un polyligne ouverte.

J'entendais "dans le sens de création".

 

Mais pour les deux cas, tu as raison, j'aurais dû être plus précis...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

On est d'accord, "à droite" ou "à gauche", c'est dans le sens de création, mais avec une polyligne fermée, pour que le décalage soit "à l'intérieur", "à droite" ou "à gauche" dépend du fait que la polyligne ait été créée en sens horaire ou pas (ce que tu as compris).

 

Avec la méthode que j'ai donné dans ma première réponse, il faut que l'utilisateur respecte la consigne :

"\nTournez dans le sens horaire ! !"

 

Avec la méthode de l'aire algébrique pour déterminer le sens de rotation on peut garantir le décalage vers l'intérieur quel que soit le sens de création de la polyligne.

 

Il suffit de charger les routines que j'ai donné et de faire :

 

  (command "_.pline")
 (while (not (zerop (getvar "cmdactive")))
   (command pause)
 )
 (OffsetInside (entlast) 5)

 

Toujours avec une polyligne fermée, une autre méthode, consiste à décaler des deux côtés (avec vla-Offset + et - la distance de décalage) et a effacer les (ou les) décalge dont l'aire est la plus grande.

 

(defun OffsetInside (pl dist / )
 (vl-load-com)
 (if (= (type pl) 'ENAME)
   (setq pl  (vlax-ename->vla-object pl))
 )
 (setq	of1 (vlax-invoke pl 'offset dist)
of2 (vlax-invoke pl 'offset (- dist))
 )
 (if (< (apply '+ (mapcar 'vla-get-area of1))
 (apply '+ (mapcar 'vla-get-area of2))
     )
   (foreach o of2 (vla-Delete o))
   (foreach o of1 (vla-Delete o))
 )
)

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

Posté(e)

Re.

 

Merci (gile) pour ces précisions, mais il faut tout de même saisir la polyligne dans le bon sens, car j'ai d'autres routines qui l'exigent, comme une cotation périmétrique de cette polyligne...

 

Si non, je ne sais pas comment m'en sortir...

 

Encore merci à tous...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

Re.

 

Merci (gile) pour ces précisions, mais il faut tout de même saisir la polyligne dans le bon sens, car j'ai d'autres routines qui l'exigent, comme une cotation périmétrique de cette polyligne...

 

Si non, je ne sais pas comment m'en sortir...

 

Encore merci à tous...

 

La fonction Pline-Algebraic-Area ci-dessus renvoie l'aire algébrique de la polyligne c'est à dire l'aire 'signée' de la polyligne. Si l'aire est négative, c'est que la polyligne est en sens horaire, sinon, il te suffit l'inverser (il existe plein de routines pour ça datant d'avant l'option Inverser de la commande PEDIT).

En programmation, on essaye au maximum de ne pas accorder trop de confiance à l'utilisateur.

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

Posté(e)

En programmation, on essaye au maximum de ne pas accorder trop de confiance à l'utilisateur.

C'est bien ça le plus difficile... ;)

 

Quand je fais une routine pour moi, elle dépasse rarement 20/30 lignes... Si c'est pour un(e) collègue, je peux multiplié ça par 5 voir 10...

 

Avec la gestion d'erreur, si il ne clique pas la bonne entité, dans quel calque il se trouve... Et j'en passe...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Posté(e)

vincentp010,

 

J'ai quelques doutes quant à la méthode que tu utilises pour déterminer si une polyligne court en sens horaire ou en sens anti-horaire.

En fait, c'est plus que des doutes j'ai fait un test avec un polyligne qui me donne le même résultat après avoir inversé le sens de la polyligne qu'avant de l'avoir fait...

 

Cette fonction n'est pas de moi, je n'arrive plus à retrouver d’où elle vient :(

Elle ne m'a jamais fait défaut sur les polylignes fermées, je m'en sert souvent pour les décaler et faire des liserés en hachures

Aide au téléchargement du cadastre dgfip-download-helper
Insertion de photos géolocalisées exif https://www.dropbox.com/s/gkf6o9ac2hxen97/exifscr.zip?dl=0
Script correction BUG SPDC V2, propriétaire département 21 et 22 : https://greasyfork.org/scripts/442400-spdcv2/code/SPDCV2.user.js

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é