-
Notifications
You must be signed in to change notification settings - Fork 0
/
koch_curves.py
135 lines (109 loc) · 4.17 KB
/
koch_curves.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""
A script to generate an animated gif of the Koch snowflake.
author: Fabrizio Musacchio (fabriziomusacchio.com)
date: Aug 2, 2021
"""
# %% IMPORTS
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
# %% KOCH SNOWFLAKE ANIMATION
def koch_snowflake(ax, p1, p2, depth=0):
if depth == 0:
ax.plot([p1[0], p2[0]], [p1[1], p2[1]], color='b')
else:
dx = p2[0] - p1[0]
dy = p2[1] - p1[1]
length = np.sqrt(dx**2 + dy**2)
unit = length / 3.0
angle = np.arctan2(dy, dx)
p1_new = p1
p2_new = [p1[0] + np.cos(angle) * unit, p1[1] + np.sin(angle) * unit]
p3_new = [p2_new[0] + np.cos(angle - np.pi / 3) * unit, p2_new[1] + np.sin(angle - np.pi / 3) * unit]
p4_new = [p1[0] + np.cos(angle) * 2 * unit, p1[1] + np.sin(angle) * 2 * unit]
koch_snowflake(ax, p1_new, p2_new, depth - 1)
koch_snowflake(ax, p2_new, p3_new, depth - 1)
koch_snowflake(ax, p3_new, p4_new, depth - 1)
koch_snowflake(ax, p4_new, p2, depth - 1)
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.axis('off')
# initial points of the Koch snowflake:
p1 = [-0.5, -0.288]
p2 = [0.5, -0.288]
p3 = [0.0, 0.577]
depth = 5 # Set the desired depth of recursion
def update(frame):
ax.clear()
ax.set_aspect('equal')
ax.axis('off')
# calculate the new points for the current frame:
new_p1 = p1
new_p2 = p2
new_p3 = p3
# adjust the depth for each frame:
current_depth = int(depth * (frame + 1) / 100.0)
# Generate the Koch snowflake
koch_snowflake(ax, new_p1, new_p2, current_depth)
koch_snowflake(ax, new_p2, new_p3, current_depth)
koch_snowflake(ax, new_p3, new_p1, current_depth)
# set the plot limits:
ax.set_xlim([-0.7, 0.7])
ax.set_ylim([-0.7, 0.7])
# annotate the depth in the plot:
ax.text(0.02, 0.95, 'Depth: {}'.format(current_depth), transform=ax.transAxes, color='black', fontsize=12)
anim = FuncAnimation(fig, update, frames=120, interval=100)
anim.save('images/koch_snowflake_animation.gif', writer='pillow', fps=60)
plt.show()
# %% KOCH SNOWFLAKE ANIMATION W/ CHANGING COLORS
def koch_snowflake(ax, p1, p2, depth=0, color='b'):
if depth == 0:
ax.plot([p1[0], p2[0]], [p1[1], p2[1]], color=color)
else:
dx = p2[0] - p1[0]
dy = p2[1] - p1[1]
length = np.sqrt(dx**2 + dy**2)
unit = length / 3.0
angle = np.arctan2(dy, dx)
p1_new = p1
p2_new = [p1[0] + np.cos(angle) * unit, p1[1] + np.sin(angle) * unit]
p3_new = [p2_new[0] + np.cos(angle - np.pi / 3) * unit, p2_new[1] + np.sin(angle - np.pi / 3) * unit]
p4_new = [p1[0] + np.cos(angle) * 2 * unit, p1[1] + np.sin(angle) * 2 * unit]
# generate a random color for each recursion level:
new_color = '#' + ''.join(random.choices('0123456789ABCDEF', k=6))
koch_snowflake(ax, p1_new, p2_new, depth - 1, new_color)
koch_snowflake(ax, p2_new, p3_new, depth - 1, new_color)
koch_snowflake(ax, p3_new, p4_new, depth - 1, new_color)
koch_snowflake(ax, p4_new, p2, depth - 1, new_color)
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.axis('off')
# initial points of the Koch snowflake:
p1 = [-0.5, -0.288]
p2 = [0.5, -0.288]
p3 = [0.0, 0.577]
depth = 5 # set the desired depth of recursion
def update(frame):
ax.clear()
ax.set_aspect('equal')
ax.axis('off')
# calculate the new points for the current frame:
new_p1 = p1
new_p2 = p2
new_p3 = p3
# adjust the depth for each frame:
current_depth = int(depth * (frame + 1) / 100.0)
# generate the Koch snowflake:
koch_snowflake(ax, new_p1, new_p2, current_depth)
koch_snowflake(ax, new_p2, new_p3, current_depth)
koch_snowflake(ax, new_p3, new_p1, current_depth)
# set the plot limits:
ax.set_xlim([-0.7, 0.7])
ax.set_ylim([-0.7, 0.7])
# annotate the depth in the plot:
ax.text(0.02, 0.95, 'Depth: {}'.format(current_depth), transform=ax.transAxes, color='black', fontsize=12)
anim = FuncAnimation(fig, update, frames=100, interval=100)
anim.save('images/koch_snowflake_animation_color.gif', writer='pillow', fps=60)
plt.show()
# %% END