Aller au contenu

Messages recommandés

Posté(e)

voici.

 
(defun C:CDGPOL ( / pol cdg)
(setq pol (car (entsel "\n pointez une polyligne")))
(if (setq cdg (cdgpol pol))
  (alert (strcat "centre de gravité : " (rtos (car cdg) 2 3) " , " (rtos (cadr cdg) 2 3)))
)
)

(defun cdgpol (pol / ent lp)
(if (and pol (= "LWPOLYLINE" (cdr (assoc 0 (setq ent  (entget pol))))))
  (setq lp (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 10 (car x))) ent)))
  (print "pas une polyligne !!! ")
)
(if lp
 (List 
    (/ (apply '+ (mapcar 'car lp)) (length lp))
    (/ (apply '+ (mapcar 'cadr lp)) (length lp))
  )
)  
)  

 

Attention, la routine ne vérifie pas si la polyligne est fermée et ne tient pas compte des arcs éventuels; si çà ne te suffit pas, dis le, on peut faire mieux.

Posté(e)

Dans le lien donné par Tramber, je donnais une routine en "pur Visual LISP" pour les VBistes.

 

Il est indispensable de passer par VisualLISP pour récupérer le centroïd d'une région ou d'un solide, mais on peut écrire la même chose de manière un peu plus "lisible" pour des lispeurs.

 

(defun c:pt-cen	(/ AcDoc Space SelSet Region)

 ;; Pointeur sur le document actif
 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))

 ;; Pointeur sur l'espace actif (objet ou papier)
 (if (= (getvar "CVPORT") 1)
   (setq Space (vla-get-PaperSpace AcDoc))
   (setq Space (vla-get-ModelSpace AcDoc))
 )

 (if (setq SelSet (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))

   ;; Pour tous les objets contenus dans le jeu de sélection
   (vlax-for obj (vla-get-activeSelectionSet AcDoc)

     ;; Création d'une région
     (setq Region (vlax-invoke Space 'addRegion (list obj)))

     ;; Création d'un point au centre de gravité
     (vlax-invoke
Space
'addPoint
(trans (vlax-get (car Region) 'Centroid) 1 0)
     )

     ;; Supression de la région
     (vla-delete (car Region))
   ) ;_ fin de vlax-for
 ) ;_ fin de if
 (princ)
) ;_ fin de defun 

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

Posté(e)

Je vais encore "chipoter", mais la routine donnée par didier-AD retourne le barycentre (plus exactement l'équibarycentre) d'un polygone. Ceci ne correspond au centre de gravité (centroïd) que dans le cas de triangles queconques ou de polygones réguliers ou particuliers (rectangles, losanges, parallélogrames) à 4 côtés ou plus.

Voir ici

 

[Edité le 31/5/2007 par (gile)]

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

Posté(e)

 

Hello

 

Dans un genre un peu différent, j'aurais plutôt besoin d'une routine qui à partir de la sélection de 1 ou N (si possibles) Polylignes 2D (ou Régions) fermées donne le barycentre ou centre de gravité (Cela m'importe peu) MAIS avec donc un point à l'intérieur du polygone IMPERATIVEMENT !

 

Comment faire avec les contours complexes (concavités) et pas si complexesque ça en forme du L ou de U par exemple !

 

Application: obtenir un point graphique (en fait un bloc avec N attributs: No, Surface, Périmètre par exemple) TOUJOURS DANS le polygone des parcelles en cadastre ...

 

Le Decapode "chiant"

 

PS: C quoi la différence entre le CDG et le Barycentre "simplement" ?

 

Autodesk Expert Elite Team

Posté(e)

Salut lecrabe,

 

Une routine vite fait qui place un point à l'intérieur des polylignes sélectionnées.

 

Le point est placé sur le barycentre des premier, deuxième, et le premier sommet suivant qui permet de remplir la condition "est à l'intérieur de la polyligne". Cette condition est évaluée avec la routine SelByObj (donc fonctionne aussi avec des polylignes contenant des arcs).

 

;;; SelByObj -Gilles Chanteau- 06/10/06
;;; Crée un jeu de sélection avec tous les objets contenus ou 
;;; capturés, dans la vue courante, par l'objet sélectionné
;;; (cercle, ellipse, polyligne fermée).
;;; Arguments :
;;; - un nom d'entité (ename) 
;;; - un mode de sélection (Cp ou Wp)
;;; - un filtre de sélection ou nil

(defun SelByObj	(ent opt fltr / obj dist n lst prec dist p_lst)
 (vl-load-com)
 (if (= (type ent) 'ENAME)
   (setq obj (vlax-ename->vla-object ent))
 )
 (cond
   ((member (cdr (assoc 0 (entget ent))) '("CIRCLE" "ELLIPSE"))
    (setq dist	(/ (vlax-curve-getDistAtParam
	     obj
	     (vlax-curve-getEndParam obj)
	   )
	   50
	)
   n	0
    )
    (repeat 50
      (setq
 lst
  (cons
    (trans
      (vlax-curve-getPointAtDist obj (* dist (setq n (1+ n))))
      0
      1
    )
    lst
  )
      )
    )
   )
   ((= (cdr (assoc 0 (entget ent))) "LWPOLYLINE")
    (setq p_lst (vl-remove-if-not
	   '(lambda (x)
	      (or (= (car x) 10)
		  (= (car x) 42)
	      )
	    )
	   (entget ent)
	 )
    )
    (while p_lst
      (setq
 lst
  (cons
    (trans (append (cdr (assoc 10 p_lst))
		   (list (cdr (assoc 38 (entget ent))))
	   )
	   ent
	   1
    )
    lst
  )
      )
      (if (/= 0 (cdadr p_lst))
 (progn
   (setq prec (1+ (fix (* 25 (sqrt (abs (cdadr p_lst))))))
	 dist (/ (- (if	(cdaddr p_lst)
		      (vlax-curve-getDistAtPoint
			obj
			(trans (cdaddr p_lst) ent 0)
		      )
		      (vlax-curve-getDistAtParam
			obj
			(vlax-curve-getEndParam obj)
		      )
		    )
		    (vlax-curve-getDistAtPoint
		      obj
		      (trans (cdar p_lst) ent 0)
		    )
		 )
		 prec
	      )
	 n    0
   )
   (repeat (1- prec)
     (setq
       lst (cons
	     (trans
	       (vlax-curve-getPointAtDist
		 obj
		 (+ (vlax-curve-getDistAtPoint
		      obj
		      (trans (cdar p_lst) ent 0)
		    )
		    (* dist (setq n (1+ n)))
		 )
	       )
	       0
	       1
	     )
	     lst
	   )
     )
   )
 )
      )
      (setq p_lst (cddr p_lst))
    )
   )
 )
 (ssget (strcat "_" opt) lst fltr)
)

;;=========================================;;

;; Place un point à l'intérieur des polylignes fermées sélectionnées

(defun c:pt-int	(/ g3 ss cnt ent plst n pt loop ssp)

 (defun g3 (p1 p2 p3)
   (mapcar '(lambda (x1 x2 x3) (/ (+ x1 x2 x3) 3)) p1 p2 p3)
 )

 (if (setq ss (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))
   (repeat (setq cnt (sslength ss))
     (setq ent (ssname ss (setq cnt (1- cnt))))
     (setq plst (mapcar 'cdr
		 (vl-remove-if-not
		   '(lambda (x) (= (car x) 10))
		   (entget ent)
		 )
	 )
     )
     (setq n  2
    pt (trans (g3 (car plst) (cadr plst) (caddr plst)) ent 0)
     )
     (entmake (list '(0 . "LINE") (cons 10 pt) (cons 11 pt)))
     (setq pt	 (entlast)
    loop T
     )
     (redraw)
     (while (and (	(setq ssp (SelByObj ent "WP" '((0 . "LINE"))))
(if
  (and ssp
       (member pt
	       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ssp)))
       )
  )
   (progn
     (entmake (list '(0 . "POINT") (assoc 10 (entget pt))))
     (entdel pt)
     (setq loop nil)
   )
   (progn
     (entdel pt)
     (setq n  (1+ n)
	   pt (trans (g3 (car plst) (cadr plst) (nth n plst)) ent 0)
     )
     (entmake (list '(0 . "LINE") (cons 10 pt) (cons 11 pt)))
     (setq pt (entlast))
   )
)
     )
   )
 )
 (princ)
)

 

PS : pour lecrabe, la routine pour mettre les sommets des polylignes fermées dans le sens trigo te convient-elle ?

 

[Edité le 1/6/2007 par (gile)]

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

Posté(e)

 

Hello Gilles

 

Comme d'habitude ça marche super ! je suis ébloui par ta rapidité !!

 

Par contre cela ne focntionne PAS sur les polylignes Splinées ou Lissées ! Sniff !?

 

J'en profite pour suggérer une petite (grosse) amélioration :

 

Plutôt que d'insérer un point, il serait TIP-TOP d'insérer un bloc avec quelques attributs

(un peu comme la routine faite pour JALNA)

 

1er attribut : reporter le code de maintien (handle) de la polyligne

(Pour jointure / identification ultérieure)

2eme / 3eme attribut : surface et périmètre de la polyligne

4eme attribut : Z départ de la polyligne

5eme attribut : une valeur numerique entière qui s'incrémente de UN en UN

à partir de la dernière valeur utilisée ou d'une valeur demandée préalablement

 

Le Decapode "chiant"

 

 

Autodesk Expert Elite Team

Posté(e)

C quoi la différence entre le CDG et le Barycentre "simplement" ?

 

Je vais essayer de faire "simplement", mais c'est pas si simple.

 

Le barycentre (centre des poids) est un point qui est la moyenne de plusieurs points pondérés.

Si les pondérations des différents points sont égales on parle d'équibarycentre.

 

Le centre de gravité d'un solide (ou d'une surface) c'est son "point d'équilibre", le point qui est à la verticale du point de suspension quelque soit celui-ci.

 

http://img516.imageshack.us/img516/9384/cdg1re1.png

 

De plus, le centre de gravité d'une structure composée de plusieurs éléments est le barycentre des points aux centres de gravité de chacun des éléments pondérés par leurs poids (ou leurs surfaces en 2d).

 

 

Excepté pour certaines figure planes (tous le triangles, les carrés, rectangles, parallélogrames, losanges et les polygones réguliers) et certains solides (prisme dont la section est une des surfaces citées et polyèdres réguliers) le centre de gravité est différent de l'équibarycentre des sommets.

 

Exemple avec un trapèze isocèle de coordonnées (0 0) (4 4) (8 4) (12 0).

L'équibarycentre est le point (6 2).

 

http://img523.imageshack.us/img523/1025/cdg2nf6.png

 

Si on décompose le trapèze en figures plus simples (un carré et deux triangles rectangles isocèles), il est aisé de placer le centre de gravité sur chacune des figures. Le "poids" de chaque figure est proportionnel à sa surface (16 unités² pour le carré, 8 unités² pour chaque triangle, soit la moitié).

 

http://img299.imageshack.us/img299/6867/cdg3ao7.png

 

Pour trouver le centre de gravité du trapèze, on peut, dans un premier temps, chercher celui du trapèze composé du triangle de gauche et du carré.

Il s'agit de trouver le barycentre de leurs centre de gravités respectifs pondérés par leurs surface.

Le centre de gravité de ce trapèze se situe donc sur la ligne entre les deux centres et au 2/3 de la distance entre ces points. le "poids" de ce trapèze est de 18 + 8 = 24 soit trois fois plus que celui du triangle.

 

http://img115.imageshack.us/img115/472/cdg4nr6.png

 

On procède de la même manière pour trouver le centre de gravité de la figure complète.

 

http://img504.imageshack.us/img504/4039/cdg5ki0.png

 

Le centre de gravité du trapèze (6.0 1.66667) est différent de son équibarycentre.

 

http://img47.imageshack.us/img47/4245/cdg6qu8.png

 

Une autre méthode est montrée ici. [Edité le 3/6/2007 par (gile)]

 

[Edité le 6/2/2008 par (gile)]

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

Posté(e)

Voilà un LISP (Parcelle) qui place le bloc "Parcelle" à l'intérieur des polylignes fermées fermées sélectionnées.

 

Le bloc doit avoir 5 attributs, dans l'ordre, le maintient (handle) de la polyligne, son périmètre, son aire, son élévation et un numéro automatiquement incrémenté.

Si plusieurs polylignes sont sélectionnées en même temps, le numéro est incrémenté dans l'ordre de création des objets.

Le périmètre et la surface sont des champs dynamiques, pour le formatage des champs se reporter aux sujets sur Pline_block.

 

;;; SelByObj -Gilles Chanteau- 06/10/06
;;; Crée un jeu de sélection avec tous les objets contenus ou
;;; capturés, dans la vue courante, par l'objet sélectionné
;;; (cercle, ellipse, polyligne fermée).
;;; Arguments :
;;; - un nom d'entité (ename)
;;; - un mode de sélection (Cp ou Wp)
;;; - un filtre de sélection ou nil

(defun SelByObj	(ent opt fltr / obj dist n lst prec dist p_lst)
 (vl-load-com)
 (if (= (type ent) 'ENAME)
   (setq obj (vlax-ename->vla-object ent))
 )
 (cond
   ((member (cdr (assoc 0 (entget ent))) '("CIRCLE" "ELLIPSE"))
    (setq dist	(/ (vlax-curve-getDistAtParam
	     obj
	     (vlax-curve-getEndParam obj)
	   )
	   50
	)
   n	0
    )
    (repeat 50
      (setq
 lst
  (cons
    (trans
      (vlax-curve-getPointAtDist obj (* dist (setq n (1+ n))))
      0
      1
    )
    lst
  )
      )
    )
   )
   ((= (cdr (assoc 0 (entget ent))) "LWPOLYLINE")
    (setq p_lst (vl-remove-if-not
	   '(lambda (x)
	      (or (= (car x) 10)
		  (= (car x) 42)
	      )
	    )
	   (entget ent)
	 )
    )
    (while p_lst
      (setq
 lst
  (cons
    (trans (append (cdr (assoc 10 p_lst))
		   (list (cdr (assoc 38 (entget ent))))
	   )
	   ent
	   1
    )
    lst
  )
      )
      (if (/= 0 (cdadr p_lst))
 (progn
   (setq prec (1+ (fix (* 25 (sqrt (abs (cdadr p_lst))))))
	 dist (/ (- (if	(cdaddr p_lst)
		      (vlax-curve-getDistAtPoint
			obj
			(trans (cdaddr p_lst) ent 0)
		      )
		      (vlax-curve-getDistAtParam
			obj
			(vlax-curve-getEndParam obj)
		      )
		    )
		    (vlax-curve-getDistAtPoint
		      obj
		      (trans (cdar p_lst) ent 0)
		    )
		 )
		 prec
	      )
	 n    0
   )
   (repeat (1- prec)
     (setq
       lst (cons
	     (trans
	       (vlax-curve-getPointAtDist
		 obj
		 (+ (vlax-curve-getDistAtPoint
		      obj
		      (trans (cdar p_lst) ent 0)
		    )
		    (* dist (setq n (1+ n)))
		 )
	       )
	       0
	       1
	     )
	     lst
	   )
     )
   )
 )
      )
      (setq p_lst (cddr p_lst))
    )
   )
 )
 (ssget (strcat "_" opt) lst fltr)
)

;;; 2d-coord->pt-lst Convertit une liste de coordonnées 2D en liste de points
;;; (2d-coord->pt-lst '(1.0 2.0 3.0 4.0)) -> ((1.0 2.0 0.0) (3.0 4.0 0.0))

(defun 2d-coord->pt-lst	(lst)
 (if lst
   (cons (list (car lst) (cadr lst) 0.0)
  (2d-coord->pt-lst (cddr lst))
   )
 )
)

;;================================================================;;

;; Place le bloc "parcelle" à l'intérieur des polylignes fermées sélectionnées

(defun c:parcelle (/	 g3    bloc  AcDoc Space ss    ent   plst
	   n	 pt    l0    loop  ech	 cnt   ssp   id
	   long	 aire
	  )

 (vl-load-com)

 (defun g3 (p1 p2 p3)
   (mapcar '(lambda (x1 x2 x3) (/ (+ x1 x2 x3) 3)) p1 p2 p3)
 )

 (if (or
(tblsearch "BLOCK" (setq bloc "Parcelle"))
(findfile (setq bloc "Parcelle.dwg"))
     )
   (progn
     (setq AcDoc (vla-get-activedocument (vlax-get-acad-object))
    Space (if (= (getvar "CVPORT") 1)
	    (vla-get-PaperSpace acDoc)
	    (vla-get-ModelSpace acDoc)
	  )
     )
     (vla-StartUndoMark AcDoc)
     (if (setq ss (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))
(progn
  (if (not (vlax-ldata-get "Parcelle" "ech"))
    (vlax-ldata-put "Parcelle" "ech" 1)
  )
  (if (not (setq
	     ech
	      (getreal
		(strcat	"\nEntrez le facteur d'échelle 				(rtos (vlax-ldata-get "Parcelle" "ech"))
			">: "
		)
	      )
	   )
      )
    (setq ech (vlax-ldata-get "Parcelle" "ech"))
    (vlax-ldata-put "Parcelle" "ech" ech)
  )
  (if (not (vlax-ldata-get "Parcelle" "inc"))
    (progn
      (initget 1)
      (vlax-ldata-put
	"Parcelle"
	"inc"
	(getint "\nNuméro de départ: ")
      )
    )
  )
  (repeat (setq cnt (sslength ss))
    (setq ent  (vlax-ename->vla-object
		 (ssname ss (setq cnt (1- cnt)))
	       )
	  plst (2d-coord->pt-lst (vlax-get ent 'Coordinates))
	  nor  (vlax-get ent 'Normal)
	  n    2
	  pt   (trans (g3 (car plst) (cadr plst) (caddr plst)) nor 0)
    )
    (entmake (list '(0 . "LINE") (cons 10 pt) (cons 11 pt)))
    (setq l0   (entlast)
	  loop T
    )
    (while (and (	      (setq ssp	(SelByObj (vlax-vla-object->ename ent)
			  "WP"
			  '((0 . "LINE"))
		)
      )
      (if
	(and ssp
	     (member
	       l0
	       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ssp)))
	     )
	)
	 (progn
	   (setq id   (vla-get-ObjectID ent)

		 ;; Attribut périmètre (mm -> m)
		 long (strcat
			"%				(itoa id)
			">%).Length \\f \"%lu2%pr2%\">%"
		      )

		 ;; Attribut surface (mm² -> m²)
		 aire (strcat
			"%				(itoa id)
			">%).Area \\f \"%lu2%pr2%\">%"
		      )
	   )

	   (setq ref
		  (vla-InsertBlock
		    Space
		    (vlax-3d-point pt)
		    bloc
		    ech
		    ech
		    1
		    0.0
		  )
	   )

	   ;; attribution de leur valeur aux attributs
	   (mapcar '(lambda (x y) (vla-put-TextString x y))
		   (vlax-invoke ref 'GetAttributes)
		   (list (vla-get-Handle ent)
			 long
			 aire
			 (vla-get-Elevation ent)
			 (vlax-ldata-get "Parcelle" "inc")
		   )
	   )

	   (vlax-ldata-put
	     "Parcelle"
	     "inc"
	     (1+ (vlax-ldata-get "Parcelle" "inc"))
	   )
	   (vla-regen AcDoc acActiveViewport)
	   (entdel l0)
	   (setq loop nil)
	 )
	 (progn
	   (entdel l0)
	   (setq n  (1+ n)
		 pt (trans (g3 (car plst) (cadr plst) (nth n plst))
			   nor
			   0
		    )
	   )
	   (entmake (list '(0 . "LINE") (cons 10 pt) (cons 11 pt))
	   )
	   (setq l0 (entlast))
	 )
      )
    )
  )
)
     )
   )
   (prompt "\nLe bloc " Parcelle " est introuvable.")
 )
 (vla-EndUndoMark AcDoc)
 (princ)
) 

 

en prime, le bloc Parcelle avec lequel j'ai fait les tests.

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

Posté(e)

 

Hello Gilles

 

Merci mais qq questions:

 

Pourquoi ton bloc comprend 10 attributs et non pas 5 ?

 

Pourquoi son système d'unité en MM et non pas en M ?

Est ce important ?

 

Moultes révérences oh Grand Seigneur de la Programmation,

Le Decapode

 

 

Autodesk Expert Elite Team

Posté(e)

Salut le crabe,

 

5 des attributs sont des attributs constants (j'aurais pu mettre des textes). Mais ce n'est qu'un exemple, tu peux faire to bloc "Parcelle" comme tu veux.

 

Pour les unités, c'est un copié/collé de pline_block, le commentaire dit conversion des mm en m (ou m²) mais j'ai supprimé le facteur de conversion dans le formatage des champs (pensant que tu travaillais en mètre)

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é