The inputs for this example problem are the angle 174 and 360. When a multiple of 174’s add up to a multiple of 360, the program stops. In advance we do not know how many 174s will add up to how many 360s, but we want the first one. This is the Least Common Multiple of Angle A (174) and 360.
LCM (A, 360)
174 has prime factors of 2 * 3 * 29
360 has prime factors of 2 * 2 * 2 * 3 * 3 * 5
the least common multiple is 360 * 29 = 10440.
we can substitute that into either side of the equation
to find that n = 60 and R = 29
The LCM can be figured different ways. There is a famous method of Euclid, and Euler, (no Eugene). There is an excel function to do it. Sample VBA code can be downloaded. The simplest method conceptually is the same way the turtle does it, by adding angles one by one and testing the result.
Here is brute force way one with no advance knowledge of when the program will stop. The program stops when the turtle heading returns to its original position. I also have a second emergency stop at 361 which never comes into play usually. (*footnote – the examples in the group photo that look like folded ribbon were polygons that did not close until 360 lines were drawn but were forced into an early exit with ” If inc > 130 Then Exit Do”) (**footnote – if the turn angle A is an integer, the maximum number of lines to bring the heading back to start is 360.)
Sub poly_360(len_side As Double, angle As Double) Dim inc As Integer Dim heading As Double heading = turtle1.heading Do turtle1.fd len_side turtle1.left angle inc = inc + 1 If inc > 361 Then Exit Do Loop While turtle1.heading <> heading End Sub
Here is a primitive LCM function based on the same method, not intended to be the final version. The angles are added one by one and the result divided by 360 looking for a remainder, breaking out when the remainder is zero. The VBA mod operator works accurately only with integers. I had some overflows on the multiplication. The function seems to work better when all is type Long.
Function LCM(A As Long, B As Long) Dim n As Long Dim result As Long Dim remainder As Long n = 0 Do n = n + 1 result = n * A remainder = result Mod B Loop While remainder <> 0 LCM = result End Function
Now the sub to draw the polygon can be taken back to its roots. The loop calculations can be removed, because we will know in advance how many lines will be drawn.
Text information labels are added after the drawing is complete.
Sub poly_1(angle As Double, n As Integer, len_side As Double) Dim inc As Integer For inc = 1 To n turtle1.fd len_side turtle1.left angle Next inc txt_h "A = " & angle, turtle1.x1, turtle1.y1, 0.125 txt_h "n = " & n, turtle1.x1, turtle1.y1 - 0.25, 0.125 txt_h "R = " & (angle * n / 360), turtle1.x1, turtle1.y1 - 0.5, 0.125 End Sub
The sub to call the poly can be fancy or plain. It can draw families of polygons. It can loop and draw a range of turning angles.
This particular one will draw all the polygons with total turns (R) = 29 of angles between 1 and 180.
Sub turtle_demo_16() init_turtle Dim inc As Integer Dim n As Integer, R As Integer Dim A As Long, B As Long B = 360 For inc = 1 To 180 A = inc n = LCM(A, B) / A R = LCM(A, 360) / 360 If R = 29 Then Debug.Print "LCM of " & A; " and " & B; " = " & LCM(A, B) Debug.Print "A = " & A Debug.Print "n = " & n Debug.Print "R = " & R Debug.Print " " Call poly_1(CDbl(A), n, 1) turtle1.x1 = turtle1.x1 + 5 End If Next inc End Sub
Sub turtle_demo_16() init_turtle Dim inc As Integer Dim n As Integer, R As Integer Dim A As Long, B As Long B = 360 For inc = 160 To 181 A = inc n = LCM(A, B) / A R = LCM(A, 360) / 360 Call poly_1(CDbl(A), n, 1) turtle1.x1 = turtle1.x1 + 1.1 Next inc End Sub