+ Reply to Thread
Results 1 to 8 of 8
  1. #1
    Full Member
    Using
    AutoCAD 2012
    Join Date
    Sep 2011
    Posts
    33

    Default 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. #2
    Full Member
    Discipline
    Surveying
    dlanorh's Discipline Details
    Occupation
    Geospatial Engineer
    Discipline
    Surveying
    Using
    AutoCAD 2012
    Join Date
    Aug 2017
    Location
    UK/Bundesrepublik Deutschland
    Posts
    65

    Default

    Quote Originally Posted by saim View Post
    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. #3
    Senior Member ziele_o2k's Avatar
    Discipline
    Construction
    Using
    AutoCAD 2018
    Join Date
    Jun 2014
    Location
    Poland
    Posts
    128

    Default

    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 (%)
                (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
    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
          )
        )
      )
    )
    all from CADPL-Pack-v1

  4. #4
    Quantum Mechanic
    Using
    Civil 3D 2016
    Join Date
    Dec 2005
    Location
    GEELONG AUSTRALIA
    Posts
    10,499

    Default

    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.
    A man who never made mistakes never made anything

  5. #5
    Super Member hanhphuc's Avatar
    Using
    AutoCAD 2007
    Join Date
    Apr 2013
    Location
    Happy Garden
    Posts
    655

    Default

    Code:
    (append (list '(0 . "LWPOLYLINE")'(100 ..) ... ) (mapcar ...) )
    Code:
    (vl-list* '(0 . "LWPOLYLINE") '(100 ..  )  . . (mapcar ... ) )
    _$ ( apply 'equal "hp" "happy" "hạnh phúc" "ハッピー" "幸福" "행복" )
    ; error: too many arguments

  6. #6
    Full Member
    Using
    AutoCAD 2012
    Join Date
    Sep 2011
    Posts
    33

    Default

    Quote Originally Posted by dlanorh View Post
    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?



    Quote Originally Posted by BIGAL View Post
    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?
    Last edited by saim; 18th May 2018 at 01:56 pm. Reason: code comments

  7. #7
    Quantum Mechanic
    Using
    Civil 3D 2016
    Join Date
    Dec 2005
    Location
    GEELONG AUSTRALIA
    Posts
    10,499

    Default

    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.
    A man who never made mistakes never made anything

  8. #8
    Full Member
    Discipline
    Surveying
    dlanorh's Discipline Details
    Occupation
    Geospatial Engineer
    Discipline
    Surveying
    Using
    AutoCAD 2012
    Join Date
    Aug 2017
    Location
    UK/Bundesrepublik Deutschland
    Posts
    65

    Default

    Registered forum members do not see this ad.

    Quote Originally Posted by saim View Post
    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

Similar Threads

  1. Draw Polyline with x,y, & z coordinates from collection of arrays
    By Jalen Weir in forum .NET, ObjectARX & VBA
    Replies: 6
    Last Post: 24th Nov 2015, 10:45 pm
  2. Specifying Insertion Point of object based on X and Y Coordinates
    By edoll in forum AutoCAD 2D Drafting, Object Properties & Interface
    Replies: 2
    Last Post: 5th Mar 2014, 09:43 am
  3. Select Objects Based on Block Coordinates
    By smweil in forum AutoLISP, Visual LISP & DCL
    Replies: 11
    Last Post: 6th Sep 2011, 08:03 pm
  4. Scaling a polyline based on its area
    By harilalmn in forum AutoCAD General
    Replies: 2
    Last Post: 12th Jan 2011, 12:34 pm
  5. Draw rectangle/square, based on 2 or 3 picked points...
    By alanjt in forum AutoLISP, Visual LISP & DCL
    Replies: 0
    Last Post: 27th Jul 2010, 04:50 pm

Bookmarks

Posting Permissions

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