2.4 Przykłady w języku Python
Przykłady przedstawione w tym rozdziale powtarzają złożenie trzech atomowych transformacji – przesunięcia, przeskalowania i obrotu.
Poniżej znajdują się definicje tych trzech przekształceń. W poniższych przykładach x
jest dwuelementowym wektorem.
import numpy as np
import matplotlib.pyplot as plt
# Przesunięcie punktu x o wektor delta.
def shift(x, delta):
return np.add(x, delta)
# Przeskalowanie punktu x razy ratio.
def scale(x, ratio):
return np.multiply(x, ratio)
# Obrót o kąt alpha (w stopniach).
def rotate(x, alpha):
= math.pi * alpha / 180
adeg = [
rotation_matrix -np.sin(adeg)],
[np.cos(adeg),
[np.sin(adeg), np.cos(adeg)]]return np.matmul(x, rotation_matrix)
2.4.1 Trójkąt Sierpińskiego
Tak jak napisaliśmy na początku tego rozdziału, fraktale możemy budować ze zwykłych kropek, nie potrzebujemy bardziej wyrafinowanych poligonów. Przedstawmy to na bazie trójkąta Sierpińskiego.
Trójkąt Sierpińskiego składa się z trzech transformacji.
\[ y_1 = x * \left[\begin{smallmatrix} 0.5 & 0\\ 0 & 0.5 \end{smallmatrix}\right] \]
\[ y_2 = x * \left[\begin{smallmatrix} 0.5 & 0\\ 0 & 0.5 \end{smallmatrix}\right] + \left[\begin{smallmatrix} 0.5 \\ 0 \end{smallmatrix}\right] \]
\[ y_3 = x * \left[\begin{smallmatrix} 0.5 & 0\\ 0 & 0.5 \end{smallmatrix}\right] + \left[\begin{smallmatrix} 0.25 \\ \sqrt3/4 \end{smallmatrix}\right] \]
import matplotlib.pyplot as plt
import numpy as np
# przesunięcie punktu x o delta
def shift(x, delta):
return np.add(x, delta)
# przeskalowanie punktu x razy ratio
def scale(x, ratio):
return np.multiply(x, ratio)
# Poniższy program powtarza złożenie tych funkcji depth razy.
# W teorii robilibyśmy to w nieskończoność, ale do uzyskania
# wyraźnego obrazka wystarczy kilka kroków.
# Liczba punktów rośnie wykładniczo, więc po k krokach wynosi 3^k.
def sierpinski(x, depth):
if depth > 1:
= scale(shift(x, [0, 0]), [0.5, 0.5])
x1 - 1)
sierpinski(x1, depth = scale(shift(x, [0.5, 0]), [0.5, 0.5])
x2 - 1)
sierpinski(x2, depth = scale(shift(x, [0.25, 0.5]), [0.5, 0.5])
x3 - 1)
sierpinski(x3, depth else:
0], x[1], marker='o',
plt.plot(x[="black", markersize=3)
color
# Inicjacja rysunku i narysowanie trójkąta Sierpińskiego.
plt.figure() 0,0], depth = 7)
sierpinski([ plt.show()
2.4.2 Pięciokąt Sierpińskiego
import math
import numpy as np
import matplotlib.pyplot as plt
# przesunięcie punktu x o delta
def shift(x, delta):
return np.add(x, delta)
# przeskalowanie punktu x razy ratio
def scale(x, ratio):
return np.multiply(x, ratio)
def pentagon(x, depth, col="black"):
if depth > 1:
= shift(scale(x, [0.382,0.382]), [0,0])
x1 -1, col="red")
pentagon(x1, depth= shift(scale(x, [0.382,0.382]), [0.618,0])
x2 -1, col="blue")
pentagon(x2, depth= shift(scale(x, [0.382,0.382]), [0.809,0.588])
x3 -1, col="green")
pentagon(x3, depth= shift(scale(x, [0.382,0.382]), [0.309,0.951])
x4 -1, col="orange")
pentagon(x4, depth= shift(scale(x, [0.382,0.382]), [-0.191,0.588])
x5 -1, col="brown")
pentagon(x5, depthelse:
0],x[1], marker='o', color=col, markersize=3)
plt.plot(x[
plt.figure()0,0], depth=6, col)
pentagon([ plt.show()
2.4.3 Smok Heighwaya
import math
import numpy as np
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.pyplot as plt
# Przesunięcie punktu x o wektor delta.
def shift(x, delta):
return np.add(x, delta)
# Przeskalowanie punktu x razy ratio.
def scale(x, ratio):
return np.multiply(x, ratio)
# Obrót o kąt alpha (w stopniach).
def rotate(x, alpha):
= math.pi * alpha / 180
adeg = [
rotation_matrix -np.sin(adeg)],
[np.cos(adeg),
[np.sin(adeg), np.cos(adeg)]]return np.matmul(x, rotation_matrix)
def heighway(x, depth, col="black"):
if depth > 1:
= rotate(x, -45)
x1 = scale(x1, [np.sqrt(0.5), np.sqrt(0.5)])
x1 -1, col="blue")
heighway(x1, depth= rotate(x, -45)
x2 = scale(x2, [np.sqrt(0.5), np.sqrt(0.5)])
x2 = shift(x2, [0.75, 0.25])
x2 -1, col="red")
heighway(x2, depthelse:
0], x[1], marker='o', color=col, markersize=3)
plt.plot(x[
plt.figure()0,0], depth=14)
heighway([ plt.show()
2.4.4 Drzewo Pitagorasa
import numpy as np
import matplotlib.pyplot as plt
# Przesunięcie punktu x o wektor delta.
def shift(x, delta):
return np.add(x, delta)
# Przeskalowanie punktu x razy ratio.
def scale(x, ratio):
return np.multiply(x, ratio)
# Obrót o kąt alpha (w stopniach).
def rotate(x, alpha):
= math.pi * alpha / 180
adeg = [
rotation_matrix -np.sin(adeg)],
[np.cos(adeg),
[np.sin(adeg), np.cos(adeg)]]return np.matmul(x, rotation_matrix)
def sbt(x, depth, col="black"):
if depth > 1:
= rotate(x, -45)
x1 = shift(scale(x1, [0.7, 0.7]), [0, 1])
x1 -1, col="blue")
sbt(x1, depth= rotate(x, 45)
x2 = shift(scale(x2, [0.7, 0.7]), [0, 1])
x2 -1, col="red")
sbt(x2, depthelse:
0], x[1], marker='o', color=col, markersize=3)
plt.plot(x[
plt.figure()0,0], depth = 14)
sbt([ plt.show()