Polyline SetBulge Arc factor

The Autocad VBA object AcadLWPolyline is made in straight line segments with AddLightWeightPolyline method using an array of coordinates. The LWPolyline object returned has a SetBulge method to change a straight line segment to an arc. Setbulge takes two parameters, the lower numbered index of the vertex that begins the segment, and a Bulge value. the Bulge value is explained thusly –

“The bulge is the tangent of 1/4 of the included angle for the arc between the selected vertex and the next vertex in the polyline’s vertex list. A negative bulge value indicates that the arc goes clockwise from the selected vertex to the next vertex. A bulge of 0 indicates a straight segment, and a bulge of 1 is a semicircle.”
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2017/ENU/AutoCAD-ActiveX/files/GUID-E1CE125E-AB3A-4645-B548-E43200064F9C-htm.html

The arc no matter what curvature it takes is always a part of a circle. Two lines drawn from the center to the vertexes define the included angle. This center moves along a line as the bulge factor changes. As the center gets closer to the arc, the angle gets larger. If the center moves far away the included angle gets small, the tangent of that angle is small, the arc is nearly a straight line, and the Bulge factor is small.

The gist of the code. Vertexes start numbering with zero.

Dim plineObj As AcadLWPolyline
Set plineObj = ThisDrawing.ModelSpace.AddLightWeightPolyline(points_array)
plineObj.SetBulge 3, -0.5

what does an even number 0.5 Bulge factor give?
2017-01-11_1

what Bulge factor would give an included angle of 90 deg?

2017-01-11_2

since B = TAN(PI/8) this can be entered directly in code

Sub B2_test()
Call connect_acad
Dim pt As Variant

pt = Array(0, 0, Cos(Pi / 4), Sin(-Pi / 4), Cos(Pi / 4), Sin(Pi / 4))
Call draw_array(pt)
global_plineobj.SetBulge 1, Tan(Pi / 8)

End Sub

To create a rounded fillet the vertexes of the arc have to be encoded in the square edge polyline, then rounded.
The B value for 90 degrees is 90/4 or 1/4 * pi/2. Here is a program to create a filleted rectangle of any size with any radius at any location. (the draw_array sub is posted previously)

2017-01-13_1

Sub B2_test_rectangle()
Call connect_acad
Dim pt As Variant
 Dim x1 As Double, x2 As Double, x3 As Double, x4 As Double
 Dim y1 As Double, y2 As Double, y3 As Double, y4 As Double
 Dim A As Double, B As Double, R As Double, Dx As Double, Dy As Double
'A is width X
'B is height Y
'R is fillet radius
'Dx and Dy are coordinates for lower left corner

A = 4
B = 5
R = 1
Dx = 2
Dy = 2
 
 x1 = Dx
 x2 = Dx + R
 x3 = A + Dx - R
 x4 = A + Dx
 
 y1 = Dy
 y2 = Dy + R
 y3 = B + Dy - R
 y4 = B + Dy
 
pt = Array(x2, y1, x3, y1, x4, y2, x4, y3, x3, y4, x2, y4, x1, y3, x1, y2)
Call draw_array(pt)
global_pline.SetBulge 1, Tan(Pi / 8)
global_pline.SetBulge 3, Tan(Pi / 8)
global_pline.SetBulge 5, Tan(Pi / 8)
global_pline.SetBulge 7, Tan(Pi / 8)

End Sub

A slot sub would simply draw a rectangle and use a B factor for the ends to give a 180 degree arc. Here is a routine for both vertical and horizontal slots. This could be combined into one program with a switch or flag. We would also call them with the dimensions as parameters. The B factor is the TAN of one fourth of 180 or pi/4.

2017-01-13_2

Sub B2_horz_slot()
Call connect_acad
Dim pt As Variant
 Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
 Dim A As Double, B As Double, Cx As Double, Cy As Double
'A is length
'B is width
'Cx and Cy are center coordinates

A = 2
B = 0.5
Cx = 3
Cy = 3
 
 x1 = Cx - A / 2
 x2 = Cx + A / 2
 
 y1 = Cy - B / 2
 y2 = Cy + B / 2
 
pt = Array(x1, y1, x2, y1, x2, y2, x1, y2)
Call draw_array(pt)
global_pline.SetBulge 1, Tan(Pi / 4)
global_pline.SetBulge 3, Tan(Pi / 4)
Call draw_point(Cx, Cy, 0) 'this draws a point for reference
End Sub


Sub B2_vert_slot()
Call connect_acad
Dim pt As Variant
 Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
 Dim A As Double, B As Double, Cx As Double, Cy As Double
'A is length
'B is width
'Cx and Cy are center coordinates

A = 2
B = 0.5
Cx = 3
Cy = 3
 
 x1 = Cx - B / 2
 x2 = Cx + B / 2
 
 y1 = Cy - A / 2
 y2 = Cy + A / 2
 
pt = Array(x1, y1, x2, y1, x2, y2, x1, y2)
Call draw_array(pt)
global_pline.SetBulge 0, Tan(Pi / 4)
global_pline.SetBulge 2, Tan(Pi / 4)
Call draw_point(Cx, Cy, 0)
End Sub

autodesk (or somebody) made the B factor the tan of one fourth the included angle. As the included arc varies from zero to almost 360, one fourth of that angle varies from zero to almost 90, and the tangent of that angle (Bulge Factor B) varies from zero to infinity. Because of the imprecision of doubles, Tan(Pi/2) should give an error, the slope of a vertical line, divide by zero, but the imprecision causes an arc with a very large radius.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s