2.5 Przykłady w języku R
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 transformacji. W tych przykładach x
jest dwuelementowym wektorem.
# Przesunięcie punktu x o delta.
= function(x, delta)
shift + delta
x
# Przeskalowanie punktu x razy ratio.
= function(x, ratio)
scale * ratio
x
# Obrót o kąt alpha (w stopniach).
= function(x, alpha) {
rotate = sin(pi * alpha / 180)
sa = cos(pi * alpha / 180)
ca %*% matrix(c(ca, -sa, sa, ca), 2, 2, byrow = TRUE)
x }
2.5.1 Trójkąt 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] \]
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.
# Zapis x |> scale(0.5) |> shift(0.2) w języku R oznacza
# ogonowe złożenie tych funkcji i jest równoważny zapisowi
# shift(scale(x, 0.5), 0.2). Jest jednak czytelniejszy.
<- function(x, depth, col = "black") {
sierpinski if (depth > 1) {
= x |> scale(0.5)
x1 sierpinski(x1, depth - 1, col = "blue")
= x |> scale(0.5) |> shift(c(0.5, 0))
x2 sierpinski(x2, depth - 1, col = "red")
= x |> scale(0.5) |> shift(c(0.25, 0.5))
x3 sierpinski(x3, depth - 1, col = "orange")
else {
} points(x[1], x[2], pch = 19, col = col, cex=0.3)
}
}
plot.new()
plot.window(xlim=c(0, 1), ylim=c(0,1), asp=1)
sierpinski(c(0,0), depth = 8)
2.5.2 Pięciokąt Sierpińskiego
<- function(x, depth, color="black") {
pentagon if (depth > 1) {
= x |> scale(0.382)
x1 pentagon(x1, depth - 1, color = "blue")
= x |> scale(0.382) |> shift(c(0.618, 0))
x2 pentagon(x2, depth - 1, color = "red")
= x |> scale(0.382) |> shift(c(0.809, 0.588))
x3 pentagon(x3, depth - 1, color = "green")
= x |> scale(0.382) |> shift(c(0.309, 0.951))
x4 pentagon(x4, depth - 1, color = "orange")
= x |> scale(0.382) |> shift(c(-0.191, 0.588))
x5 pentagon(x5, depth - 1, color = "pink")
else
} points(x[1], x[2], pch = 19, col = color, cex=0.5)
}
plot.new()
plot.window(xlim=c(-0.5,1.5), ylim=c(-0.1,1.7), asp=1)
pentagon(c(0,0), depth = 6)
2.5.3 Smok Heighwaya
<- function(x, depth, color="black") {
heighway if (depth > 1) {
= x|> rotate(45)|> scale(sqrt(0.5))|> shift(c(1,0))
x1 heighway(x1, depth-1, color="blue")
= x|> rotate(45)|> scale(sqrt(0.5))
x2 heighway(x2, depth-1, color="red")
else
} points(x[1], x[2], pch=19, col=color, cex=0.5)
}
plot.new()
plot.window(xlim=c(-1,2), ylim=c(-1.5,0.5), asp=1)
heighway(c(1,1), depth = 15)
2.5.4 Symetryczne drzewo binarne / drzewo Pitagorasa
= function(x, depth, color="black") {
pitagoras if (depth > 1) {
= x|> rotate(-45) |> scale(sqrt(0.5)) |> shift(c(0,1))
x1 pitagoras(x1, depth-1, color="blue")
= x|> rotate(45) |> scale(sqrt(0.5)) |> shift(c(0,1))
x2 pitagoras(x2, depth-1, color="red")
else
} points(x[1], x[2], pch=19, col=color, cex=0.5)
}
plot.new()
plot.window(xlim = c(-3,3), ylim = c(0,3), asp=1)
pitagoras(c(1,1), depth = 15)