Aller au contenu

Lignes brisées


(gile)

Messages recommandés

Salut,

 

Une demande sur le forum Autodesk AutoCAD France m'a amené à écrire une routine LISP que je voudrais partager aussi ici.

 

La demande initiale était de transformer les segments d'une polyligne en ligne brisée aléatoire (pour figurer un rocher).

 

Le LISP définit deux commandes principales :

  • PBRLINE (pour Poly BRoken LINE) qui permet de dessiner une polyligne aux segments en ligne brisés "à la volée".
  • PLINE2BRLINE (pour PolylLINE to BRoken LINE) qui redessine en ligne brisée les segments des polylignes sélectionnées.

Les deux commandes partagent certaines routines et des paramètres modifiables enregistrés dans le dessin à la manière des variables système (des commandes de même nom permettent d'en modifier les valeurs).

  • BRLINE_DENSITY qui correspond au nombre de divisions.
  • BRLINE_DEVIATION qui correspond au rapport de proportion entre le déplacement maximal d'un point de division et la longueur d'une division.

Une "déviation" inférieure ou égale à 0.5 garanti l'impossibilité de croisement (polyligne croisée).

 

Exemples en image :

Brline_settings.png

Code modifié, voir réponse #4

Code modifié, voir réponse #8

 

;;;----------------------------------------------------------------------------------;;;
;;;                                PolyBrokenLine.lsp                                ;;;
;;;                                                                                  ;;;
;;; Gilles Chanteau                                                                  ;;;
;;; http://forums.autodesk.com/t5/autocad-francais/creer-une-patatoide/td-p/6549276  ;;;
;;; Version 1.0.0 : 10/09/2016                                                       ;;;
;;; Version 1.1.0 : 12/09/2016 modification de BrLinePoints                          ;;;
;;;----------------------------------------------------------------------------------;;;

;;; Valeurs des paramètres enregistrées dans le dessin
(vl-load-com)
(or (vlax-ldata-get "PBRLINE" "Density") (vlax-ldata-put "PBRLINE" "Density" 8))
(or (vlax-ldata-get "PBRLINE" "Deviation") (vlax-ldata-put "PBRLINE" "Deviation" 0.5))

;;; Retourne un nombre "pseudo aléatoire" entre -1 et 1
(defun SignedRandom ()
 (or *randomSeed* (setq *randomSeed* (getvar 'date)))
 (setq *randomSeed* (rem (1+ (* 1664525 *randomSeed*)) 4294967296.))
 (- (* 2. (/ *randomSeed* 4294967296.)) 1.)
)

;;; Génère une liste de points "pseudo aléatoires" entre startPt et endPt
(defun BrLinePoints (startPt endPt / a d n r l)
 (setq a (angle startPt endPt)
       d (distance startPt endPt)
       n (vlax-ldata-get "PBRLINE" "Density")
       d (/ d n)
       r (* d (vlax-ldata-get "PBRLINE" "Deviation"))
 )
 (if (< 0 d)
   (mapcar
     '(lambda (p / v)
        (setq v (list (* (SignedRandom) d 0.5) (* (SignedRandom) r)))
        (list
          (+ (car p) (* (car v) (cos a)) (* (cadr v) (- (sin a))))
          (+ (cadr p) (* (car v) (sin a)) (* (cadr v) (cos a)))
        )
      )
     (repeat (1- n) (setq l (cons (polar startPt a (* (setq n (1- n)) d)) l)))
   )
   ;; ancien mode de calcul (polaire)
   ;;(mapcar
   ;;  '(lambda (p) (polar p (* PI (SignedRandom)) (* r (SignedRandom))))
   ;;  (repeat (1- n) (setq l (cons (polar startPt a (* (setq n (1- n)) d)) l)))
   ;;)
 )
)

;;; Affiche les paramètres courants
(defun DisplayBrLineSettings ()
 (prompt
   (strcat
     "\nParamètres courants: Densité = "
     (itoa (vlax-ldata-get "PBRLINE" "Density"))
     " Déviation = "
     (rtos (vlax-ldata-get "PBRLINE" "Deviation"))
   )
 )
)

;;;----------------------------------------------------------------------------------;;;
;;;                                  BRLINE_DENSITY                                  ;;;
;;;                                                                                  ;;;
;;; Modifie la valeur de la "densité".                                               ;;;
;;; La "densité" correspond au nombre de divisions d'un segment.                     ;;;
;;;----------------------------------------------------------------------------------;;;
(defun c:BrLine_Density (/ n)
 (initget 6)
 (if (setq n (getint (strcat "\nEntrez une nouvelle valeur pour BrLine_Density <"
                             (itoa (vlax-ldata-get "PBRLINE" "Density"))
                             ">: "
                     )
             )
     )
   (vlax-ldata-put "PBRLINE" "Density" n)
 )
)

;;;----------------------------------------------------------------------------------;;;
;;;                                 BRLINE_DEVIATION                                 ;;;
;;;                                                                                  ;;;
;;; Modifie la valeur de la "déviation".                                             ;;;
;;; La "déviation" correspond au rapport de proportion entre le déplacement maximal  ;;;
;;; du point de division et la longueur de la division.                              ;;;
;;;----------------------------------------------------------------------------------;;;
(defun c:BrLine_Deviation (/ d)
 (initget 6)
 (if (setq d (getdist (strcat "\nEntrez une nouvelle valeur pour BrLine_Deviation <"
                              (rtos (vlax-ldata-get "PBRLINE" "Deviation"))
                              ">: "
                      )
             )
     )
   (vlax-ldata-put "PBRLINE" "Deviation" d)
 )
)

;;;----------------------------------------------------------------------------------;;;
;;;                                     PBRLINE                                      ;;;
;;;                                                                                  ;;;
;;; Dessine une polyligne dont les segments sont des lignes brisées.                 ;;;
;;;----------------------------------------------------------------------------------;;;

(defun c:PBRLINE (/ updpline p1 p2 points echo pline)

 ;; mise à jour (re-création) la polyligne.
 (defun updpline (opt)
   (setvar 'cmdecho 0)
   (and pline (entdel pline))
   (command "_.pline")
   (foreach p points (command "_none" p))
   (command opt)
   (setvar 'cmdecho echo)
   (entlast)
 )

 ;; fonction principale.
 (DisplayBrLineSettings)
 (if
   (and
     (setq p1 (getpoint "\nSpécifiez le point de départ: "))
     (setq p2 (getpoint p1 "\nSpécifiez le point suivant: "))
   )
    (progn
      (setq points (cons p1 (append (BrLinePoints p1 p2) (list p2)))
            echo   (getvar 'cmdecho)
            pline  (updpline "")
            p1     p2
      )
      (while
        (progn
          (initget "Clore")
          (and
            (setq p2 (getpoint p1 "\nSpécifiez le point suivant ou [Clore]: "))
            (listp p2)
          )
        )
         (setq points (append points (BrLinePoints p1 p2) (list p2))
               p1     p2
               pline  (updpline "")
         )
      )
      (if (= p2 "Clore")
        (setq points (append points (BrLinePoints p1 (car points)))
              pline  (updpline "_close")
        )
      )
    )
 )
 (princ)
)

;;;----------------------------------------------------------------------------------;;;
;;;                                   PLINE2BRLINE                                   ;;;
;;;                                                                                  ;;;
;;; Redessine les segments des polylignes sélectionnées en lignes brisées.           ;;;
;;;----------------------------------------------------------------------------------;;;

(defun c:PLINE2BRLINE (/ massoc genvertices nb pline elst pts)

 ;; retourne la liste de toutes les valeurs pour le code
 ;; spécifié dans une liste d'association.
 (defun massoc (key alst)
   (if (setq alst (member (assoc key alst) alst))
     (cons (cdar alst) (massoc key (cdr alst)))
   )
 )

 ;; génère une liste de sommets en insérant les points
 ;; aléatoires entre les sommets existants.
 (defun genvertices (pts nb)
   (if (cadr pts)
     (append
       (list (car pts))
       (BrLinePoints (car pts) (cadr pts))
       (genVertices (cdr pts) nb)
     )
     (list (car pts))
   )
 )

 ;; Fonction principale.
 (DisplayBrLineSettings)
 (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
 (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
   (repeat (setq i (sslength ss))
     (setq elst (entget (ssname ss (setq i (1- i)))))
     (setq pts (genvertices (massoc 10 elst) nb))
     (if (= (logand 1 (cdr (assoc 70 elst))) 1)
       (setq pts (append pts (BrLinePoints (last pts) (car pts))))
     )
     (entmakex
       (vl-list*
         (cons 0 "LWPOLYLINE")
         (cons 100 "AcDbEntity")
         (assoc 8 elst)
         (cond
           ((assoc 62 elst))
           ((cons 62 256))
         )
         (cond
           ((assoc 6 elst))
           ((cons 6 "ByLayer"))
         )
         (cond
           ((assoc 370 elst))
           ((cons 370 -1))
           )
         (cons 100 "AcDbPolyline")
         (cons 90 (length pts))
         (assoc 70 elst)
         (assoc 38 elst)
         (assoc 210 elst)
         (mapcar '(lambda (p) (cons 10 p)) pts)
       )
     )
     (entdel (cdr (assoc -1 elst)))
   )
 )
 (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)))
 (princ)
)

  • Upvote 1

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

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

À Demixav,

Ça doit être un problème de copier/coller. Re-essaye en prenant soin de copier tout le code et rien que le code.

 

À tous,

J'ai modifié la routine BrLinePoints pour écarter tout risque de génération de polyligne croisée avec des valeurs de BrLone_Deviation supérieures à 0.5.

Le "délpacement aléatoire" des points de division n'est plus calculé en "mode polaire" avec un angle aléatoire et une distance aléatoire inférieure à la "déviation" multipliée par la longueur d'une division, mais en "mode cartésien" avec un décalage aléatoire suivant la direction du segment toujours inférieur à la moitié de la longueur d'une division combiné à un décalage perpendiculaire inférieure à la "déviation" multipliée par la longueur d'une division.

 

Brline_settings_2.png

  • Upvote 1

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

Lien vers le commentaire
Partager sur d’autres sites

Salut (gile).

 

Excellentes commandes ! ! ! De plus, il y a quelques mois, quelqu'un avait fait cette demande sur CadXP...

 

Merci pour le temps passé et pour le partage...

 

Denis...

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)

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

J'ai copié-coller de nouveau le LISP, je l'ai à nouveau chargé, et j'ai eu le même message au lancement de PRBLINE ou de de PLINE2BRLINE...

 

J'ai testé Brline_Deviation pour voir si il me demandait une valeur et c'etait bien le cas!

 

J'ai réessayé de relancer les deux commandes... et ca fonctionne! :blink:

 

Bref, un grand merci encore à Gilles pour ton partage! :)

Xav

AutoCad Map 3D 2011 - Covadis v16.0d

Windows 7 - 64b

Lien vers le commentaire
Partager sur d’autres sites

Salut à tous...

 

Juste un petit truc sur cet excellent LISP, histoire de chipoter, les polylignes modifiées par PLINE2BRLINE ne gardent pas leurs propriétés (couleur, calque...)

 

Mais c'est vraiment pour chipoter... ;)

 

Denis...

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)

Lien vers le commentaire
Partager sur d’autres sites

Salut (gile)...

 

Merci, c'est nickel...

 

Encore un super LISP de (gile) à ajouter à nos bibliothèques... ;)

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)

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é