Das folgende kleine Dokument berechnet und druckt einen [Barnsley-Farn][1] mittels des sog. Chaos Games: zufällig ausgewählte Transformationen werden wiederholt angewendet.
Hier verwende ich Lua zur Berechnung und pgfplots für die Ausgabe. Daher wird LuaLaTeX benötigt. Die Matrix m enthält die Koordinaten für die affinen Transformationen sowie ihre Wahrscheinlichkeiten, die dann summiert separat in der Wahrscheinlichkeitsmatrix pm abgelegt werden, damit ich nicht in der Schleife mehr addieren muss. Die Matrix-Schreibweise vereinfacht Veränderungen der Parameter.
Vorsicht, das Übersetzen dauert sehr lang! Ich habe 100000 Punkte berechnen lassen, wer das hier mal laufen lassen will, sollte zunächst einen viel kleineren Wert nehmen.
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\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("\\begin{axis}[hide axis]\\addplot["
.. options .. "] coordinates{")
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..")")
end
tex.sprint("};\\end{axis}")
end
\end{luacode*}
\begin{document}
\begin{tikzpicture}
\directlua{barnsley(100000, [[color=green!50!black, only marks,
mark size = 0.05pt]])}
\end{tikzpicture}
\end{document}
![Barnsley-Farn][2]
Die Matrix kann man verändern, um Fraktale zu erhalten, die mehr einem Baum, einem Busch oder anderen Farnen ähneln. Beispielsweise mit Werten von der oben verlinkten Wikipedia-Seite (m.E. original von [David Nicolls][3])
0.0, 0.0, 0.0, 0.25, 0.0, -0.14, 0.02,
0.85, 0.02, -0.02, 0.83, 0.0, 1.0, 0.84,
0.09, -0.28, 0.3, 0.11, 0.0, 0.6, 0.07,
-0.09, 0.28, 0.3, 0.09, 0.0, 0.7, 0.07
![Leptosporangiate-Farn][4]
0.0, 0.0, 0.0, 0.25, 0.0, -0.4, 0.02,
0.95, 0.005, -0.005, 0.93, -0.002, 0.5, 0.84,
0.035, -0.2, 0.16, 0.04, -0.09, 0.02, 0.07,
-0.04, 0.2, 0.16, 0.04, 0.083, 0.12, 0.07
![Thelypteridaceae-Farn][5]
Mit einer einfacheren Matrix und damit leicht verkürztem Code erhält man ein Sierpinski-Dreieck:
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepackage{luacode}
\begin{luacode*}
function ifs(iterations,options)
local x = math.random()
local y = math.random()
local m = {
0.5, 0, 0, 0.5, 0, 0, 0.3333,
0.5, 0, 0, 0.5, 0.25, 0.5, 0.3333,
0.5, 0, 0, 0.5, 0.5, 0, 0.3333,
}
local pm = { m[7], m[7] + m[14], m[7] + m[14] }
if options ~= [[]] then
tex.sprint("\\begin{axis}[hide axis]\\addplot["
.. options .. "] coordinates{")
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
else
case = 2
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..")")
end
tex.sprint("};\\end{axis}")
end
\end{luacode*}
\begin{document}
\begin{tikzpicture}
\directlua{ifs(20000, [[color=black, only marks,
mark size = 0.05pt]])}
\end{tikzpicture}
\end{document}
![Sierpinski-Dreieck][6]
Analog kann man einen Sierpinski-Teppich erhalten, und in 3D einen [Menger-Schwamm][7] aka Menger sponge. Bei letzterem stellt sich dann die Frage einer guten dreidimensionalen Darstellung.
[1]: http://en.wikipedia.org/wiki/Barnsley_fern
[2]: http://texwelt.de/wissen/upfiles/barnsley.png
[3]: http://www.home.aone.net.au/~byzantium/ferns/fractal.html
[4]: http://texwelt.de/wissen/upfiles/Leptosporangiate.png
[5]: http://texwelt.de/wissen/upfiles/Thelypteridaceae.pnghttp://texwelt.de/wissen/upfiles/Thelypteridaceae.png
[6]: http://texwelt.de/wissen/upfiles/sierpinski.png
[7]: http://de.wikipedia.org/wiki/Menger-Schwamm