I dont really know how can be solved keeping the recursion, I was studying the turtle library but in the asignature they ask for use matplotlib so I am not really sure about how take it
from turtle import Turtle
def hilbert_curve(turtle, A, parity, n):
if n == 1:
hilbert_curve_draw(turtle, A, parity)
else:
turtle.right(parity * 90)
hilbert_curve(turtle, A, - parity, n - 1)
turtle.forward(A)
turtle.left(parity * 90)
hilbert_curve(turtle, A, parity, n - 1)
turtle.forward(A)
hilbert_curve(turtle, A, parity, n - 1)
turtle.left(parity * 90)
turtle.forward(A)
hilbert_curve(turtle, A, - parity, n - 1)
turtle.right(parity * 90)
def hilbert_curve_draw(turtle, A, parity):
turtle.right(parity * 90)
turtle.forward(A)
turtle.left(parity * 90)
turtle.forward(A)
turtle.left(parity * 90)
turtle.forward(A)
turtle.right(parity * 90)
yertle = Turtle()
yertle.hideturtle()
yertle.penup()
yertle.goto(-200, 200)
yertle.pendown()
yertle.speed('fastest')
hilbert_curve(yertle, 60, 1, 3)
The turtle keeps an internal state with its position and orientation. These can be represented by local variables. The orientation can be a tuple (xdir, ydir)
representing a vector with length 1. Turning left would multiply the vector with a rotation matrix. The rotations can be simplified when only vectors with coordinates -1
, 0
and 1
are used.
The code below implements these ideas. To make things a bit more readable, A
has been renamed to length
and n
to levels
.
from matplotlib import pyplot as plt
def turn_left(orient, parity):
return (orient[1] * parity, -orient[0] * parity)
def turn_right(orient, parity):
return turn_left(orient, -parity)
def draw_line(x0, y0, orient, length):
x1 = x0 + orient[0] * length
y1 = y0 + orient[1] * length
plt.plot([x0, x1], [y0, y1], color='navy')
return x1, y1
def hilbert_curve_draw(x, y, length, orient, parity):
orient = turn_right(orient, parity)
x, y = draw_line(x, y, orient, length)
orient = turn_left(orient, parity)
x, y = draw_line(x, y, orient, length)
orient = turn_left(orient, parity)
x, y = draw_line(x, y, orient, length)
orient = turn_right(orient, parity)
return x, y, orient
def hilbert_curve(x, y, length, orient, parity, levels):
if levels == 1:
x, y, orient = hilbert_curve_draw(x, y, length, orient, parity)
else:
orient = turn_right(orient, parity)
x, y, orient = hilbert_curve(x, y, length, orient, - parity, levels - 1)
x, y = draw_line(x, y, orient, length)
orient = turn_left(orient, parity)
x, y, orient = hilbert_curve(x, y, length, orient, parity, levels - 1)
x, y = draw_line(x, y, orient, length)
x, y, orient = hilbert_curve(x, y, length, orient, parity, levels - 1)
orient = turn_left(orient, parity)
x, y = draw_line(x, y, orient, length)
x, y, orient = hilbert_curve(x, y, length, orient, - parity, levels - 1)
orient = turn_right(orient, parity)
return x, y, orient
hilbert_curve(x=-200, y=200, length=5, orient=(1, 0), parity=1, levels=5)
plt.axis('equal') # same lengths in x and y direction
plt.show()