Private Function Factor(inToFactor As Integer, outArray() As Integer) As Integer ' Factor inToFactor into the array outArray If (inToFactor > 1) Then ReDim outArray(Sqr(inToFactor)) factorCount = 0 toFactor = inToFactor ' Factor out all powers of 2 Do While ((toFactor Mod 2) = 0) outArray(factorCount) = 2 factorCount = factorCount + 1 toFactor = toFactor / 2 Loop limit = toFactor ' Walk through the odd numbers, testing each one For testFactor = 3 To limit Step 2 Do While ((toFactor Mod testFactor) = 0) outArray(factorCount) = testFactor factorCount = factorCount + 1 toFactor = toFactor / testFactor Loop Next ReDim Preserve outArray(factorCount - 1) Factor = factorCount - 1 Else ' if number to factor is less than 1, return single factor 1 ReDim outArray(1) factorCount = 0 outArray(0) = 1 Factor = 0 End If End Function Private Sub CalculateCycles() ' The required number of cycles (times around the Big circle) is ' determined by the largest common multiple of the radii of the ' Big and Small circles If (StrComp(bigRadiusText.Text, "") And StrComp(smallRadiusText.Text, "")) Then Dim toFactor1 As Integer Dim toFactor2 As Integer toFactor1 = bigRadiusText.Text toFactor2 = smallRadiusText.Text ' Get the factors of each radius Dim factor1List() As Integer Dim factor2List() As Integer factors1 = Factor(toFactor1, factor1List) factors2 = Factor(toFactor2, factor2List) ' Cross off all factors held in common For i = 0 To factors2 For j = 0 To factors1 If (factor1List(j) = factor2List(i)) Then factor1List(j) = 1 factor2List(i) = 1 End If Next Next cycles = 1 ' and multiply together all remaining factors in the small radius For i = 0 To factors2 cycles = cycles * factor2List(i) Next ' to determine the number of cycles cyclesText.Text = cycles End If End Sub Private Sub drawButton_Click() Dim appObj As Illustrator.Application Dim docObj As Illustrator.Document Dim groupObj As Illustrator.GroupItem Dim pathWidth As Double ' Width of each of the lines Dim pathOpacity As Double ' Opacity of the lines Set appObj = GetObject("", "Illustrator.Application") Set docObj = appObj.Documents.Add pathWidth = 1 pathOpacity = 100 docObj.DefaultFilled = False docObj.DefaultStroked = True docObj.DefaultStrokeWidth = pathWidth Set groupObj = docObj.ActiveLayer.GroupItems.Add Dim docWidth As Double Dim docHeight As Double Dim BigX As Double ' Center, Radius of large circle Dim BigY As Double Dim bigRadius As Double Dim SmallX As Double ' Center, Radius of small circle Dim SmallY As Double Dim smallRadius As Double Dim alphaAngle As Double ' angle (from vertical) of small circle center Dim betaAngle As Double ' angle (from vertical) of pen Dim penDistance As Double ' pen draw radius (distance from center of small circle Dim radiusDifference As Double ' distance from center of big circle to center of small circle ' (depends upon Outside checkbox) Dim pi As Double Dim bigStepSize As Double ' alphaAngle angle step Dim smallStepSize As Double ' betaAngle angle step Dim prevX As Double ' trailing drawing point Dim prevY As Double Dim X As Double ' leading drawing point Dim Y As Double ' Get the values from the user input bigRadius = CyclegraphForm.bigRadiusText.Text smallRadius = CyclegraphForm.smallRadiusText.Text stepsPerCycle = CyclegraphForm.pointsPerCycleText.Text cycles = CyclegraphForm.cyclesText.Text penDistance = CyclegraphForm.penDistanceText.Text ' set center of large circle at middle of page docWidth = docObj.Width docHeight = docObj.Height BigX = docWidth / 2 BigY = docHeight / 2 ' set small circle at top of large circle SmallX = BigX SmallY = BigY + bigRadius - smallRadius radiusDifference = bigRadius - smallRadius ' initial angles alphaAngle = 0 betaAngle = 0 ' initialize pi value, step sizes pi = 4# * Math.Atn(1) bigStepSize = (2# * pi) / stepsPerCycle smallStepSize = bigStepSize * bigRadius / smallRadius ' initialize trailing point prevX = SmallX prevY = SmallY + penDistance ' for each step For i = 0 To stepsPerCycle * cycles alphaAngle = alphaAngle + bigStepSize betaAngle = betaAngle - smallStepSize SmallX = BigX + (radiusDifference * Sin(alphaAngle)) SmallY = BigY + (radiusDifference * Cos(alphaAngle)) X = SmallX + (penDistance * Sin(betaAngle)) Y = SmallY + (penDistance * Cos(betaAngle)) CreateLine groupObj, prevX, prevY, X, Y, pathOpacity prevX = X prevY = Y Next i End Sub Private Sub CreateLine(inGroupItem As Illustrator.GroupItem, inStartX As Double, inStartY As Double, inEndX As Double, inEndY As Double, inOpacity As Double) Dim pathItem As Illustrator.pathItem Set pathItem = inGroupItem.PathItems.Add pathItem.SetEntirePath Array(Array(inStartX, inStartY), Array(inEndX, inEndY)) pathItem.Opacity = inOpacity End Sub ' Calculate the required number of cycles every time the Big radius is changed Private Sub bigRadiusText_Change() CalculateCycles End Sub ' Calculate the required number of cycles every time the Small radius is changed Private Sub smallRadiusText_Change() CalculateCycles End Sub