Created
November 5, 2022 21:56
-
-
Save ekm507/4787e25942ae73ac4f659a9958ec8cd6 to your computer and use it in GitHub Desktop.
kochs snowflake with linear mapping in python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from matplotlib import pyplot as plt | |
# define the initial line. it has two points and its length should be 1 to normalize everything. | |
points = [] | |
first_points = [np.array([0, 0]), np.array([1, 0])] | |
points += first_points | |
# number of iterations in making fractal. how deep do you want it to be? | |
# for Koch's snowflake, if level is set to 1, it should draw something like this: _/\_ | |
levels = 5 | |
# angle of rotation in snowflake. standart value is Pi/3 but you can try it with Pi/2.5 and Pi/4 | |
rotation_angle = np.pi / 3 | |
# make rotation matrices. one for clockwise, other for counter-clockwise. | |
sin_r = np.sin(rotation_angle) | |
cos_r = np.cos(rotation_angle) | |
rm1 = np.array([ | |
[cos_r, sin_r], | |
[-sin_r, cos_r] | |
]) | |
rm2 = np.array([ | |
[cos_r, -sin_r], | |
[sin_r, cos_r] | |
]) | |
# make displacement vectors | |
d0 = np.array([0, 0]) | |
d1 = np.array([1, 0]) | |
d2 = np.array([1 + np.cos(rotation_angle), np.sin(rotation_angle)]) | |
d3 = np.array([1 + 2 * np.cos(rotation_angle), 0]) | |
# calculate scaling factor for each itteration. it is not 1/2 because the shape is a fractal | |
scale_factor = 1/(2 + 2 * np.cos(rotation_angle)) | |
# this fractal repeats itself 4 times. this function generates one of the sides by mapping points. | |
def one_side_of_fractal(points, which_side): | |
output = [] | |
for point in points: | |
if which_side == 0: | |
output.append(point) | |
elif which_side == 1: | |
point_rotate = np.matmul(point, rm1) + d1 | |
output.append(point_rotate) | |
elif which_side == 2: | |
point_rotate = np.matmul(point, rm2) + d2 | |
output.append(point_rotate) | |
elif which_side == 3: | |
point_rotate = point + d3 | |
output.append(point_rotate) | |
return output | |
# one iteration of fractal. | |
# this function generates 4 copies of the fractal and joins them together. finally scales the fractal. | |
def one_level_deeper_koch(points): | |
output = [] | |
for i in range(4): | |
output += one_side_of_fractal(points, i) | |
return list(np.array(output) * scale_factor) | |
# get an initial line and turn it into a fractal. this is only one side of snowflake. because I am too lazy to make other sides too! | |
def make_koch(points, levels): | |
for _ in range(levels): | |
points = one_level_deeper_koch(points) | |
return points | |
# | |
for i in range(levels): | |
# scale_factor = float(input()) | |
points = [] + first_points | |
points = make_koch(points, i) | |
points_x = [point[0] for point in points] | |
points_y = [point[1] for point in points] | |
plt.plot(points_x, points_y) | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment