 # Visual LISP & Polylines - Part 2

This is the VBA method to create a lightweight polyline from a list of vertices.

`RetVal = object.AddLightweightPolyline(VerticesList)`
• Object : ModelSpace Collection, PaperSpace Collection, Block. The object or objects this method applies to.
• VerticesList : Variant (array of doubles). The array of 2D OCS coordinates specifying the vertices of the polyline. At least two points (four elements) are required for constructing a lightweight polyline. The array size must be a multiple of 2.
• RetVal : LightweightPolyline object. The newly created LightweightPolyline object.

In Visual Lisp, the syntax would be as follows :

`(vla-addLightweightPolyline Object VerticesList)`

and would return `RetVal`.

## The Process

Let's try this out. First we need a reference to Model Space :

```_\$ (setq mspace (vla-get-modelSpace (vla-get-activeDocument
```

Get the first point :

```_\$ (setq pt1 (getpoint))
(424.505 252.213 0.0)
```

Extract the X and Y coordinates

```_\$ (setq pt1 (list (car pt1) (cadr pt1)))
(424.505 252.213)
```

And now the second point :

```_\$ (setq pt2 (getpoint))
(767.689 518.148 0.0)
```

Extract the X and Y coordinates :

```_\$ (setq pt2 (list (car pt2) (cadr pt2)))
(767.689 518.148)
```

Join the the two lists together :

```_\$ (setq pt1 (append pt1 pt2))
(424.505 252.213 767.689 518.148)
```

Construct a 4 element safearray :

```_\$ (setq anarray (vlax-make-safearray vlax-vbDouble '(0 . 3)))
#<safearray...>
```

Fill it with our point X and Y values :

```_\$ (vlax-safearray-fill anarray pt1)
#<safearray...>
```

Draw the polyline :

```_\$ (setq myobj (vla-addLightweightPolyline mspace anarray))
```

## A Practical Example

Let's now have a look how we could apply this to a practical example :

```;CODING STARTS HERE

(prompt "\nType \"VL-Steel\" to run......")

;set up default rotation angle
(if (= rot nil) (setq rot 0))

;define the function and declare all local variables
(defun C:VL-Steel ( / ptlist oldsnap oldecho oldblip acaddoc util mspace names sizes
dcl_id siza userclick dlist H B T1 T2 R1 IP IPA P1 ptlisp tmp myobj fname fn pts)

;obtain reference to the Active Document

;obtain reference to Utilities
(setq util (vla-get-utility acaddoc))

;obtain reference to Model Space
(setq mspace (vla-get-modelSpace acaddoc))

;store system variables
(setq oldsnap (vla-getvariable acaddoc "OSMODE")
oldecho  (vla-getvariable acaddoc "CMDECHO")
oldblip  (vla-getvariable acaddoc "BLIPMODE")
);setq

;switch off system variables
(vla-setvariable acaddoc "CMDECHO" 0)
(vla-setvariable acaddoc "BLIPMODE" 0)

;create list of steel sections for the list box
(setq names '("100x55x8" "120x64x10" "140x73x13" "160x82x16"
"180x91x19" "200x100x22" "203x133x25" "203x133x30" "254x146x31"
"254x146x37" "254x146x43" ) )

;create list of steel section values
(setq sizes '((100.0 55.0 4.1 5.7 7.0)
(120.0 64.0 4.4 6.3 7.0) (140.0 73.0 4.7 6.9 7.0)
(160.0 82.0 5.0 7.4 9.0) (180.0 91.0 5.3 8.0 9.0)
(200.0 100.0 5.6 8.5 12.0) (203.2 133.4 5.8 7.8 7.6)
(206.8 133.8 6.3 9.6 7.6) (251.5 146.1 6.1 8.6 7.6)
(256.0 146.4 6.4 10.9 7.6) (259.6 147.3 7.3 12.7 7.6)))

;construct the dialog
(create_dialog)

(setq dcl_id (load_dialog fname))
(if (not (new_dialog "ubeam" dcl_id))
(exit)
)

;setup the list box
(start_list "selections")
(end_list)

;default rotation angle
(set_tile "rot" (rtos rot))

;setup the Cancel button
(action_tile
"cancel"
"(done_dialog) (setq userclick nil)"
)

;setup the OK button
(action_tile
"accept"
(strcat
"(progn (setq siza (atof (get_tile \"selections\")))
(setq rot (atof (get_tile \"rot\")))"
"(done_dialog) (setq userclick T))" )
)

;display the dialog
(start_dialog)

;delete the temp DCL file
(vl-file-delete fname)

;if the OK button was selected
(if userclick

;do the following
(progn

;retrieve the steel section values
(setq dlist (nth (fix siza) sizes))

;place them into variables
(mapcar 'set '(H B T1 T2 R1) dlist)

;switch on the intersection snap
(vla-setvariable acaddoc "OSMODE" 32)

;get the insertion point
(setq IP (vla-getpoint util nil "\nInsertion Point : "))

;switch off the snaps
(vla-setvariable acaddoc "OSMODE" 0)

;calculate the points and store them in a list
(setq pts (list
(setq P1 (vla-polarpoint util IP 0 (/ T1 2)))
(setq P1 (vla-polarpoint util P1 (DTR 90.0)
(/ (- H (+ T2 T2 R1 R1)) 2)))
(setq P1 (vla-polarpoint util P1 (DTR 45.0)
(sqrt (* R1 R1 2.0))))
(setq P1 (vla-polarpoint util P1 0
(/ (- B (+ T1 R1 R1)) 2)))
(setq P1 (vla-polarpoint util P1 (DTR 90.0) T2))
(setq P1 (vla-polarpoint util P1 (DTR 180.0) B))
(setq P1 (vla-polarpoint util P1 (DTR 270.0) T2))
(setq P1 (vla-polarpoint util P1 0
(/ (- B (+ T1 R1 R1)) 2)))
(setq P1 (vla-polarpoint util P1 (DTR 315.0)
(sqrt (* R1 R1 2.0))))
(setq P1 (vla-polarpoint util P1 (DTR 270.0)
(- H (+ T2 T2 R1 R1))))
(setq P1 (vla-polarpoint util P1 (DTR 225.0)
(sqrt (* R1 R1 2.0))))
(setq P1 (vla-polarpoint util P1 (DTR 180.0)
(/ (- B (+ T1 R1 R1)) 2)))
(setq P1 (vla-polarpoint util P1 (DTR 270.0) T2))
(setq P1 (vla-polarpoint util P1 0 B))
(setq P1 (vla-polarpoint util P1 (DTR 90.0) T2))
(setq P1 (vla-polarpoint util P1 (DTR 180.0)
(/ (- B (+ T1 R1 R1)) 2)))
(setq P1 (vla-polarpoint util P1 (DTR 135.0)
(sqrt (* R1 R1 2.0))))
(setq P1 (vla-polarpoint util IP 0 (/ T1 2)))
));setq

;extract only the X and Y values of each point list
(mapcar

'(lambda  (pt)

;convert to lists
(setq pt (vlax-safearray->list (variant-value pt)))

;X and Y values only
(setq ptlist (cons (list (car pt) (cadr pt)) ptlist))

);lambda

pts

);mapcar

;break the point list up into elements
(setq ptlist (apply 'append ptlist))

;create a safearray to store the elements
(setq tmp (vlax-make-safearray vlax-vbDouble
(cons 0 (- (vl-list-length ptlist) 1))))

;fill the safearray
(vlax-safearray-fill tmp ptlist)

;draw the steel section
(setq myobj (vla-addLightweightPolyline mspace tmp))

(vla-setbulge myobj 1 0.4142)
(vla-setbulge myobj 7 0.4142)
(vla-setbulge myobj 9 0.4142)
(vla-setbulge myobj 15 0.4142)

;rotate the object
(vla-rotate myobj ip (dtr rot))

);progn

);if

;reset system variables
(vla-setvariable acaddoc "OSMODE" oldsnap)
(vla-setvariable acaddoc "CMDECHO" oldecho)
(vla-setvariable acaddoc "BLIPMODE" oldblip)

;release all objects
(vlax-release-object mspace)
(vlax-release-object util)

;finish clean
(princ)

);defun

;--------------------------
(defun create_dialog ()

;create a temp DCL file
(setq fname (vl-filename-mktemp "dcl.dcl"))

;open it to write
(setq fn (open fname "w"))

;write the dialog coding
(write-line
"ubeam : dialog {
label = \"VL-Steel\";
: list_box {
label = \"Choose Section :\";
key = \"selections\";
allow_accept = true;
height = 8;
}
: edit_box {
label = \"Rotation Angle :\";
key = \"rot\";
edit_limit = 4;
edit_width = 4;
}
spacer;
ok_cancel ;
:text_part {
label = \"Designed and Created\";
}
:text_part {
label = \"by Kenny Ramage\";
}
}" fn)

;close the temp DCL file
(close fn)

);defun
;------------------------------

;convert degrees to radians

(defun DTR (a)

(* pi (/ a 180))

);defun

;---------------------------------

(princ)

;CODING ENDS HERE
```

Save this as VL-Steel.lsp and then load and run it. A dialog like this will appear : Choose the section size you would like, choose a rotation angle, select an insertion point, and voila, your steel section is drawn using a polyline.

"OK Kenny, now we give in. HOW do you calculate a bulge?"

Bulge = TAN ( / Included Angle 4)

In our case Bulge = TAN ( / 90 4) = 0.4142

Thanks to Stig Madsen for the insight into some of this coding.