Jump to content

draw a polyline based on coordinates


saim

Recommended Posts

I'm trying to cut a long routine into smaller ones. This time, I'm trying to (lik ethe title says) draw a polyline based on given coordinates.

I'll have a list of 2D coordinates (take this for example)

(setq listpts (list (list 0 0) (list 1 1) (list 2 1) (list 2 2)))

and I want to draw a polyline that connects those points.

I know it can be done, because it has been done here, I just don't understand the code. Since the subject is a little different, I thought it would be better to start a new thread.

 

I can draw several lines, though. It helps, but does not entirelly. I'd really apreciate if this was one single polyline.

(defun despoly (plist / p1 p2)
(setq p1 (car plist)); put the 1st element (point) on a variable
(setq plist (cdr plist)); eliminate the 1st element
	(foreach pt plist; for each remaining point
		(setq p2 pt); set the current element (point) to a second variable
		(command "line" p1 p2 ""); draw a line connecting those points
		(setq p1 p2); set the second point to the first variable, in order to draw the next line
	)
)

'then, use it to draw the list above, like
(despoly listpts)

If you can help, please PLEASE fully comment your code, because I really need to understand this. Just making it work won't be enough, for I plan to use logic involved to develop the rest of the routine.

Thanks!

Link to comment
Share on other sites

If you can help, please PLEASE fully comment your code, because I really need to understand this. Just making it work won't be enough, for I plan to use logic involved to develop the rest of the routine.

Thanks!

 

 

Not my code but perhaps you can understand this

(setq listpts (list (list 0 0) (list 1 1) (list 2 1) (list 2 2))); your list of points


; create pline from a list by Alan H


(command "_pline")                          ;start pline command
(while (= (getvar 'cmdactive) 1 )           ;while a command is running loop (it is because we haven't entered any points)
 (repeat (setq x (length listpts))         ;repeat loop (sets x to length of your list) repeat x times
   (command (nth (setq x (- x 1)) listpts));because this is still inside the pline command it evaluates the expression (nth item (x-1) of list listpts  
 );end repeat                              ;length gives you number of items in list but list is 0 based so first item is 0 and last is (x-1)
 (command "")                              ;end pline command with a return ("")
);end while

Link to comment
Share on other sites

1st

; =========================================================================================== ;
; Tworzy obiekt typu LWPOLYLINE / Creates a LWPOLYLINE object                                 ;
;  Space  [VLA-Object] - kolekcja / collection | Model/Paper + Block Object                   ;
;  Pts    [list]  - lista wierzcholkow polilinii / list of polyline vertex                    ;
;  Closed [T/nil] - nil = otwarta / open                                                      ;
;                   T   = zamknieta / closed                                                  ;
; ------------------------------------------------------------------------------------------- ;
; (cd:ACX_AddLWPolyline (cd:ACX_ASpace) (list '(5 5) '(15 5) '(15 10) '(10 10)) nil)          ;
; =========================================================================================== ;
(defun cd:ACX_AddLWPolyline (Space Pts Closed / obj)
 (setq Pts
   (apply
     (quote append)
     (mapcar
       (function
         (lambda (%)
           (list (car %) (cadr %))
         )
       )
       (mapcar
         (function
           (lambda (%)
             (trans % 1 (trans '(0 0 1) 1 0 T))
           )
         )
         Pts
       )
     )
   )
 )
 (setq obj
   (vla-AddLightweightPolyline Space
     (vlax-make-variant
       (vlax-safearray-fill
         (vlax-make-safearray vlax-vbdouble (cons 0 (1- (length Pts))))
         Pts
       )
     )
   )
 )
 (if Closed (vla-put-closed obj Closed))
 obj
)
; =========================================================================================== ;
; Aktywny obszar / Active space                                                               ;
; =========================================================================================== ;
(defun cd:ACX_ASpace ()
 (if (= (getvar "CVPORT") 1)
   (vla-item (cd:ACX_Blocks) "*Paper_Space")
   (cd:ACX_Model)
 )
)
; =========================================================================================== ;
; Kolekcja Blocks / Blocks collection                                                         ;
; =========================================================================================== ;
(defun cd:ACX_Blocks ()
 (or
   *cd-Blocks*
   (setq *cd-Blocks* (vla-get-blocks (cd:ACX_ADoc)))
 )
 *cd-Blocks*
)
; =========================================================================================== ;
; Aktywny dokument / Active document                                                          ;
; =========================================================================================== ;
(defun cd:ACX_ADoc ()
 (or
   *cd-ActiveDocument*
   (setq *cd-ActiveDocument*
     (vla-get-ActiveDocument (vlax-get-acad-object))
   )
 )
 *cd-ActiveDocument*
)
(defun cd:ACX_Model ()
 (or
   *cd-ModelSpace*
   (setq *cd-ModelSpace* (vla-get-ModelSpace (cd:ACX_ADoc)))
 )
 *cd-ModelSpace*
)

2nd

; =========================================================================================== ;
; Tworzy obiekt typu LWPOLYLINE / Creates a LWPOLYLINE object                                 ;
;  Layout [sTR]   - nazwa arkusza / layout tab name                                           ;
;  Pts    [list]  - lista wierzcholkow polilinii / list of polyline vertex                    ;
;  Closed [T/nil] - nil = otwarta / open                                                      ;
;                   T   = zamknieta / closed                                                  ;
; ------------------------------------------------------------------------------------------- ;
; (cd:ENT_MakeLWPolyline "Model" (list '(5 5) '(15 5) '(15 10) '(10 10)) nil)                 ;
; =========================================================================================== ;
(defun cd:ENT_MakeLWPolyline (Layout Pts Closed / zdir)
 (setq zdir (trans '(0 0 1) 1 0 T))
 (entmakex
   (append
     (list
       (cons 0 "LWPOLYLINE")
       (cons 100 "AcDbEntity")
       (cons 100 "AcDbPolyline")
       (cons 38 (caddr (trans (car Pts) 1 zdir)))
       (cons 90 (length Pts))
       (cons 70 (if Closed 1 0))
       (cons 210 zdir)
       (cons 410 Layout)
     )
     (mapcar
       (function
         (lambda (%)
           (cons 10 (trans % 1 zdir))
         )
       )
       Pts
     )
   )
 )
)

all from CADPL-Pack-v1

Link to comment
Share on other sites

If your points are in excel its even easier you can copy a column directly to the command line, 1st row would have PLINE, next row has =concatenate(a1,",",b1) for say x is column A and Y is column B, copy down as required then just copy the column including one blank line at end or if you want closed just have C as the last row entry.

 

If its a file of points again its probbably easier to make a list and use the existing code, you could though do a read-line from a file. let us know and we can point you in the right direction.

Link to comment
Share on other sites

(append (list '(0 . "LWPOLYLINE")'(100 ..) ... ) (mapcar ...) )

 

(vl-list* '(0 . "LWPOLYLINE") '(100 ..  )  . . (mapcar ... ) )

Link to comment
Share on other sites

Not my code but perhaps you can understand this

(setq listpts (list (list 0 0) (list 1 1) (list 2 1) (list 2 2))); your list of points


; create pline from a list by Alan H


(command "_pline")                          ;start pline command
(while (= (getvar 'cmdactive) 1 )           ;while a command is running loop (it is because we haven't entered any points)
 (repeat (setq x (length listpts))         ;repeat loop (sets x to length of your list) repeat x times
   (command (nth (setq x (- x 1)) listpts));because this is still inside the pline command it evaluates the expression (nth item (x-1) of list listpts  
 );end repeat                              ;length gives you number of items in list but list is 0 based so first item is 0 and last is (x-1)
 (command "")                              ;end pline command with a return ("")
);end while

Thanks, dude, it helps.

But I still need some enlightnement. First off, I did'nt know I could insert commands inside a command. I did try to do that in a similar way I did that "multiple single lines" code, but it didn't work, so of course, I did SOMETHING wrong. Let me show what I did.

(defun despoly (plist)
(command "_pline"                ; starts the command
	(car plist)              ; calls the first point of the list
	(setq plist (cdr plist)) ; deletes that first point
	(foreach pt plist        ; starts a loop for each remaining point
		(command pt)     ; connects the polyline to that point
	)                        ; end the loop
	(command "")             ; end the polyline command
) ; end the command
)

(now I see I could just go straigh to the loop, without drawig the first point, but nevermind that)

I guess the logic is similar, only the syntax must be wrong.

In the code you commented, there is the "'cmdactive" check. I didn't get it. Why do I need to check if a command is running when I just started it without ending?

Oh, forget it! I tried and it worked!!! YAY!!!

I edited the many questions I made because now this test answered them. The only remaining one is the above. Can you elaborate on that?

Here you have the working code:

(defun despoly (plist)
(command "_pline")                ; starts the command
(while (= (getvar 'cmdactive) 1 ) ; still don't get it
	(foreach pt plist         ; starts a loop for each point
		(command pt)      ; connects the polyline to that point
	)                         ; end the loop
	(command "")              ; end the polyline
)                                 ; end the while loop
)

 

 

 

@ziele_o2k:

Thank you for your effort, pal, but I'm a major noob. I just can't get to that level of coding yet, there is so much I don't understand going on there.

For beginning, I only knew the "(defun c:nameOfFunction)" method of defining a function. Also, I still need to go through a tutorial that teaches about vla-functions (what they do and how to use them).

That second code seems a little easier to understand... if you could comment that and I get through the help file to find out what each command does, maybe I can understand that.

For a quick run, what are the arguments required for testing it? I figure that "Pts" is the list and "closed" is whether I want the polyline closed, but what about the "layout" argument?

 

 

 

If your points are in excel its even easier you can copy a column directly to the command line, 1st row would have PLINE, next row has =concatenate(a1,",",b1) for say x is column A and Y is column B, copy down as required then just copy the column including one blank line at end or if you want closed just have C as the last row entry.

 

If its a file of points again its probbably easier to make a list and use the existing code, you could though do a read-line from a file. let us know and we can point you in the right direction.

Dude... DUDE... it opens a wide branch of possibilities, to me! I had no idea I could do that to bring stuff from excell.

Yes, as you figured, I'm trying to draw based on excell results and that method surelly will be useful during the testing stage.

But I think in the end, I'll import those numbers from a text file, for a number of reasons. The ones I can think right now are:

- I'll ask the user for a point from which the drawing will be made, making the actually drawn coordinates relative to the ones excell gave me

- There is that thing whith the decimal separator in Brazil (excell uses comma and AutoCad uses dot), and I still haven't figured that out.

- I'll probably have many polylines drawn this way (there'll be a bigger code that calls this one I'm making right now for each one) and I'm not sure how to organize this in excell

 

 

@hanhphuc:

Sorry, pal... I see you tried to guide me into the right direction - your code seems similar to the ziele_o2k posted - but I just can't figure out how that syntax is supposed to work.

It looks like a more direct coding and I would appreciate some instruction about it. Can you elaborate?

Edited by saim
code comments
Link to comment
Share on other sites

Use ID pick point paste into excel cell then pull apart X Y etc using the excel functions of substr. You can pick a point and put the value straight into a excel cell or two cells X & Y. Lots of examples out there.

Link to comment
Share on other sites

In the code you commented, there is the "'cmdactive" check. I didn't get it. Why do I need to check if a command is running when I just started it without ending?

Oh, forget it! I tried and it worked!!! YAY!!!

I edited the many questions I made because now this test answered them. The only remaining one is the above. Can you elaborate on that?

 

Lets hope i get this right. Basically, it's the controller for the control loop (the while loop) that allows command calls to be issued within a command. If it's > 1 something is active (script, lisp, dialog...), if it = 1 an ordinary command is active and if it's = 0 no command is active. If it wasn't there the next (command) call would cancel the previous one.

 

There are three ways to call commands in Autocad. Here are the links to the 2016 Help files :

 

 

command-s http://help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-5C9DC003-3DD2-4770-95E7-7E19A4EE19A1

 

 

command http://help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-1C989B35-2C5A-47EC-A0C9-71998EDFB157

 

 

vl-cmdf http://help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-6F1AAB6B-D5B1-426A-A463-0CBE93E4D956

 

 

If you've got Express Tools try typing "_.sysvdlg" to read up on cmdactive

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