# Thread: draw a polyline based on coordinates

1. ## draw a polyline based on coordinates

Registered forum members do not see this ad.

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)
Code:
`(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.
Code:
```(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!

2. Originally Posted by saim
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
Code:
```(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```

3. 1st
Code:
```; =========================================================================================== ;
; 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 (%)
)
)
(mapcar
(function
(lambda (%)
(trans % 1 (trans '(0 0 1) 1 0 T))
)
)
Pts
)
)
)
)
(setq obj
(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*
)
*cd-Blocks*
)
; =========================================================================================== ;
; Aktywny dokument / Active document                                                          ;
; =========================================================================================== ;
(or
*cd-ActiveDocument*
(setq *cd-ActiveDocument*
)
)
*cd-ActiveDocument*
)
(defun cd:ACX_Model ()
(or
*cd-ModelSpace*
)
*cd-ModelSpace*
)```
2nd
Code:
```; =========================================================================================== ;
; 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
)
)
)
)```

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

5. Code:
`(append (list '(0 . "LWPOLYLINE")'(100 ..) ... ) (mapcar ...) )`
Code:
`(vl-list* '(0 . "LWPOLYLINE") '(100 ..  )  . . (mapcar ... ) )`

6. Originally Posted by dlanorh
Not my code but perhaps you can understand this
Code:
```(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.
Code:
```(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:
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?

Originally Posted by BIGAL
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?

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

8. Registered forum members do not see this ad.

Originally Posted by saim
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/20...9-71998EDFB157

vl-cmdf http://help.autodesk.com/view/ACD/20...3-0CBE93E4D956

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

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts