1.5 Examples in R
Dear Reader, you can reproduce the described fractals on your computer. All you need is an installed R language interpreter, which can be freely downloaded and installed from CRAN. No prior knowledge of this language is necessary, although it would, of course, be helpful. Here is some information to help you understand this code.
- The following examples use the basic graphics library for R, namely
graphics
. You don’t need to load it, as it is available immediately after starting R. Theplot.new()
function creates an empty graph. It is filled by using thepolygon()
function to draw filled polygons, here, a triangle and a square. - R is a language for mathematicians and statisticians, so most of the mathematical operations are available as soon as you start the console, like the
sqrt()
function needed to calculate the height of an equilateral triangle. - The R works natively on vectors, which means we can use arithmetic operators such as
+
or/
for both numbers and vectors. - To make the code more readable, we use recursion, a situation in which a function calls itself. New functions are defined using the
function
keyword. The functions shown have adepth
argument, specifying how many more times the function should call itself.
1.5.1 Cantor dust
Let’s start drawing fractals with Cantor dust. For this, we will use the recursive function dust
, which takes four arguments: x
, y
– the location from which to draw the fractal, scale
– information about the size of the fractal, and depth
– the current nesting level of the fractal.
# Recursive function to draw dust.
# If depth=1, it draws a line segment,
# if depth>1 it draws two copies of Cantor dust side by side.
= function(x, y, scale, depth = 1) {
dust if (depth == 0) {
lines(c(x, x + scale), c(y, y))
else {
} dust(x, y, scale/3, depth - 1)
dust(x + scale*2/3, y, scale/3, depth - 1)
}
}
# Clear the screen and start drawing dust.
plot.new()
dust(0, 0, scale = 1, depth = 4)
1.5.2 Sierpinski triangle
It’s time for the iconic Sierpiński triangle. To draw it, we will use the recursive function sierpinski()
, which takes four arguments: x
, y
– the location from which to draw the fractal, scale
– information about the size of the fractal, and depth
– the current nesting level of the fractal.
<- function(x, y, scale) {
triangle polygon(x + scale*c(0, 1, 1/2),
+ scale*c(0, 0, sqrt(3)/2), col = "black")
y
}
# Recursive function to draw Sierpiński triangle.
# If depth=1, we draw a triangle using the triangle() function,
# if depth>1, we draw three triangles side by side.
<- function(x, y, scale, depth = 1) {
sierpinski if (depth == 0) {
triangle(x, y, scale)
else {
} sierpinski(x, y, scale/2, depth-1)
sierpinski(x+scale/2, y, scale/2, depth-1)
sierpinski(x+scale/4, y+sqrt(3)*scale/4,scale/2,depth-1)
}
}
plot.new()
sierpinski(0, 0, scale = 1, depth = 6)
1.5.3 Sierpinski carpet
The fractal structure proposed by Wacław Sierpiński can be repeated for other shapes.
# Recursive function to draw a carpet.
# Depending on the current depth, it either draws a square or, recursively calls itself eight times.
= function(x, y, scale, depth = 1) {
carpet if (depth == 1) {
rect(x, y, x + scale, y + scale, col = "black")
else {
} carpet(x, y, scale/3, depth - 1)
carpet(x+scale*1/3, y, scale/3, depth - 1)
carpet(x+scale*2/3, y, scale/3, depth - 1)
carpet(x, y+scale*1/3, scale/3, depth - 1)
carpet(x+scale*2/3, y+scale*1/3, scale/3, depth - 1)
carpet(x, y+scale*2/3, scale/3, depth - 1)
carpet(x+scale*1/3, y+scale*2/3, scale/3, depth - 1)
carpet(x+scale*2/3, y+scale*2/3, scale/3, depth - 1)
}
}
plot.new()
carpet(0, 0, scale = 1, depth = 4)