A better description of a bulge is the tangent of the arc's rise/1/2 the segment length
Function RadiusFromBulge(Bulge As Double, pt1, pt2) As Double
Dim Dist As Double, Rad As Double
Dist = 0.5 * Length(pt1, pt2)
RadiusFromBulge = Abs(Dist / Sin(Atn(Bulge) * 2))
End Function
Public Function CenterFromBulge(P1, P2, Bulge As Double)
If UBound(P1) = 1 Then
ReDim Preserve P1(2)
End If
If UBound(P2) = 1 Then
ReDim Preserve P2(2)
End If
Dim Ang As Double, CenPt(2) As Double
Dim Rad As Double, Dist As Double
Dist = Length(P1, P2) 'Use your length function
Rad = Abs(0.5 * Dist / Sin(Atn(Bulge) * 2))
Ang = ThisDrawing.Utility.AngleFromXAxis(P1, P2)
If Bulge > 0 Then
Ang = Ang + ((0.5 * pi) - (Atn(Bulge) * 2))
Else
Ang = Ang - ((0.5 * pi) + (Atn(Bulge) * 2))
End If
CenPt(0) = P1(0) + Cos(Ang) * Rad
CenPt(1) = P1(1) + Sin(Ang) * Rad
CenPt(2) = 0
CenterFromBulge = CenPt
End Function
This looks long winded but it's optimised for x,y points(pline coordinates) or x,y,z points
Kerry asked the question "Is it better to multiply or use ^2.
It goes faster using multiplication.
Public Function Length(StartPoint As Variant, EndPoint As Variant) As Double
Dim Stx As Double, Sty As Double, Stz As Double
Dim Enx As Double, Eny As Double, Enz As Double
Dim dX As Double, dY As Double, Dz As Double
Dim i As Integer
If IsEmpty(StartPoint) Then Err.Raise 13
i = UBound(StartPoint)
If UBound(EndPoint) = i Then
If i > 0 Then
Stx = StartPoint(0): Sty = StartPoint(1)
Enx = EndPoint(0): Eny = EndPoint(1)
dX = Stx - Enx
dY = Sty - Eny
If i = 1 Then
Length = Sqr(dX * dX + dY * dY)
Else
Stz = StartPoint(2): Enz = EndPoint(2)
Dz = Stz - Enz
Length = Sqr((dX * dX) + (dY * dY) + (Dz * Dz))
End If
Else
Exit Function
End If
Else
Exit Function
End If
End Function