Iterierte Fraktale

Im Anschluss an die L-Systeme befasste ich mich mit Iterierten Funktionen-Systemen, kurz IFS. Auch hier haben wir wiederholte Transformationen: der Raum wird immer wieder in sich selbst abgebildet. Hierbei kann es verschiedene Abbildungsvorschriften geben. Das tun wir am besten unendlich oft 🙂 und betrachten die Menge im Raum, die bei alledem invariant bleibt. Diese kann nun fraktal sein!

Genug der Theorie, die man auf Wikipedia einstiegshalber und tiefer in tollen Büchern nachlesen kann. Wie produzieren wir sowas nun? Der einfachste Ansatz ist das sogenannte “Chaosspiel”: wie nehmen einen Punkt her, und wenden eine der Transformationen an. Da es um Punktmengen geht, die invariant sind unter den Transformationen, muss der Zielpunkt wieder in der Menge landen. Mit diesem neuen Punkt wiederholen wir das, abertausendfach, bis sich ein Bild abzeichnet.

Dann tun wir das doch mit dem berühmten Barnsley-Farn!

Doch wie? Wir brauchen Schleifen, und die Möglichkeit zur Berechnung affiner Transformationen. Mit pgfmath ist das machbar, aber meiner Ansicht nach gar nicht gut leserlich. Ich nehme dafür Lua her, um einmal zu nutzen, dass ich eine Programmiersprache im üblichen Sinn integrieren kann. Damit ist das einfach geschrieben. Die Parameter schreibe ich in eine Matrix, also Transformations-Parmeter und Wahrscheinlichkeiten der Transformations-Auswahl im Chaos-Spiel – lassen wir den Punkt rennen!

Wir benötigen zum Übersetzen LuaTeX und Geduld. Beim Ausprobieren oder Parameter-Spielen am besten erstmal geringe Iterations-Anzahl nehmen.

% !TEX lualatex
\documentclass[tikz,border=10pt]{standalone}
\usepackage{luacode}
\begin{luacode*}
  function barnsley(iterations,options)
    local x = math.random()
    local y = math.random()
    local m = {
        0.0,   0.0,   0.0, 0.16, 0.0,  0.0, 0.01,
       0.85,  0.04, -0.04, 0.85, 0.0,  1.6, 0.85,
        0.2, -0.26,  0.23, 0.22, 0.0,  1.6, 0.07,
      -0.15,  0.28,  0.26, 0.24, 0.0, 0.44, 0.07
    }
    local pm = { m[7], m[7] + m[14], m[7] + m[14] + m[21] }
    if options ~= [[]] then
      tex.sprint("\\draw[" .. options .. "] ")
    else
      tex.sprint("\\addplot coordinates{")
    end
    for i=1, iterations do
      p = math.random()
      if     p < pm[1] then
        case = 0
      elseif p < pm[2] then
        case = 1
      elseif p < pm[3] then
        case = 2
      else
        case = 3
      end
      newx = (m[7*case+1] * x) + (m[7*case+2] * y) + m[7*case+5]
         y = (m[7*case+3] * x) + (m[7*case+4] * y) + m[7*case+6]
         x = newx
      tex.sprint("("..x..","..y..") circle (0.05pt)")
    end
    tex.sprint(";")
  end
\end{luacode*}
\begin{document}
\begin{tikzpicture}
  \directlua{barnsley(100000, [[color=green!50!black,fill]])}
\end{tikzpicture}
\end{document}
Barnsley-Farn

Auf TeXwelt habe ich noch Variationen erzeugt, dort einmal mittels pgfplots ausgegeben.

Farn-Variation Farn-Variation

Und auch das berühmte Sierpinski-Dreieck kann man, statt als L-System, auch als IFS-Fraktal im Chaos-Spiel erzeugen, der ganz analoge Quellcode steht auch wie oben verlinkt auf TeXwelt.de:

Sierpinski-Dreieck

Nun das ganze noch in drei Dimensionen, oder? 🙂 Kein Scherz - analog zum obigen Dreieck gibt es den quadratischen Sierpinski-Teppich, der in drei Dimensionen zum Menger-Schwamm wird.

 


Posted

in

by

Tags: