Author Topic: Drawing a polyline (well it's more complicated than that)  (Read 5388 times)

0 Members and 1 Guest are viewing this topic.

iliekater

  • Guest
Drawing a polyline (well it's more complicated than that)
« on: December 19, 2007, 02:07:37 AM »
Is it possiple to draw a PLINE with LISP if we have a list with variables (variables that could be either points or list of coordinates - you choose what's easier) ?
I know I can do something like that with VBA (although in that case I had to use an array) but I wonder if I can do that with LISP since it's easy to me to create a list with all points that I want to unite .
« Last Edit: December 22, 2007, 07:25:22 AM by iliekater »

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Drawing a polyline (well it's more complicated than that)
« Reply #1 on: December 19, 2007, 02:27:35 AM »
Hi,

You can see this reply
Speaking English as a French Frog

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8785
  • AKA Daniel
Re: Drawing a polyline (well it's more complicated than that)
« Reply #2 on: December 19, 2007, 02:31:27 AM »
like this?

Code: [Select]
(defun c:doit (/            activedocument            iacadapplication
               modelspace   paperspace   pt1          pt2
               pt3          pt4          pt5
              )
  (vl-load-com)
  (setq IAcadApplication (vlax-get-acad-object)
        ActiveDocument   (vla-get-ActiveDocument IAcadApplication)
        PaperSpace       (vla-get-PaperSpace ActiveDocument)
        ModelSpace       (vla-get-ModelSpace ActiveDocument)
  )
  (setq pt1 '(0 0 0))
  (setq pt2 '(0 100 0))
  (setq pt3 '(100 100 0))
  (setq pt4 '(100 0 0))
  (setq pt5 '(0 0 0))
  (DrawLwPolyLine ModelSpace (list pt1 pt2 pt3 pt4 pt5) "0")
  (princ)
)
;;;-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-
;;;DrawLwPolyLine DocSpace (list pt1 pt2 pt3) layer
;;;-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-
(defun DrawLwPolyLine (DocSpace PointList layer / e plist ptl)
  (setq ptl   PointList
        plist '()
  )
  (foreach e ptl
    (setq plist (cons (car e) plist)
          plist (cons (cadr e) plist)
    )
  )
  (vla-put-layer
    (vla-addLightweightPolyline
      DocSpace
      (vlax-safearray-fill
        (vlax-make-safearray
          vlax-vbDouble
          (cons 0
                (-
                  (length plist)
                  1
                )
          )
        )
        (reverse plist)
      )
    )
    layer
  )
)


edit: Oops Gile beat me to it

Joe Burke

  • Guest
Re: Drawing a polyline (well it's more complicated than that)
« Reply #3 on: December 19, 2007, 09:57:33 AM »
Personally I prefer entmake vs vlisp for a new lwpline because it accepts a 2D or 3D point list (dropping off the Z value in that case) whereas the vlisp method is more picky about what it will accept.

The methods are the same speed-wise.

iliekater

  • Guest
Re: Drawing a polyline (well it's more complicated than that)
« Reply #4 on: December 22, 2007, 07:24:04 AM »
Thanks a lot guys . I used it and it did work . The only thing I changed was the
Code: [Select]
"0"in the
Code: [Select]
c:doit function , in order to use the layer I want . I suppose you used "0" in order to make sure that the layer should exist so as not to use useless code to see if it exists. Thanks again !

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8785
  • AKA Daniel
Re: Drawing a polyline (well it's more complicated than that)
« Reply #5 on: December 22, 2007, 07:47:22 AM »
Thanks a lot guys . I used it and it did work . The only thing I changed was the
Code: [Select]
"0"in the
Code: [Select]
c:doit function , in order to use the layer I want . I suppose you used "0" in order to make sure that the layer should exist so as not to use useless code to see if it exists. Thanks again !


Glad it worked  :-)
You should probably add some sort of layer verification method.



iliekater

  • Guest
Re: Drawing a polyline (well it's more complicated than that)
« Reply #6 on: December 22, 2007, 09:54:50 AM »
Thanks , don't worry ; I have !  ;-)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Drawing a polyline (well it's more complicated than that)
« Reply #7 on: December 22, 2007, 10:22:26 PM »
I like gile's example.
Code: [Select]
;;  wraper function created by CAB using entmake code by gile
;;  Expects pts to be a list of 2D or 3D points
;;  Returns the ename of the new pline object
(defun makePline (pts    ; list of points
                  closed ; 1 for closed 0 overwise
                  layer  ; if new layer entmake will create it
                  ;;  must be a valid layer name
                  / elv zdir)
  ;;  add zero Z if 2D point list - CAB added
  (setq pts (mapcar '(lambda(x) (if (=(length x)2)(append x '(0.0))x)) pts))
  ;; catch nil layer name - CAB added
  (or layer (setq layer (getvar "CLAYER")))
 
  ;;  code by gile, modified by CAB
  (setq zdir (trans '(0 0 1) 1 0 t)
        elv  (caddr (trans (car pts) 1 zdir))
  )
  (entmakex ; mod by CAB added x
    (append
      (list '(0 . "LWPOLYLINE")
            '(100 . "AcDbEntity")
            '(100 . "AcDbPolyline")
            (cons 8  layer) ; CAB added
            (cons 90 (length pts))
            (cons 70 closed) ; 1 for closed 0 overwise
            (cons 38 elv)
            (cons 210 zdir)
      )
      (mapcar '(lambda (pt) (cons 10 (trans pt 1 zdir))) pts)
    )
  )
)

Code: [Select]
;;  Test the MakePline
(defun c:DrawPline (/ pt ofs ang ll lr ur ul)
  (if (setq pt (getpoint "\nPick point for center of rectangle"))
    (progn
      (setq ofs 50.0
            ang 0.0 ; base angle
      )
      (setq ll (polar pt (- ang (* pi 0.75)) (sqrt (* (* ofs ofs) 2)))
            lr (polar pt (- ang (/ pi 4)) (sqrt (* (* ofs ofs) 2)))
            ur (polar pt (+ ang (/ pi 4)) (sqrt (* (* ofs ofs) 2)))
            ul (polar pt (+ ang (* pi 0.75)) (sqrt (* (* ofs ofs) 2)))
      )
      (makePline (list ll lr ur ul) 1 "LayerName")
    )
  )
  (princ)
)
« Last Edit: December 23, 2007, 08:31:34 AM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8785
  • AKA Daniel
Re: Drawing a polyline (well it's more complicated than that)
« Reply #8 on: December 22, 2007, 11:35:47 PM »
Interesting, Why the use of entmakex?

Never Mind, .. its in the docs, Nice coding Gile & Cab


gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Drawing a polyline (well it's more complicated than that)
« Reply #9 on: December 23, 2007, 03:22:07 AM »
Quote
I like gile's example
Thanks Alan,

But I don't understand why do you add this:
Quote
;;  add zero Z if 2D point list - CAB added
  (setq pts (mapcar '(lambda(x) (if (=(length x)2)(append x '(0.0))x)) pts))

As said Joe, entmake works as well with 2D or 3D points and the Z value is dropped off in the final data list.
« Last Edit: December 23, 2007, 04:53:12 AM by gile »
Speaking English as a French Frog

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Drawing a polyline (well it's more complicated than that)
« Reply #10 on: December 23, 2007, 08:25:36 AM »
Because your code
Code: [Select]
elv  (caddr (trans (car pts) 1 zdir))is looking for the Z. I could have conditionally removed that but it seemed to me to be easier to
understand the final code the way I did it. Perhaps & should have only added the Z to the first point only.
OK, this may be better.
Code: [Select]
;;  Expects pts to be a list of 2D or 3D points
;;  Returns the ename of the new pline object
(defun makePline (pts    ; list of points
                  closed ; 1 for closed 0 overwise
                  layer  ; if new layer entmake will create it
                  ;;  must be a valid layer name
                  / zdir elv)
  ;; catch nil layer name - CAB added
  (or layer (setq layer (getvar "CLAYER")))
 
  ;;  code by gile, modified by CAB
  (if (caddr pts)
    (setq zdir (trans '(0 0 1) 1 0 t)
          elv  (caddr (trans (car pts) 1 zdir))
    )
  )
  (entmakex ; CAB added x
    (append
      (list '(0 . "LWPOLYLINE")
            '(100 . "AcDbEntity")
            '(100 . "AcDbPolyline")
            (cons 8  layer) ; CAB added
            (cons 90 (length pts))
            (cons 70 closed) ; 1 for closed 0 overwise
            (if elv (cons 38 elv) '(38 . 0.))
            (if zdir (cons 210 zdir) '(210 0. 0. 1.))
      )
      (mapcar '(lambda (pt) (cons 10 (trans pt 1 zdir))) pts)
    )
  )
)
« Last Edit: December 23, 2007, 08:30:46 AM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Drawing a polyline (well it's more complicated than that)
« Reply #11 on: December 23, 2007, 10:00:29 AM »
Don't worry with the Z coordinate the trans function will add it if it doesn't exist yet:
(trans '(2 3) 1 1) returns (2.0 3.0 0.0)
so, (setq elv  (caddr (trans (car pts) 1 zdir))) will return 0.0 if (car pts) is a 2D point, the z coordinates overwise.

Try to run (makepline '((0 0) (1 0) (1 1) (0 1)) 1 nil) with this defun:

Code: [Select]
;;  Expects pts to be a list of 2D or 3D points
;;  Returns the ename of the new pline object
(defun makePline (pts ; list of points
  closed ; 1 for closed 0 overwise
  layer ; if new layer entmake will create it
  ;;  must be a valid layer name
  / zdir elv)
  ;; catch nil layer name - CAB added
  (or layer (setq layer (getvar "CLAYER")))

  (setq zdir (trans '(0 0 1) 1 0 t)
elv  (caddr (trans (car pts) 1 zdir))
  )
  (entmakex ; CAB added x
    (append
      (list '(0 . "LWPOLYLINE")
    '(100 . "AcDbEntity")
    '(100 . "AcDbPolyline")
    (cons 8 layer) ; CAB added
    (cons 90 (length pts))
    (cons 70 closed) ; 1 for closed 0 overwise
    (cons 38 elv)
    (cons 210 zdir)
      )
      (mapcar '(lambda (pt) (cons 10 (trans pt 1 zdir))) pts)
    )
  )
)

« Last Edit: December 23, 2007, 01:21:25 PM by gile »
Speaking English as a French Frog

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Drawing a polyline (well it's more complicated than that)
« Reply #12 on: December 23, 2007, 01:59:15 PM »
Silly me for not testing it. I thought trans would choke on a 2D point.
Thanks gile.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Drawing a polyline (well it's more complicated than that)
« Reply #13 on: December 24, 2007, 02:32:46 PM »
Just wanted to play with the routine a little.

I'm sure others can improve on my coding abilities...

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Drawing a polyline (well it's more complicated than that)
« Reply #14 on: December 24, 2007, 02:46:54 PM »
Nothing wrong with that Gary.
I almost always prefer getdist over getreal and I would use this
Code: [Select]
(or a (setq a 0.0))just a personal preference.

Merry Christmas
Alan
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.