mikefc

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 by B-A-B
    • Replace B by A+B+A
  • When drawing:
    • A and B 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 by X+YF+
    • Replace Y by -FX-Y
  • 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