L-system fractals with grid
graphics in R
This is a follow-up to the prior post - by changing the axiom and the L-system production rules you can change the type of fractal produced
Rather than simply calculating and drawing lines, I am interested in how viewports
in the grid
system work. So to draw L-systems, the movement and rotation of lines
are carried out by pushing new viewports on the viewing stack.
Sierpinski Arrowhead L-system: Axiom, Rules and drawing/viewport functions
See wikipedia for the background on this L-system.
Summary:
- Start with the string `A’ (the axiom)
- At every iteration:
- Replace
A
byB-A-B
- Replace
B
byA+B+A
- Replace
- When drawing:
A
andB
mean ‘move forward’+/-
mean to ‘rotate right/left’ by 60 degrees
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Sierpinski
# - axiom and rules
# - Reference: https://en.wikipedia.org/wiki/L-system
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
axiom <- el(strsplit('A', ''))
rules <- list(
'A' = el(strsplit('B-A-B', '')),
'B' = el(strsplit('A+B+A', ''))
)
f <- function() {
grid.lines(x = c(0.5, 0.5), y = c(0, length))
pushViewport(
viewport(x = 0.5, y = length, clip = 'off', just = c('centre', 'bottom')),
recording = FALSE
)
invisible()
}
plus <- function() {
pushViewport(
viewport(angle = 60, clip = 'off', x = 0.5, y = 0, just = c('centre', 'bottom')),
recording = FALSE
)
invisible()
}
minus <- function() {
pushViewport(
viewport(angle = -60, clip = 'off', x = 0.5, y = 0, just = c('centre', 'bottom')),
recording = FALSE
)
invisible()
}
Dragon Curve
- Start with the string `FX’ (the axiom)
- At every iteration:
- Replace
X
byX+YF+
- Replace
Y
by-FX-Y
- Replace
- When drawing:
F
meanss ‘move forward’+/-
mean to ‘rotate right/left’ by 90 degrees- ‘X’ and ‘Y’ do not correspond to drawing actions
axiom <- el(strsplit('FX', ''))
rules <- list(
'X' = el(strsplit('X+YF+', '')),
'Y' = el(strsplit('-FX-Y', ''))
)
f <- function() {
grid.lines(x = c(0.5, 0.5), y = c(0, length))
pushViewport(
viewport(x = 0.5, y = length, clip = 'off', just = c('centre', 'bottom')),
recording = FALSE
)
invisible()
}
plus <- function() {
pushViewport(
viewport(angle = -90, clip = 'off', x = 0.5, y = 0, just = c('centre', 'bottom')),
recording = FALSE
)
invisible()
}
minus <- function() {
pushViewport(
viewport(angle = 90, clip = 'off', x = 0.5, y = 0, just = c('centre', 'bottom')),
recording = FALSE
)
invisible()
}
Future
- Rendering other L-systems with grid graphics