Dodecagon Spiral (Source Code)

In other related projects, we draw a pentagon spiral and a square spiral. Now draw a dodecagon spiral with 12 sides. Also make the grayscale of dodecagons gradually grow lighter as it gets smaller.

Dodecagon Spiral

Source Code:

import turtle
import math

screen = turtle.Screen()
screen.title('Dodecagon Spiral - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()

def draw_spiral(x,y,r,direction):
    if r < 10: return
    d = direction
    r2 = r*math.cos(math.radians(360/24))/math.cos(math.radians(360/24-alpha))
    dist = r*math.sin(math.radians(360/24))-r2*math.sin(math.radians(360/24-alpha))
    turtle.up()
    px = x + r*math.cos(math.radians(d))
    py = y + r*math.sin(math.radians(d))
    turtle.goto(px,py)
    turtle.color((1-r/900,1-r/900,1-r/900))
    turtle.down()
    d += 360/12
    for _ in range(12):
        px = x + r*math.cos(math.radians(d))
        py = y + r*math.sin(math.radians(d))
        turtle.goto(px,py)
        d += 360/12
    draw_spiral(x,y,r2,direction+alpha)
    
    
alpha = 3
draw_spiral(0,0,900,90)

Hexagon Spiral of Spirals Colored (Source Code)

After drawing pentagon spiral of pentagon spirals, draw colored version of hexagon spiral of spirals with recursion and Turtle library.

Hexagon Spiral of Spirals Colored

Source Code:

import turtle
import math

screen = turtle.Screen()
screen.title('Hexagon Spiral of Hexagon Spirals - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
screen.tracer(0,0)

colors = [ 'red', 'orange', 'green', 'teal', 'blue', 'magenta' ]

def draw_spiral(x,y,r,direction,first=False):
    if r < 1: return
    d = direction
    r_ratio = math.cos(math.radians(30))/math.cos(math.radians(30-alpha))
    d_ratio = math.sin(math.radians(30))-r_ratio*math.sin(math.radians(30-alpha))
    for i in range(6):
        if first: turtle.color(colors[i]) 
        px = x + r*math.cos(math.radians(direction))
        py = y + r*math.sin(math.radians(direction))
        r2 = r
        d = direction
        c = 0
        flag = False
        while True:
            dist = r2*d_ratio
            if c > 10 and dist < 1: break
            if dist > 4:
                draw_spiral(px,py,dist*0.4,d)
                turtle.up()
                turtle.goto(px,py)
                turtle.seth(d+180-60)
                turtle.fd(dist)
                px,py = turtle.xcor(), turtle.ycor()
            elif not flag:
                turtle.up()
                turtle.goto(px,py)
                turtle.down()
                flag = True
                turtle.seth(d+180-60)
                turtle.fd(dist)
            else:   
                turtle.seth(d+180-60)
                turtle.fd(dist)
    
            r2 = r2*r_ratio
            d += alpha
            c += 1
        direction += 60
    
    
alpha = 20
draw_spiral(0,0,800,90,True)
screen.update()
ts=turtle.getscreen()
ts.getcanvas().postscript(file = "spiral.eps")

Pentagon Spiral of Pentagon Spirals Fractal (Source Code)

After finishing 5 spirals and spiral of spirals, draw the following pentagon spiral of pentagon spirals using recursion.

Pentagon Spiral of Pentagon Spirals

Source Code: (This code may run for several minutes)

import turtle
import math

screen = turtle.Screen()
screen.title('Pentagon Spiral of Pentagon Spirals - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
screen.tracer(0,0)

def draw_spiral(x,y,r,direction):
    if r < 1: return
    d = direction
    r_ratio = math.cos(math.radians(36))/math.cos(math.radians(36-alpha))
    d_ratio = math.sin(math.radians(36))-r_ratio*math.sin(math.radians(36-alpha))
    for _ in range(5):
        px = x + r*math.cos(math.radians(direction))
        py = y + r*math.sin(math.radians(direction))
        r2 = r
        d = direction
        c = 0
        flag = False
        while True:
            dist = r2*d_ratio
            if c > 10 and dist < 1: break
            if dist > 3:
                draw_spiral(px,py,dist*0.5,d)
                turtle.up()
                turtle.goto(px,py)
                turtle.seth(d+180-54)
                turtle.fd(dist)
                px,py = turtle.xcor(), turtle.ycor()
            elif not flag:
                turtle.up()
                turtle.goto(px,py)
                turtle.down()
                flag = True
                turtle.seth(d+180-54)
                turtle.fd(dist)
            else:   
                turtle.seth(d+180-54)
                turtle.fd(dist)
    
            r2 = r2*r_ratio
            d += alpha
            c += 1
        direction += 360/5
    
    
alpha = 20
draw_spiral(0,0,800,90)
screen.update()
ts=turtle.getscreen()
ts.getcanvas().postscript(file = "spiral.eps")

5 Spirals (Source Code)

Modify pentagon spiral to draw 5 spirals as shown here.

Five Spirals

Source Code:

import turtle
import math

screen = turtle.Screen()
screen.title('5 Spirals - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
turtle.pensize(2)

colors = [ 'red', 'orange', 'green', 'blue', 'purple' ]
def draw_spiral(x,y,r,direction):
    if r < 10: return
    d = direction
    r_ratio = math.cos(math.radians(36))/math.cos(math.radians(36-alpha))
    d_ratio = math.sin(math.radians(36))-r_ratio*math.sin(math.radians(36-alpha))
    for i in range(5):
        px = x + r*math.cos(math.radians(d))
        py = y + r*math.sin(math.radians(d))
        turtle.color(colors[i])
        turtle.up()
        turtle.goto(px,py)
        turtle.down()
        turtle.seth(d+180-54)
        dist = r*d_ratio
        r2 = r
        while dist > 0.1:
            turtle.fd(dist)
            r2 = r2*r_ratio
            dist = r2*d_ratio
            turtle.left(alpha)
        d += 360/5
       
alpha = 5
draw_spiral(0,0,900,90)

Pentagon Spiral inside Pentagon (Source Code)

This project draws square spiral inside a square. Now draw a pentagon spiral inside pentagon as shown.

Pentagon Spiral inside Pentagon

Source Code:

import turtle
import math

screen = turtle.Screen()
screen.title('Pentagon Spiral inside Pentagon - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
#screen.tracer(0,0)

def draw_spiral(x,y,r,direction):
    if r < 10: return
    d = direction
    r2 = r*math.cos(math.radians(36))/math.cos(math.radians(36-alpha))
    dist = r*math.sin(math.radians(36))-r2*math.sin(math.radians(36-alpha))
    turtle.up()
    px = x + r*math.cos(math.radians(d))
    py = y + r*math.sin(math.radians(d))
    turtle.goto(px,py)
    turtle.down()
    d += 360/5
    for _ in range(5):
        px = x + r*math.cos(math.radians(d))
        py = y + r*math.sin(math.radians(d))
        turtle.goto(px,py)
        d += 360/5
    draw_spiral(x,y,r2,direction+alpha)
    
    
alpha = 7
draw_spiral(0,0,900,90)

Golden Dragon Curve Fractal (Source Code)

Draw a dragon curve based on the golden ratio. At each recursion, the first recursion step turns 32.89 degrees to the left and move 0.74 times the original distance; the second recursion step turns 46.99 degrees to the right and move 0.55 times the original distance. Please check out this web page on mathematical details of the golden dragon.

The following show the recursions depths from 0 to 3.

Recursion Depth 0
Recursion Depth 1
Recursion Depth 2
Recursion Depth 3

The following figure is generated not by the recursion depth but by stopping the recursion when the distance becomes smaller than 1.

Golden Dragon Curve

Source Code:

import turtle
import math

screen = turtle.Screen()
screen.title('Golden Dragon Curve - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
turtle.pencolor('gold')
screen.bgcolor('royal blue')
screen.tracer(0,0)

golden_ratio = (1+5**0.5)/2
r1 = r = (1/golden_ratio)**(1/golden_ratio)
r2 = r1**2
angle1 = math.acos((1+r**2-r**4)/(2*r))
angle2 = math.acos((1+r**4-r**2)/(2*r**2))
print(r1,r2,math.degrees(angle1),math.degrees(angle2))

def golden_dragon(x1,y1,x2,y2,turn,n):
    dist = ((x2-x1)**2 + (y2-y1)**2)**0.5
    if dist<1:
        turtle.goto(x2,y2)
        return
    angle = math.atan2(y2-y1,x2-x1)
    if turn:
        px = x1+dist*r1*math.cos(angle+angle1)
        py = y1+dist*r1*math.sin(angle+angle1)
    else:
        px = x1+dist*r2*math.cos(angle-angle2)
        py = y1+dist*r2*math.sin(angle-angle2)
    golden_dragon(x1,y1,px,py,True,n-1)
    golden_dragon(px,py,x2,y2,False,n-1)

turtle.up()
turtle.goto(-500,-200)
turtle.down()
golden_dragon(-500,-200,700,-200,True,3)
screen.update()

Octaflake with Python Turtle (Source Code)

Draw the Octaflake fractal with recursion and Turtle library. The following shows Octaflake in various recursion depths:

A Simple Octagon at Recursion Depth 0
Recursion Depth 1
Recursion Depth 2
Recursion Depth 3

Instead of stopping the recursion by recursion depth, you can also stop the recursion when the radius becomes smaller than certain size. The following Octaflake is generated by setting the threshold for recursion by radius to 10. Now you can see all octagons has the same sizes.

Octaflake with Radius Less than 10

Source Code:

import turtle
import math

screen = turtle.Screen()
screen.title('Octaflake Fractal - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
turtle.fillcolor('royal blue')
turtle.pencolor('steel blue')
screen.tracer(0,0)

def octagon(x,y,r): #x,y is the center
    turtle.up()
    turtle.goto(x,y)
    turtle.seth(90)
    turtle.fd(r)
    turtle.left(180-135/2)
    turtle.down()
    turtle.begin_fill()
    for _ in range(8):
        turtle.fd(2*r*math.sin(math.radians(45/2)))
        turtle.left(45)
    turtle.end_fill()

    
def octaflake(x,y,r,n):
    if r<10:
        octagon(x,y,r)
        return
    r2 = r/(1+1/math.tan(math.radians(45/2)))   
    octaflake(x,y,r-2*r2,n-1)
    direction = 90
    for _ in range(8):
        turtle.up()
        turtle.goto(x,y)
        turtle.seth(direction)
        turtle.fd(r-r2)
        octaflake(turtle.xcor(),turtle.ycor(),r2,n-1)
        direction += 45

octaflake(0,0,900,3)
screen.update()

Hexaflake Fractal with Python Turtle (Source Code)

Draw hexaflake fractal that consists of hexagons with recursion. The following figures show hexaflake in different recursion depths.

Hexaflake Recursion Depth 0
Hexaflake Recursion Depth 1
Hexaflake Recursion Depth 2
Hexaflake Recursion Depth 3
Hexaflake Recursion Depth 4
Hexaflake Recursion Depth 5

Source Code:

import turtle

screen = turtle.Screen()
screen.title('Hexaflake Fractal - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
turtle.fillcolor('blanched almond')
turtle.pencolor('sandy brown')
screen.tracer(0,0)

def hexagon(x,y,r): #x,y is the center
    turtle.up()
    turtle.goto(x,y)
    turtle.seth(90)
    turtle.fd(r)
    turtle.left(120)
    turtle.down()
    turtle.begin_fill()
    for _ in range(6):
        turtle.fd(r)
        turtle.left(60)
    turtle.end_fill()

    
def hexaflake(x,y,r,n):
    if n==0:
        hexagon(x,y,r)
        return
    hexaflake(x,y,r/3,n-1)
    direction = 90
    for _ in range(6):
        turtle.up()
        turtle.goto(x,y)
        turtle.seth(direction)
        turtle.fd(r*2/3)
        hexaflake(turtle.xcor(),turtle.ycor(),r/3,n-1)
        direction += 60

hexaflake(0,0,900,5)
screen.update()

Colored Pentaflake Fractal (Source Code)

Based on petaflake fractal, color it with colorsys library.

Colored Pentaflake Fractal

Source Code:

import turtle
import math
import colorsys

screen = turtle.Screen()
screen.title('Pentaflake Fractal Colored - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.setworldcoordinates(-1000,-1000,1000,1000)
turtle.speed(0)
turtle.hideturtle()
screen.tracer(0,0)
turtle.fillcolor('dark cyan')

def pentagon(x,y,r,direction): #x,y is the center
    turtle.up()
    turtle.goto(x,y)
    turtle.seth(direction)
    turtle.fd(r)
    turtle.left(126)
    turtle.down()
    c = colorsys.hsv_to_rgb((x+1000)/2000,1,0.7)
    turtle.color(c)
    turtle.begin_fill()
    for _ in range(5):
        turtle.fd(2*r*math.sin(math.radians(36)))
        turtle.left(72)
    turtle.end_fill()
    
def pentaflake(x,y,r,direction,n):
    if n==0:
        pentagon(x,y,r,direction)
        return

    r2 = r/(1+2*math.cos(math.radians(36)))
    d = 2*r2*math.cos(math.radians(36))
    for _ in range(5):
        x2,y2 = x+d*math.cos(math.radians(direction)),y+d*math.sin(math.radians(direction))
        pentaflake(x2,y2,r2,direction,n-1)
        direction += 72
    pentaflake(x,y,r2,direction+180,n-1)
    
pentaflake(0,0,1000,90,6)
screen.update()