Jump to content

Add New Vertex By Distance on polyline ( x axis)


RepCad

Recommended Posts

hi all, i have a polyline and i want to add new vertex by measure on polyline and remove old vertex and measure must be on x axis,,,

so i need a lisp get polyline and distance from user then program add vertex on polyline In the x-axis direction.

 

thanks in advanced (sorry for my poor english)

Vertex.png

Edited by amir0914
Link to comment
Share on other sites

hi you joined 2017, so i assume you have 1 year coding experience.

 

This is draft, assuming the Lwpolyline x-direction is in order i.e: start point to enpoint by increasing no backwards or self-intersect.

1.select lwpolyline by entsel or ssget, then get X-distance by getdist or getreal

2.find min & max coordinates from vertex list by entget or vla-get-coordinates

3.loop within min & max x-coordinates, by increasing X-distance from starting point

add X-line object & vla-intersecwith lwpolyline object

collecting intersections coordinates list, by (setq L (cons ip L))

then entdel the xline entity

4.entmake new lwpolyline with L data

5.invoke command qdim with newly created lwpolyline

 

example: get the intersection ip , where p= incremental coordinates by x-direction & en= lwpolyline entity

   (setq xl (entmakex (list '(0 . "XLINE")
				       '(100 . "AcDbEntity")
				       '(100 . "AcDbXline")
				       (cons 10 p)
				       (cons 11 (getvar 'ucsydir))
				       ) 
				 ) 
		    ) 
	      (setq [b][color="red"]ip[/color][/b] (vlax-invoke
			 (vlax-ename->vla-object xl)
			 '[color="blue"]intersectwith[/color]
			 (vlax-ename->vla-object en)
			 acExtendNone
			 ) 
		    ) 
	      ) 

 

ZHPj7si.gif

  • Like 1
Link to comment
Share on other sites

hi you joined 2017, so i assume you have 1 year coding experience.

 

This is draft, assuming the Lwpolyline x-direction is in order i.e: start point to enpoint by increasing no backwards or self-intersect.

1.select lwpolyline by entsel or ssget, then get X-distance by getdist or getreal

2.find min & max coordinates from vertex list by entget or vla-get-coordinates

3.loop within min & max x-coordinates, by increasing X-distance from starting point

add X-line object & vla-intersecwith lwpolyline object

collecting intersections coordinates list, by (setq L (cons ip L))

then entdel the xline entity

4.entmake new lwpolyline with L data

5.invoke command qdim with newly created lwpolyline

 

example: get the intersection ip , where p= incremental coordinates by x-direction & en= lwpolyline entity

   (setq xl (entmakex (list '(0 . "XLINE")
                          '(100 . "AcDbEntity")
                          '(100 . "AcDbXline")
                          (cons 10 p)
                          (cons 11 (getvar 'ucsydir))
                          ) 
                    ) 
               ) 
             (setq [b][color=red]ip[/color][/b] (vlax-invoke
                (vlax-ename->vla-object xl)
                '[color=blue]intersectwith[/color]
                (vlax-ename->vla-object en)
                acExtendNone
                ) 
               ) 
             ) 

ZHPj7si.gif

 

Sweet, You could also (vlax-put "obj" 'Coordinates (apply 'append "pt_lst")) if you didn't require the original polyline.

Link to comment
Share on other sites

Sweet, You could also (vlax-put "obj" 'Coordinates (apply 'append "pt_lst")) if you didn't require the original polyline.

 

Thanks! nice idea suits OP request, but i'm not sure if remaining distance so just kept both :)

 

I'm used to using undocumented method too, convenient without variant safearray conversion

FWIW, coordinates list can be both '(x y z x y z ....) & '(x y x y ...) ,

i think OP knows LWPolyline uses the latter

  • Like 1
Link to comment
Share on other sites

Lwpolyline is x y x y 3dpoly is x y z x y z so a quick check of object name.

 

; pline co-ords example
(if (= (vla-get-ObjectName obj) "AcDb3dPolyline") ; divide list by 2 or 3

Edited by BIGAL
  • Like 1
Link to comment
Share on other sites

hi hanhphuc, thank you for reply, i know a little autolisp but i I could not do it with your guide. can you do it ?? (i already need it)

Link to comment
Share on other sites

hi hanhphuc, thank you for reply, i know a little autolisp but i I could not do it with your guide. can you do it ?? (i already need it)

 

The previous post#2 is graphical method i.e: can be done manually by

array or offset X-line with osmode 33

 

This is another math function from library

[color="green"];Limitations:
;2D coordinates only 
;list must be incremental in X direction
;only single occurence[/color]

(defun hp:IntersOnX (p l / xy)
;hanhphuc 
(setq xy '((x)(mapcar '* x '(1.0 1.0)))
     p (xy p))
(cadr
 (assoc T
(cons
  (list (vl-some ''((x)(equal p (xy x) 1e-4)) l) p)
  (mapcar ''((a b / d )(setq d (xy (mapcar '- b a)))
	    (list
	     (<= (car a) (car p) (car b))
	     (list (car p) (+ (cadr a) (* (- (car p) (car a))
		(if (vl-some 'zerop d) 0. (/ 1. (apply '/ d ))))))
	     )
	    )
	 l (cdr l)
	 )
       )
 ) 
 )
)

 

example test

[color="green"];example list without duplicates[/color]
(setq [color="red"][b]L[/b][/color]'((-82.133 26.692) (-48.8729 57.0485) (-11.0094 57.0485) (17.675 41.0031) (34.8857 7.76624) (34.8857 -49.5388) (56.6859 -73.6069) (111.76 -73.6069)) )

(hp:IntersOnX [color="red"]'(0. 0.)[/color] l ) [color="green"]; or replace red with (getpoint)[/color]
[color="green"];(0.0 50.8901) [/color]

manipulate the function using loop WHILE, FOREACH, MAPCAR , REPEAT, vl-remove-if etc..

if i have free time, will post some examples

 

using alert as comment, read it step by step


(defun c:example ( / l pnt pt )
[color="green"];example to use function hp:IntersOnX[/color]
;hanhphuc 05.05.2018

(setq [color="red"][b]L[/b][/color] '((-82.133 26.692) (-48.8729 57.0485) (-11.0094 57.0485) (17.675 41.0031) (34.8857 7.76624) (34.8857 -49.5388) (56.6859 -73.6069) (111.76 -73.6069)) )
(alert (strcat "Example we have a point list 'L' : \n\n" (vl-princ-to-string l) "\n
       \nWe'll then use 'L' list to draw a LwPolyline"))

(LWP l)
 
(alert
 (strcat
   "The 'hp:IntersOnX' sub-function requires 2 arguments, i.e: P=point & L=list, for point here we can use GETPOINT function :\n
   (setq PNT (GETPOINT \"Type prompt massage within the quote marks\" )) 
   \nThis prompts user to specify a point then SETQ function to store the point coordinates in variable 'PNT'.
   \n\nLet's try it next.. "
   ) 
 )

(while  (not pnt)
(if
 (and (setq pnt (getpoint "\nSpecify any point within the X-range of LwPolyline.. "))
       (<= (caar l) (car pnt)(car(last l)))
      )
 
(alert (strcat "\nYou have just picked "(vl-princ-to-string p)"\n\n" "next we'll try to supply the 'PNT' in the sub-function :
\n(hp:IntersOnX PNT L)"))
(progn (princ "Oops! ")(setq pnt nil))
 )
 (princ)
)

(alert (strcat "\nSo the result "
       (vl-princ-to-string pnt)
       ", X-intersects with 'L' list is :  \n\n"
       (if (setq pt (hp:IntersOnX pnt l))
	 (strcat (vl-princ-to-string pt)" ! as we can see both X equal, only Y changes. \n"
	   )
	 "Oops.. Out of range !?"
	 )
       "\nNext, we proceed multiple method."
       )
      )
 

(prompt "\nA circle is marked at the X-intersected point! Zoom in and see.. ")
(entmakex (list '(0 . "CIRCLE")(cons 10 pt)(cons 40 2.0)'(62 . 1)))
 
(getpoint "\nPress any [ENTER] to proceed.. ")
 
(alert (strcat "Let's say we want X-interval 10 unit measured from starting point .\nAs example 0 to 100, we populate the incremental values in a list..
\n(list 0 10 20 30 40 50 60 70 80 90 100 ..... <etc..> ) "))
;multiple

(alert (strcat "\nThis 'hp:IntersOnX' sub-function only can run in single stake, so if there are many data we can use loop or iteration functions to handle it.
\nThe starting point =(list X Y) & d= X-distance, to iterate (X+d Y) here we use MAPCAR as an example : 
	\n"
       (vl-princ-to-string
	 '(mapcar
	   (function (lambda (d) (hp:IntersOnX (list (+ d (caar l) 0.004) 0.0) l)))

	   (list 0 10 20 30 40 50 60 70 80 90 100) ;<--- to modify here 
	   
	   )
	 )
;;;	        "\nNote: You can add more in list. (list 0 10 20 30 40 50 60 70 80 90 100 .... )"
       ) 
      ) ;_ end of alert

(alert (strcat "\nHere's the output: a new point list of X-intersections (by 10 unit incremental), we can use it to draw a new LwPolyline or entmod existing LwPolyline.
	\n"
(vl-princ-to-string'((-82.133 26.692) (-72.133 35.819) (-62.133 44.946) (-52.133 54.073) (-42.133 57.0485) (-32.133 57.0485)
 		(-22.133 57.0485) (-12.133 57.0485) (-2.133 52.0832) (7.867 46.4895) (17.867 40.6323)) 
 )
       "\n\nIn this example we'll redraw a new LwPolyline then command: _QDIM "
)
      )
      
(vl-cmdf "_QDIM"
 (LWP (mapcar ''((d) (trans (hp:IntersOnX (list (+ d (caar l) 1e-4) 0.0) l) 1 0))
	      '([color="red"]0 10 20 30 40 50 60 70 80 90 100[/color])[color="green"] ; suggestion - while loop [/color]
	      ) 
      ) 
 ""
 "\\"
 )

(if (/= (getvar 'cmdecho)0) (command))

(alert "\nLesson completed! \nPlease study other looping functions : 'WHILE', 'FOREACH' & 'REPEAT' as well, in order to fully automate the routine.
\nHappy coding & good luck! ")
  
(princ)
)

 

if you know little coding?

Try to learn or search lwpolyline vertex routines to replace 'L' list,

simply then just modify the red

Edited by hanhphuc
add example
  • 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...