PDA

View Full Version : vla-addpolyline


ccowgill
2007-10-15, 05:21 PM
could someone please post an example of how to use vla-addpolyline. I mostly need the formating for the list of points. I am passing points to the polyline but I keep getting errors. right now, my code just draws 3 separate lines, but I would like to shorten it up.

here is my current program:

(defun c:waterbracket (/ obj objent objentdata objdir itm xobj yobj hobj wobjhorz1 horz2 vert1)
(prompt "\nSelect Mtext object and leader\n")
(setq obj (ssget)
objent (ssname obj 0)
objentdata (entget objent)
) ;_ select object
(if (equal (assoc 0 objentdata) '(0 . "LEADER"))
(progn
(if (equal (cadr (assoc 213 objentdata)) 0.0)
(setq objdir "right")
(setq objdir "left")
)
(setq objent (ssname obj 1)
objentdata (entget objent)
)
)
(progn
(setq objent (ssname obj 1)
objentdata (entget objent)
)
(if (equal (cadr (assoc 213 objentdata)) 0.0)
(setq objdir "right")
(setq objdir "left")
)
(setq objent (ssname obj 0)
objentdata (entget objent)
)
)
)
(if (/= (equal (assoc 73 objentdata) '(73 . 2)) t)
(progn
(setq objentdata
(subst '(73 . 2) (assoc 73 objentdata) objentdata)
)
(entmod objentdata)
)
)
(foreach itm objentdata
(cond ((= (car itm) 10) ;_ get insert point
(setq yobj (cadr (cdr itm))
xobj (car (cdr itm))
)
)
((= (car itm) 43)
(setq hobj (cdr itm))
)
((= (car itm) 42)
(setq wobj (cdr itm))
)
)
)
(if (= objdir "left")
(progn
(setq horz1
(vla-addline
acadPaperSpace
(vlax-3d-point
(list (- (+ xobj wobj) 0.04) (+ yobj 0.04) 0)
) ;_ end of vlax-3d-point
(vlax-3d-point
(list (+ (+ xobj wobj) 0.04) (+ yobj 0.04) 0)
) ;_ end of vlax-3d-point
) ;_ end of vla-addline
vert1 (vla-addline
acadPaperSpace
(vlax-3d-point
(list (+ (+ xobj wobj) 0.04) (+ yobj 0.04) 0)
) ;_ end of vlax-3d-point
(vlax-3d-point
(list (+ (+ xobj wobj) 0.04) (- yobj hobj) 0)
) ;_ end of vlax-3d-point

) ;_ end of vla-addline
horz2 (vla-addline
acadPaperSpace
(vlax-3d-point
(list (+ (+ xobj wobj) 0.04) (- yobj hobj) 0)
) ;_ end of vlax-3d-point
(vlax-3d-point
(list (- (+ xobj wobj) 0.04) (- yobj hobj) 0)
) ;_ end of vlax-3d-point
) ;_ end of vla-addline
) ;_ end of setq
(vla-put-layer vert1 "Dim")
(vla-put-layer horz1 "Dim")
(vla-put-layer horz2 "Dim")
)
)
(if (= objdir "right")
(progn
(setq horz1
(vla-addline
acadPaperSpace
(vlax-3d-point
(list (+ xobj 0.04) (+ yobj (/ 2. 75)) 0)
) ;_ end of vlax-3d-point
(vlax-3d-point
(list (- xobj 0.04) (+ yobj (/ 2. 75)) 0)
) ;_ end of vlax-3d-point
) ;_ end of vla-addline
vert1 (vla-addline
acadPaperSpace
(vlax-3d-point
(list (- xobj 0.04) (+ yobj (/ 2. 75)) 0)
) ;_ end of vlax-3d-point
(vlax-3d-point
(list (- xobj 0.04) (- yobj hobj) 0)
) ;_ end of vlax-3d-point

) ;_ end of vla-addline
horz2 (vla-addline
acadPaperSpace
(vlax-3d-point
(list (- xobj 0.04) (- yobj hobj) 0)
) ;_ end of vlax-3d-point
(vlax-3d-point
(list (+ xobj 0.04) (- yobj hobj) 0)
) ;_ end of vlax-3d-point
) ;_ end of vla-addline
) ;_ end of setq
(vla-put-layer vert1 "Dim")
(vla-put-layer horz1 "Dim")
(vla-put-layer horz2 "Dim")
)
)
;add 2/75 to y coord dxf 10
;add .04 to x coord dxf 10
;get height of object dxf 43
;draw polyline x-.08 down height + 2/75 x+.08
)


Thanks,

T.Willey
2007-10-15, 05:25 PM
Say you pick three points, and you want that to be your polyline. Use code like

(vlax-invoke
CurSpace
'AddLightweightPolyline
(list
(car Pt1) (cadr Pt1)
(car Pt2) (cadr Pt2)
(car Pt3) (cadr Pt3)
)
)

CAB2k
2007-10-15, 08:44 PM
Yea, the other way can be a pita.
;; by CAB 10/05/2007
;; Expects pts to be a list of 2D or 3D points
;; Returns new pline object
(defun makePline (spc pts)
;; flatten the point list to 2d
(if (= (length (car pts)) 2) ; 2d point list
(setq pts (apply 'append pts))
(setq pts (apply 'append (mapcar '(lambda (x) (list (car x) (cadr x))) pts)))
)
(setq
pts (vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray vlax-vbdouble (cons 0 (1- (length pts))))
pts
)
)
)
(vla-addlightweightpolyline spc pts)
)

ccowgill
2007-10-15, 10:51 PM
Say you pick three points, and you want that to be your polyline. Use code like

(vlax-invoke
CurSpace
'AddLightweightPolyline
(list
(car Pt1) (cadr Pt1)
(car Pt2) (cadr Pt2)
(car Pt3) (cadr Pt3)
)
)


Worked great with my program. Sorry Alan that it took so long to get back to the post, I hope you didnt spend too much time working on your version. although it is good to know there is more than one way to skin a cat.

CAB2k
2007-10-15, 11:40 PM
My version was done on the 5th for another lisp. So it didn't cost me any time to reply. :)

ccowgill
2008-03-18, 06:58 PM
Yea, the other way can be a pita.
;; by CAB 10/05/2007
;; Expects pts to be a list of 2D or 3D points
;; Returns new pline object
(defun makePline (spc pts)
;; flatten the point list to 2d
(if (= (length (car pts)) 2) ; 2d point list
(setq pts (apply 'append pts))
(setq pts (apply 'append (mapcar '(lambda (x) (list (car x) (cadr x))) pts)))
)
(setq
pts (vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray vlax-vbdouble (cons 0 (1- (length pts))))
pts
)
)
)
(vla-addlightweightpolyline spc pts)
)
Alan, any chance that your code can be easily modified to allow input for arcs within the polyline. I have a complex list of points that need to be input into a pline. the format will be close to this:
'((0,0,0)(1,0,0)(a)(s)(1.5,1,0)(2,1.25,0)(l)(3,1,0))
the list is designed more towards the polyline command, i just need to convert it into something usable. if you follow the commandline form, startpoint, point 1, a for arc, s for second point, point2, end of arc point, l for line segment, point 4

'gile'
2008-03-18, 08:53 PM
Hi,

To make arcs in lwpolylines using ActiveX, you have to use the vla-setBulge function with 2 arguments, the index of the vertex (start point of the arc) and the bulge value.
The bulge value is equal to the tangent of the quarter of the arc angle (negative if the arc is clockwise, positive otherwise)

So in your example, if the arc start point is (1.5 1 0) at index 2 and the end point (2 1.25 0) and if you want the arc to be tangent with the previous segment (as in the AutoCAD command), you can calc the bulge this way:

;; TAN
;; Returns the tangent of an angle (radians)
(defun tan (a) (/ (sin a) (cos a)))

;; Create the pline with CAB's routine
(setq pline (makePline (vla-get-ModelSpace
(vla-get-ActiveDocument
(vlax-get-acad-object)
)
)
'((0 0 0) (1 0 0) (1.5 1 0) (2 1.25 0) (3 1 0))
)
)

;; Calculate the bulge on third segment tangent to the second one
(setq bulge (tan (/ (- (angle '(1.5 1 0) '(2 1.25 0))
(angle '(1 0 0) '(1.5 1 0))
)
2
)
)
)

;; set the bulge to the pline segment
(vla-setBulge pline 2 bulge)

ccowgill
2008-03-24, 05:38 PM
Hi,

To make arcs in lwpolylines using ActiveX, you have to use the vla-setBulge function with 2 arguments, the index of the vertex (start point of the arc) and the bulge value.
The bulge value is equal to the tangent of the quarter of the arc angle (negative if the arc is clockwise, positive otherwise)

So in your example, if the arc start point is (1.5 1 0) at index 2 and the end point (2 1.25 0) and if you want the arc to be tangent with the previous segment (as in the AutoCAD command), you can calc the bulge this way:

;; TAN
;; Returns the tangent of an angle (radians)
(defun tan (a) (/ (sin a) (cos a)))

;; Create the pline with CAB's routine
(setq pline (makePline (vla-get-ModelSpace
(vla-get-ActiveDocument
(vlax-get-acad-object)
)
)
'((0 0 0) (1 0 0) (1.5 1 0) (2 1.25 0) (3 1 0))
)
)

;; Calculate the bulge on third segment tangent to the second one
(setq bulge (tan (/ (- (angle '(1.5 1 0) '(2 1.25 0))
(angle '(1 0 0) '(1.5 1 0))
)
2
)
)
)

;; set the bulge to the pline segment
(vla-setBulge pline 2 bulge)
what if I dont want it to be tangent to the previous section. what if I have just 3 points and I want the arc to pass through all 3 points.

'gile'
2008-03-24, 11:56 PM
what if I have just 3 points and I want the arc to pass through all 3 points

Using some sub routines

;; Returns the middle of two points
(defun mid-pt (p1 p2)
(mapcar
(function
(lambda (x)
(/ x 2.0)
)
)
(mapcar '+ p1 p2)
)
)

;; Returns T if p1 p2 p3 are clockwise
(defun clockwise-p (p1 p2 p3)
(< (sin (- (angle p1 p3) (angle p1 p2))) -1e-14)
)

;; Returns a list: (center radius angle) of an arc defined by 3 points
(defun arc3points (p1 p2 p3 / m1 m2 cen ang)
(setq cen (inters
(setq m1 (mid-pt p1 p2))
(polar m1 (+ (angle p1 p2) (/ pi 2)) 1.0)
(setq m2 (mid-pt p2 p3))
(polar m2 (+ (angle p2 p3) (/ pi 2)) 1.0)
nil
)
ang (- (angle cen p3) (angle cen p1))
)
(list cen
(distance cen p1)
(cond
((and (clockwise-p p1 p2 p3) (< 0 ang)) (- ang (* 2 pi)))
((and (clockwise-p p3 p2 p1) (< ang 0)) (+ ang (* 2 pi)))
(T ang)
)
)
)

;; Returns the tangent of an angle
(defun tan (a) (/ (sin a) (cos a)))

;; Draws a polyarc defined by 3 points
(defun example (p1 p2 p3 / pl)
(setq pl
(vlax-invoke
(vla-get-ModelSpace
(vla-get-activeDocument
(vlax-get-acad-object)
)
)
'addLightWeightPolyline
(list (car p1) (cadr p1) (car p3) (cadr p3))
)
)
(vla-setBulge
pl
0
(tan (/ (caddr (arc3points p1 p2 p3)) 4.0))
)
)