Code:'---------------------------------------------------------------------- Sub Main() Begin Dialog TUBEMITERDIALOG 50,47, 160, 96, "Tube Miter" Text 4 ,12,120,12, "Diameter of intersecting tube (mm)" TextBox 120,12,25 ,12, .IDD_D1 Text 4 ,24,120,12, "Diameter of mitered tube (mm)" TextBox 120,24,25 ,12, .IDD_D2 Text 4 ,36,120,12, "included angle" TextBox 120,36,25 ,12, .IDD_PHI Text 4 ,48,120,12, "Offset (mm)" TextBox 120,48,25 ,12, .IDD_OFFSET OKButton 4,80,37,12 CancelButton 45,80,37,12 End Dialog Dim dlg As TUBEMITERDIALOG Dim ot As Long If(dcSelectAll) Then dcEraseSelObjs dcSetDrawingScale 25.4 dcSetLineParms dcBLACK, dcSOLID, dcTHIN dcSetSplineParms dcBLACK, dcSOLID, dcTHIN dlg.IDD_D1 = "25.4" dlg.IDD_D2 = "25.4" dlg.IDD_PHI = "90" dlg.IDD_OFFSET= "0.0" Button = Dialog(dlg) If Button = -1 Then Make_TubeMiter dlg.IDD_d1/2,dlg.IDD_D2/2,rad(90 - dlg.IDD_PHI),dlg.IDD_OFFSET/2 dcViewAll End If End Sub '---------------------------------------------------------------------- ' Square a value '---------------------------------------------------------------------- Function square(ByVal x As Double) square = x * x End Function '---------------------------------------------------------------------- ' Convert from degrees into radians '---------------------------------------------------------------------- Function rad(ByVal deg As Double) rad = (2*3.1415926535/360)*deg End Function '---------------------------------------------------------------------- ' Plot the tube miter ' R1 = radius of intersecting tube ' R2 = radius of intersected (cut) tube ' Phi = included angle between tubes (in radians) ' Offset = offset along the z axis between the tubes ' ' ' The generalized equation for a cylinder of radius r about the x axis is 1 = (y/r)^2 + (z/r)^2 ' apply the transformation y = y'cos(phi) + x'sin(phi) to rotate the cylinder about the z axis by angle phi ' this gives the equation 1 = ((y cos(phi) + x sin(phi))/r)^2 + (z/r)^2 ' now solve for x to get: x = (+- r*sqrt(1-(z/r)^2) - y cos(phi))/sin(phi) ' we can now iterate over values of y and z to find the discreet x points that make up our curve and fit them with ' a spline ' so we'll find our y and z values by rotating around the mitered cylinder which is along the x axis. So we get: ' y = R sin(alpha) ' z = R cos(alpha) for alpha = 0 to 360 ' actually let's not forget the offset, which applies only to the Z axis, so z = R cos(alpha) + Offset ' we can then substitute these back into the above equation for x. ' This X dimension is exactly what we want to plot, but the y parmeter for plotting needs to be the circumfrence ' of the mitered cylinder. so Yplot= R * alpha (if alpha is in radians) ' we also need to account for the fact that we support having a mitered cylinder larger than the intersecting cylinder ' so there is some logic there to figure out when a value is valid and not. '---------------------------------------------------------------------- Sub Make_TubeMiter(ByVal R1 As Double,ByVal R2 As Double,ByVal Phi As Double,ByVal Offset As Double) Dim X As Double ' X(a) Dim s(361) As Double 'Array for the spline Dim i As Double 'i for for loop Dim start As Double 'start of a spline Dim sign As Double 'either 1 or -1 to determine the sign in the equation below Dim loopCount As Integer 'loop once if the intersecting tube is larger, twice if smaller Dim j As Integer Dim ya As Double Dim za As Double Dim alpha As Double Dim max As Double sign = -1 loopCount = 1 max = 0 ' If the intersecting tube is smaller, we need to draw both sides ' of the intersection since it is making a hole though the tube, Thus we want to run through ' the loop twice. If (R2 + Offset > R1) Then loopCount = 2 End If For j = 1 to loopCount start = -1 For i=0 To 360 Step 2 'iterate 0 - 360 by 2 degree increments alpha = rad(i) 'we need everything in radians ya = R2*Sin(alpha) za = R2*Cos(alpha)+Offset 'if there is something to cut here If square(za/R1) <= 1 Then X= (R1 * sign * Sqr(1 - square(za/R1)) - ya * Sin(Phi))/Cos(Phi) ' from the equation derived int he comments above ' If this is the first good sample in this spline, then record that If start = -1 Then start = i End If Else ' we are cutting a hole, and this is outside that hole X = 0.0 ' this is the first sample that is outside the hole, draw the spline If start > -1 Then dcCreateSpline s(start), (i-start)/2, False start = -1 End If End If ' spline point = (x,R*alpha) s(i) = X s(i+1) = R2 * alpha ' record the largest extent for the purpose of drawing reference lines If (Abs(X) > max) Then max = Abs(X) Next i ' If we stopped the loop while we still had valid values, display the spline If start > -1 Then dcCreateSpline s(start), (362 - start)/2, False End If ' swap the sign just in case we need to run through the loop again sign = 1 Next j ' Draw reference lines dcCreateLine (-2*max), (R2 * rad(0) ), (2*max), (R2 * rad(0) ) dcCreateLine (-2*max), (R2 * rad(90) ), (2*max), (R2 * rad(90) ) dcCreateLine (-2*max), (R2 * rad(180)), (2*max), (R2 * rad(180)) dcCreateLine (-2*max), (R2 * rad(270)), (2*max), (R2 * rad(270)) dcCreateLine (-2*max), (R2 * rad(360)), (2*max), (R2 * rad(360)) End Sub




Reply With Quote



Bookmarks