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}
Auf TeXwelt habe ich noch Variationen erzeugt, dort einmal mittels pgfplots ausgegeben.
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:
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.