Title: Draw a Koch curve fractal with Python
The Koch curve is a fractal curve discovered by Swedish mathematician Niels Fabian Helge von Koch. To draw the curve, you start with a straight line segment. You then break it into three pieces and replace the middle piece with two pieces that form an equilateral triangle. You then beak each of the segments of the new curve into three pieces and repeat until you reach a desired depth. Normally the drawing method is recursive and the depth gives the depth of recursion.
(Actually, von Koch's original 1904 paper was titled "On a Continuous Curve Without Tangents, Constructible from Elementary Geometry" and described the limit as the depth approaches infinity, giving a continuous curve that has no tangent points.)
The following pictures show the curve with depths of recursion 0 through 3.
The following code shows how this example draws a Koch curve.
def draw_koch_curve(points, depth, p1, theta, length):
'''
Recursively draw a snowflake edge starting at p1 in direction theta
and distance dist. Return the endpoint.
'''
if depth == 0:
# Just move there.
p2 = (p1[0] + length * math.cos(theta),
p1[1] + length * math.sin(theta))
points.append(p2)
return p2
# Recursively draw the edge.
length /= 3
p1 = draw_koch_curve(points, depth - 1, p1, theta, length)
theta -= math.radians(60)
p1 = draw_koch_curve(points, depth - 1, p1, theta, length)
theta += math.radians(120)
p1 = draw_koch_curve(points, depth - 1, p1, theta, length)
theta -= math.radians(60)
p1 = draw_koch_curve(points, depth - 1, p1, theta, length)
return p1 # Return the final end point.
This method first checks the desired depth of recursion. If the depth is 0, it calculates the end of the segment starting at point p1 moving at the angle theta for distance length. It adds that end point p2 to the points list and returns the end point.
If depth is greater than 0, the code divides the segment into three pieces and recursively calls itself to draw those pieces with depth reduced by 1.
To do that, it first divides length by 3. It then calls itself to draw in the original direction by the reduced length.
Next, the code turns 60° and recursively calls itself again to draw in the rotated direction. It rotates -120° and draws again. Finally, it rotates 60° and calls itself one last time.
When it calls itself, the method saves the returned end point in p1 so each recursive call begins drawing where the previous one finished.
The following code shows how the main program uses the recursive method.
# Find the starting point, distance, and angle.
wid = self.canvas.winfo_width()
hgt = self.canvas.winfo_height()
p1 = (20, hgt / 2)
length = wid - 40
theta = 0
# Get the points.
points = [p1]
draw_koch_curve(points, depth, p1, theta, length)
# Draw the polygon.
self.canvas.create_line(points, width=1, fill='black')
This code calculates a good starting point, distance, and angle. It creates a points list and calls draw_koch_curve to generate the curve's points. It finishes by using its Canvas widget's create_line method to draw the curve.
Download the example to see additional details.
|