The Sierpinski triangle is a classic fractal pattern formed by recursive subdividing an equilateral triangle into smaller equilateral triangles. By removing the central triangle at each step, the distinctive gasket structure emerges.
While turtle graphics are often implemented using relative directional movements, a coordinate-based approach provides a clearer mathematical representation of the subdivision. The algorithm calculates the midpoints of the parent triangle's edges to define the vertices of the three smaller sub-triangles, avoiding overlapping line redraws.
import turtle
# Function to calculate the midpoint between two coordinate vertices
def compute_mid(point_a, point_b):
return ((point_a[0] + point_b[0]) / 2.0, (point_a[1] + point_b[1]) / 2.0)
# Function to draw a single equilateral triangle given three vertices
def trace_shape(cursor, corners):
cursor.penup()
cursor.goto(corners[0])
cursor.pendown()
cursor.goto(corners[1])
cursor.goto(corners[2])
cursor.goto(corners[0])
# Recursive function to generate the Sierpinski gasket
def render_sierpinski(cursor, depth, corners):
# Draw the current triangle outline
trace_shape(cursor, corners)
# If depth is greater than zero, recursively draw the three sub-triangles
if depth > 0:
# Bottom-left sub-triangle
render_sierpinski(cursor, depth - 1, [corners[0],
compute_mid(corners[0], corners[1]),
compute_mid(corners[0], corners[2])])
# Bottom-right sub-triangle
render_sierpinski(cursor, depth - 1, [compute_mid(corners[0], corners[1]),
corners[1],
compute_mid(corners[1], corners[2])])
# Top sub-triangle
render_sierpinski(cursor, depth - 1, [compute_mid(corners[0], corners[2]),
compute_mid(corners[1], corners[2]),
corners[2]])
def main():
# Initialize the drawing environment
canvas = turtle.Screen()
canvas.setup(width=800, height=800)
canvas.title("Sierpinski Triangle Generation")
# Create and configure the turtle cursor
artist = turtle.Turtle()
artist.speed(0) # Set to maximum drawing speed
# Prompt the user for the fractal depth, enforcing a valid range
while True:
try:
level = int(input("Enter the fractal depth (1-9): "))
if 1 <= level <= 9:
break
else:
print("Invalid input. Please enter a number between 1 and 9.")
except ValueError:
print("Invalid input. Please enter a valid integer.")
# Define the initial vertices for a large equilateral triangle
initial_size = 600
start_x = -initial_size / 2
start_y = -initial_size / 2
base_corners = [(start_x, start_y),
(start_x + initial_size, start_y),
(start_x + initial_size / 2, start_y + (initial_size * (3**0.5)/2))]
# Execute the recursive drawing process
render_sierpinski(artist, level, base_corners)
# Hide the cursor and keep the window open
artist.hideturtle()
canvas.mainloop()
if __name__ == "__main__":
main()