Jump to content

Recommended Posts

Posted
(setq gct (osnap (vlax-curve-getStartPoint bm) "gcen"))

The above code line gives only closed polyline

How to find the geometric center of an open polyline and a single line

Posted
1 hour ago, maahee said:
(setq gct (osnap (vlax-curve-getStartPoint bm) "gcen"))

The above code line gives only closed polyline

How to find the geometric center of an open polyline and a single line

 

Only the geometric center is available for closed areas, since open polylines have no area and therefore no true center. If it’s just a line, the "geometric center” is the midpoint. 

  • Agree 1
  • Thanks 1
Posted

You can actually calculate it, here is the code (you can change it for your purposes):

 

(setq ptlist (mapcar 'cdr (vl-remove-if-not (function (lambda (x) (= (car x) 10))) (setq ent (entget (car (entsel "\nSelect the line:")))))) ;; point list
      sum_x 0
      sum_y 0
      vertices (cdr (assoc 90 ent)) ;; number of vertices for LWPOLYLINE
      )

(foreach pt ptlist
  (setq sum_x (+ sum_x (car pt))) ;; sum only the X vertices values
  )

(foreach pt ptlist
  (setq sum_y (+ sum_y (cadr pt))) ;; sum only the Y vertices values
  )

(setq sum_x (/ sum_x vertices) ;; dividing the total sum X by the number of vertices
      sum_y (/ sum_y vertices) ;; dividing the total sum Y by the number of vertices
      pt (list sum_x sum_y) ;; geometric center
      )

 

Below are the pictures with geometric center for open and closed polyline (picture 1 open, picture 2 closed).

 

image.thumb.png.4e531361356ba9dfe867cd03e1353f4a.png

Picture 1.

 

image.thumb.png.e0d8712fb4e7a95fb95f64ef80acc19e.png

Picture 2.

 

50 minutes ago, DATVO said:

If it’s just a line, the "geometric center” is the midpoint. 

 

This is true.

 

Best regards.

  • Like 1
  • Agree 1
  • Thanks 1
Posted

Not quite the middle of say 2 points. The red is the average answer. The green is gcen. so 4 answers. If the shape is say 4 points then you could force a close get the Gcen then do a undo.

 

image.thumb.png.9168d46d0bd7671f1035b27493aaaf86.png

  • Thanks 1
Posted

The geometric center (a.k.a. centroid) of an open polyline is deteremined by summing the length of each line segment times the coordinates of the midpoint of the respective segment. The result is then divided by the total length of the polyline. 

It is NOT the average of the point locations.

; Calculates the centroid for an open lwpolyline
; lrm 8/9/2025
(defun c:pl_centroid (/ ss pt_lst sum_x sum_y sum_d n i d mid_pt centroid)
  (setq	ss     (entget (car (Entsel "\nSelect Open Polyline")))
	pt_lst (mapcar
		 'cdr
		 (vl-remove-if-not '(lambda (x) (= (car x) 10)) ss)
	       )
  )
(setq sum_x 0
      sum_y 0
      sum_d 0.0
      n	    (length pt_lst)
      i	    0
)
(while (<= i (- n 2))
  (setq d (distance (nth i pt_lst) (nth (+ i 1) pt_lst)))
  (setq
    mid_pt (mapcar '/
		   (mapcar '+ (nth i pt_lst) (nth (+ i 1) pt_lst))
		   '(2 2 2)
	   )
  )
(setq sum_x (+ sum_x (* (car mid_pt) d))
      sum_y (+ sum_y (* (cadr mid_pt) d))
      sum_d (+ d sum_d)
      i	    (+ i 1)
)
)
(setq centroid (list
		 (/ sum_x sum_d)
		 (/ sum_y sum_d)
	       )
)
(princ "\n Centroid at: ")
(princ centroid)
(command "_point" "_non" centroid)
(princ)
)

 

 

  • Like 1
  • Thanks 1
Posted (edited)

Okay, this is the sub-function for calculating geometric center for open or closed polygon made from polyline.

 

; *******************************************************************************************
; Sub-Function      :  SX:geomCenter
; Description       :  Geometric center for open or closed lwpolyline for 2D polygons
; Arguments:        :  ent - Selected entity into the drawing
; Calling function  :  (SX:geomCenter ent)
; Author            :  Saxlle
; Date              :  August 11, 2025
; *******************************************************************************************

(defun SX:geomCenter ( ent / ptlist sum_x sum_y sum_area temp_area i len temp_x temp_y j cen_x cen_y cen_pt)
  
  (setq ptlist (mapcar 'cdr (vl-remove-if-not (function (lambda (x) (= (car x) 10))) (entget ent)))) ;; point list
  
  (if (and (equal (cdr (assoc 0 (entget ent))) "LWPOLYLINE") (>= (length ptlist) 3))
    
    (progn
      
      (setq sum_x 0.0
	    sum_y 0.0
	    sum_area 0.0
	    temp_area 0.00
	    i 0
	    )
      
      (repeat (setq len (length ptlist))
	
	(if (< (1+ i) len)
	  
	  (progn
	    
	    (setq temp_area (- (* (car (nth i ptlist)) (cadr (nth (1+ i) ptlist))) (* (car (nth (1+ i) ptlist)) (cadr (nth i ptlist))))
		  sum_area (+ sum_area temp_area)
		  temp_x (+ (car (nth i ptlist)) (car (nth (1+ i) ptlist)))
		  temp_y (+ (cadr (nth i ptlist)) (cadr (nth (1+ i) ptlist)))
		  sum_x (+ sum_x (* temp_x temp_area))
		  sum_y (+ sum_y (* temp_y temp_area))
		  i (1+ i)
		  )
	    )
	  
	  (progn
	    
	    (setq j 0
		  temp_area (- (* (car (nth i ptlist)) (cadr (nth j ptlist))) (* (car (nth j ptlist)) (cadr (nth i ptlist))))
		  sum_area (+ sum_area temp_area)
		  temp_x (+ (car (nth i ptlist)) (car (nth j ptlist)))
		  temp_y (+ (cadr (nth i ptlist)) (cadr (nth j ptlist)))
		  sum_x (+ sum_x (* temp_x temp_area))
		  sum_y (+ sum_y (* temp_y temp_area))
		  )
	    )
	  )
	)
      
      (setq sum_area (/ sum_area 2))
      
      (if (not (equal sum_area 0.0))
	
	(setq cen_x (/ sum_x (* sum_area 6))
	      cen_y (/ sum_y (* sum_area 6))
	      cen_pt (list cen_x cen_y)
	      )
	)
      
      (prompt (strcat "\nThe geometric center is: " (rtos cen_x 2 2) "," (rtos cen_y 2 2)))
      (princ)
      
      )
    
    (progn
      
      (cond
	
	((equal (cdr (assoc 0 (entget ent))) "LWPOLYLINE")
	 
	 (prompt "\nSelected entity is POLYLINE and the number of vertices are lower than 3! Need at least 3 or more vertices!")
	 (princ)
	 
	 )
	
	((equal (cdr (assoc 0 (entget ent))) "LINE")
	 
	 (prompt "\nSelected entity is LINE and the center is the midpoint!")
	 (princ)
	 
	 )
	
	)
      
      )
    
    )
  
  )

 

An example video of how it works.

 

Best regards.

 

Edited by Saxlle
  • Like 1
  • Thanks 1
Posted (edited)

@devitg@Saxlle  There seems to be some dissagreement of the definition of the geometric center of a polyline.  Should the polyline  be considered a linear object or a closed shape?  If it's a linear object then the geometric center for an open polyline as shown below is (1.5,0.8) and not (1.5,0.5). There is no line from (3,0) to (0,0) that influeces the location of the geometric cener. My code above considers the polyline as a series of lines and not the bounds of a shape (which is ill defined as it is open).

image.png.fc4cddc7828347b7a77abf98708b2afc.png

 

There is also the interpretation of how to handle a polyline that is "open" but should be considered a closed shape where the last vertex is assumed to be the same as the first vertex.  In this case the polyline needs to be tested for the "closed" property and then appropriately dealt with to define a closed shape.

Edited by lrm
Posted
(defun C:Am (/ ss num i ent entdata p1 p2 p ang p_offset oldUcs)
(if (setq ss (ssget '((0 . "LINE,LWPOLYLINE,ARC,CIRCLE"))))
    (progn
     (setq oldOsn (getvar "OSMODE"))  ; Save current OSNAP modes
(setvar "OSMODE" 0)               ; Disable all object snaps
(setvar "CMDECHO" 0)              ; Disable command echo
     (command "_.undo" "_be")

      (setq num (sslength ss))
      (setq i 0)
      (repeat num
        (setq ent (ssname ss i))
        (setq entdata (entget ent))
        (if (= (cdr (assoc 0 entdata)) "LINE")
          (progn
            (setq p1 (cdr (assoc 10 entdata)))
            (setq p2 (cdr (assoc 11 entdata)))
            ;; Calculate the angle
            (setq ang (angle p1 p2))
            ;; Perpendicular point offset
            (setq p (polar p1 (+ ang (/ pi 2)) 0.2))
            ;; Create aligned dimension
            (command "DIMALIGNED" p1 p2 p)
          )
        )
        (setq i (1+ i))
      )
(setvar "OSMODE" oldOsn)          ; Restore previous OSNAP modes
(setvar "CMDECHO" 1)
     
    )
    (alert "No entities selected.")
  )
  ;; Restore UCS
  

  (princ)
)

When executing AutoLisp, it works well, but whenever the UCS is shifted, running AutoLisp causes the dimensions of the same object to shift, resulting in a discrepancy between the dimensions and the object. This difference corresponds to the change between the old UCS and the new UCS.

Posted

@maahee It is not clear what you want to calculate.   Please respond to the following questions.

  1. Should the program be able to handle lines?
  2. ... lwpolylines without arc segments?
  3.  ... lwpolylinese with arc segments?
  4.  arc objects?
  5. circle objects?
  6. If the open/close property of a polyline is "open" sould the polyline be considered a closed shape defined by a line segment from the last vertex to the first vertex?

The code in your last post dows nothing if the object is not a line.  If it is a line it adds a dim line but does not identify the "center".

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...