Jump to content

Reshape polyline/3Dpolyline by moving vertices to nearest point


drdownload18

Recommended Posts

try lisp from

@ronjonp   

 

 



(defun c:s2o (/ a b c d el m s)
  ;; RJP » 2020-04-29
  ;; Could give bad results for multiple vertices that are within the 'search distance'
  (cond
    ((and (setq d (getdist "\nPick a distance to search: "))
	  (setq s (ssget ":L" (list '(0 . "CIRCLE,INSERT,POINT,LWPOLYLINE"))))
     )
     (foreach e	(vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
       (if (= "LWPOLYLINE" (cdr (assoc 0 (setq el (entget e)))))
	 (setq b (cons (vl-remove-if '(lambda (x) (/= 10 (car x))) el) b))
	 (setq a (cons (list (cdr (assoc 10 el)) e) a))
       )
     )
     (if (setq b (mapcar 'cdr (apply 'append b)))
       (foreach	p a
	 (setq c (mapcar '+ (car p) '(0 0)))
	 (cond
	   ((setq m (vl-some '(lambda (x)
				(if (equal c x d)
				  x
				)
			      )
			     b
		    )
	    )
	    (setq b (vl-remove m b))
	    (entmod (append (entget (cadr p)) (list (cons 10 (append m (list (last (car p))))))))
	   )
	 )
       )
     )
    )
  )
  (princ)
)

 

Link to comment
Share on other sites

It's a bit tricky.

Your points are all on different Z-value

 

You certainly cannot make a polyline that has different z-values for its vertices.

So you want to replace the polyline by a newly drawn 3D Polyline

Link to comment
Share on other sites

They are asking for X-Y direction only, but likewise I would be tempted to make something up to cater for X-Y and X-Y-Z - versatility for others who follow. Does the OP want to retain any Z coordinate of the original polyline / 3D Polyline?

 

Not had a chance to do much LISP recently, the guy who keeps paying me wants me to do what he pays me for. 

 

It might be easiest to create a new line to the points rather than modify the existing line - for example if there are more verticies in the line than there are points it might do something odd. So perhaps find the bounding box for the polyline and use the points as a 'crossing polygon' selection set, filter to points to find the points - perhaps offset a little, draw the line to suit and delete the original.

 

Link to comment
Share on other sites

This code works for the example you provided.

 

I'm not sure if it will work in all situations.  

The elevation is greater than the distance between points, so it may find the wrong point sometimes.

 


(vl-load-com)

;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/how-to-get-the-z-coordinate-of-3d-polyline/td-p/2435197
;;  Poly-Pts
;;; returns a list of the polyline vertices WCS coordinates
;;; Argument: a polyline (ENAME or VLA-OBJECT)
(defun poly-pts (p / n l)
	(setq n (fix (vlax-curve-getEndParam p)))
	(or (vlax-curve-IsClosed p) (setq n (1+ n)))
	(repeat n
	    (setq l (cons (vlax-curve-getPointAtParam p (setq n (1- n))) l))
	)
)


(defun draw3DWPoly (lst cls)

	(command "_3dpoly")
	(foreach a lst
		(command a)
	)
	(command "")
)


;; RPTP for "Reshape Polyline To Points"
(defun c:RPTP ( / pts pt dst closest_dst pl verts vrt i j ind pointlist)
	(princ "\nSelect points: ")
	(setq pts (ssget (list (cons 0 "POINT"))))
	
	(setq pl (car (entsel "\nSelect polyline: ")))
	;; read the vertices of the polyline
	(setq verts (poly-pts pl))
	
	;; for each vertex find the closest points.
	;; verts is already sorted from start to end (as the polyline was drawn)

	(setq pointlist (list))
	
	(foreach vrt verts
		;; 
		(setq i 0)	
		(setq closest_dst nil)	
		(repeat (sslength pts)
		
			(setq dst (distance 
				vrt									;; vertex
				(cdr (assoc 10 (entget (ssname pts i))))		;; location of the POINT
			))

			(if (= closest_dst nil)
				;; first try
				(progn	
					(setq closest_dst dst)
					(setq ind i)				;; we want to keep track of the index of the closest point
				)
				;; else, see if we get a closer match
				(if (< dst closest_dst)
					(progn	
						(setq closest_dst dst)
						(setq ind i)
					)
				)
			)
			(setq i (+ i 1))
		)
		
		(setq pointlist (append pointlist (list (cdr (assoc 10 (entget (ssname pts ind)))) )))
		;; remove the point from the list, so we don't look at the same point twice
		(ssdel (ssname pts ind) pts)
	
	)
	
	(princ pointlist)
	(draw3DWPoly pointlist 0)
	(entdel pl)
	
)

 

  • Like 1
Link to comment
Share on other sites

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...