3D-Plots beschneiden

Wenn Funktionswerte zu groß werden, können wir die grafische Darstellung beschneiden. Wie machen wir es geschickt, damit es auch noch gut aussieht? Wenn wir beispielsweise einen Surface-Plot zeichnen, die Oberfläche der Funktion durch sogenannte Patches darstellen, kann es etwas gezackt aussehen, statt gerade. Wie schlimm, richtet sich nach Anzahl der Samples, also der Teilpunkte: wählen wir mehr, so wird es feiner.

Schauen wir es uns am Beispiel an. Wir plotten einen Kegel und beschränken den Maximalwert der Höhe durch die Option restrict z to domain:

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    grid,
    domain=-5:5, y domain=-5:5,
    xmin=-10, xmax=10,
    ymin=-10, ymax=10,
    zmin=0,
    restrict z to domain=0:5
]
    \addplot3 [surf] {sqrt(x^2 + y^2};
  \end{axis}
\end{tikzpicture}
\end{document
}
Kegel in 3D

Ziemlich ausgefranst. Wir können anders beschneiden durch eine Variante der genannten Option mit *, also restrict z to domain*=0:5, das wird glatter:

Weiterlesen

Schreibe einen Kommentar

Zweifarbige Buchstaben

ZweifarbigesBMitunter werden in Foren lustige Sachen gewünscht: einmal brauchte jemand ein zweifarbiges Zeichen, die linke Seite sollte grün und die rechte rot sein.

Für das zweifarbige Zeichen wird ein Befehl \bicolorletter mit einem optionalen Argument für die Farben und einem obligatorischen für den Buchstaben definiert.

Der Befehl reserviert zunächst mit \phantom den benötigten Platz und fügt dann mit Hilfe von \clip die beiden farbigen Buchstabenhälften ein. Die beiden Farben können dabei über Stile festgelegt und geändert werden.

\documentclass[margin=5mm,varwidth]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\tikzset{
   bclleft/.style={.},
   letter left/.style={bclleft/.append style={#1}},
   bclright/.style={.},
   letter right/.style={bclright/.append style={#1}},
}
\newcommand\bicolorletter[2][]{%
   \tikz[baseline=(n.base),inner sep=0pt,outer xsep=0pt,#1]{
     \node(n){\phantom{#2}};
     \foreach \a/\c in {west/bclleft,east/bclright}{
       \begin{scope}
         \clip(n.south)rectangle(n.north \a);
         \node[\c]at(n){#2};
       \end{scope}
     }}}
\begin{document}
\tikzset{letter left=green,letter right=red}
Erst ein grün-roter Buchstabe: \bicolorletter{B}
\par
und dann ein orange-brauner:
\bicolorletter[letter left=orange,letter right=brown]{B}
\par
und wieder ein grün-roter: \bicolorletter{M}
\end{document
}

 

ZweifarbigeBuchstaben

Wie man in dem Code sieht, kann zum einen die Farbkombination grün-rot mit
Weiterlesen

Kommentare: 3

Feature request mit Blume

Sag’s mit einer Blume, und Dein Ansinnen wird freundlicher aufgenommen.

Das tat ich spontan mit einem feature request an den Autor von pgfplots. Nun weiß ich, dass er generell gern auf Fragen antwortet und Neues implementiert und das Paket sehr gut pflegt. Umso mehr Grund für ein Blümchen. :-)

Wenn ich Funktionen mit Polarkoordinaten parametrisiere, insbesondere mit Rotations-Symmetrie, habe ich oft mit Winkelfunktionen zu tun, also mit den trigonometrischen Funktionen wie beispielsweise Sinus und Cosinus. Winkel kann man in Grad angeben, den Vollkreis von 0 bis 360 Grad durchlaufen, oder man verwendet Radiant, entsprechend von 0 bis 2*pi. pgfplots verwendet Grad. Wenn ich das weiß, gebe ich den Quellbereich eben in Grad an und gut ist es, wie in dieser ersten Blüte:

Funktion in 3D

Der Code hierfür ist:
Weiterlesen

Schreibe einen Kommentar

Dynamische Füllhöhe eines Glases

Meine ersten Schritte in Foren habe ich vor ungefähr 5 1/2 Jahren auf dem Matheplaneten gemacht. In einer meiner ersten Antworten sollte damals ein Befehl definiert werden, mit dem ein unterschiedlich hoch gefülltes Wasserglas gezeichnet werden kann und der deshalb die relative Füllhöhe, also einen Wert zwischen 0 und 1, als Argument erwartet:

\Glas{<relative fuellhoehe>}

Der Pfad für das leere Glas war bereits vorgegeben:

\draw[very thick] (0,2) -- (0.25,0) -- (1.5,0) -- (1.75,2);

glasleer

Zur besseren Übersicht habe ich hier ein Gitternetz (Linienabstand: 0.25 cm) darunter gelegt und den Koordinatenursprung markiert.

Damaliger Lösungsvorschlag:
Weiterlesen

Kommentare: 2

Dynamische Systeme, Bifurkationen, prozedurale Welten

Nachdem ich im vorangehenden Post erwähnte, dass ich auch pgfplots zur grafischen Ausgabe nutze, möchte ich hier ein paar Beispiele nennen.

Als Vorteile von pgfplots gegenüber Basis-TikZ nutze ich hier:

  • einfaches Plotten mit 3D-Koordinaten und Schrägbildansicht
  • Darstellung zugehöriger Koordinatenachsen
  • Verwenden von Farbverläufen
  • Einlesen von Dateien, falls die Daten extern berechnet wurden.

In jedem Fall kann man hier wieder Lua zum Berechnen der Daten verwenden. Lua generiert uns die TeX-Befehle zur Ausgabe, die in der pgfplots-Achsen-Umgebung verarbeitet werden.

Hier die Beispiele, einfach draufklicken, um zur zugehörigen Diskussion auf TeXwelt zu gelangen, wo man den vollständigen Quellcode findet.

Lorenz-Attraktor (Dynamisches System)

Während ich auf TeXwelt eine auf Python basierende Version postete, brachte Henri eines, was LuaTeX verwendet, daher zunächst sein Bild:

Lorenz-Attraktor

Von pgfplots nutzte ich neben der einfachen 3D-Darstellung die Fähigkeit zum durchscheinenden Plotten, so erhalte ich eine Dichte-Darstellung:

Lorenz-Attraktor

Und der Code, hat man einmal die Daten berechnen lassen, ist einfach:

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
      xmin = -25, xmax = 25,
      ymin = -25, ymax = 25,
      zmin =   0, zmax = 50,
      hide axis,
   
]
    \addplot3[mark=none, mesh, shader=interp, color=black, opacity=0.2]
      file { lorenz.dat };
  \end{axis}
\end{tikzpicture}
\end{document
}

Fraktale Landschaften (Grundansatz für Produktion prozeduraler Welten)

Zwischen benachbart liegenden Punkten werden neue Punkte bestimmt mit zufälligen, aber begrenzten Variationen, was am Ende eine bergige “Landschaft” ergibt. Die errechneten Punkte gebe ich mit Farben entsprechend ihrer Höhe aus, also blau für Meeresspiegelhöhe und darunter, grün für Berge und weiß ab “Schneegrenze”.

Fraktale Landschaft

Nächster Schritt: ein paar Startwerte vorgeben, um mit einer vordesignten Grobstruktur zu starten, wie etwa einer Insel im Wasser.

Feigenbaum-Diagram (Bifurkationen)

Ein Klassiker der Chaos-Theorie und eng verwandt mit der Mandelbrot-Menge. Auch hier wird Transparenz verwendet für einen Eindruck der Punktdichte.

Feigenbaum-Diagramm

Themen dieser Art schneide ich auf TeXwelt.de gern an. Dort fragen nicht nur Bachelor-Schreiber um Hilfe, sondern es hat sich auch eingebürgert, dass TeX-Kenner und TikZ-Freunde ihre Ideen als Fragen in den Raum stellen und oft selbst eine der Antworten dazu geben.

 

Schreibe einen Kommentar

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.

\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.

 

Ein Kommentar

Rekusive Fraktale ganz simpel – L-Systeme

Lindenmayer-Systeme, kurz L-Systeme genannt, sind “Ersetzungs-Systeme”: Bei einem (grafischen) Objekt werden Teile davon ersetzt, im einfachsten Fall durch das verkleinerte Objekt selbst. Das wird wiederholt, beispielsweise rekursiv. Dadurch kann eine sehr komplexe fraktale Struktur entstehen und gleichzeitig sehr simpel definiert sein.

Das einfachste Beispiel ist die Koch-Kurve, auch als Schneeflockenkurve genannt. Wer sie nicht kennt, einfach den Links zur Wikipedia folgen. :-) Ich möchte sie hier ja nicht erklären, sondern nur kurz zeigen, wie man sie mit TikZ auf einfachste Weise erzeugen kann.

Bausteine sind Symbole für einfache grafische Operationen wie Zeichnen einer Linie oder Drehen um einen Winkel, diese Symbole werden in einer Zeichenkette angegeben, Teile dieser Zeichenkette werden durch “Produktionsregeln” schrittweise ersetzt. Die Kette wird immer länger, am Ende wird diese Zeichnung ausgeführt.

Im TikZ-Handbuch sind die Regeln im Kapitel 55 erklärt, das beschreibt die Lindenmeyer-System-Bibliothek, die eigens hierfür geschrieben wurde. Sie stellt eine Syntax zum einfachen Deklarieren eines solchen Objekts samt Regeln bereit und erledigt das Zeichnen.

Zur Motivation ein Dokument mit ein paar Beispiele, das ich mal für TeXample.net geschrieben hatte. Wie man sehen kann, ist jedes der vier Beispiele simpel definiert. Ich habe noch wild Farben und Farbverläufe dazu getan, nur um zu zeigen, dass man mit TikZ noch weiterbearbeiten kann.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\usetikzlibrary[shadings]
\begin{document}
\pgfdeclarelindenmayersystem{Koch curve}{
  \rule{F -> F-F++F-F}}
\pgfdeclarelindenmayersystem{Sierpinski triangle}{
  \rule{F -> G-F-G}
  \rule{G -> F+G+F}}
\pgfdeclarelindenmayersystem{Fractal plant}{
  \rule{X -> F-[[X]+X]+F[+FX]-X}
  \rule{F -> FF}}
\pgfdeclarelindenmayersystem{Hilbert curve}{
  \rule{L -> +RF-LFL-FR+}
  \rule{R -> -LF+RFR+FL-}}

\begin{tabular}{cc}
\begin{tikzpicture}
\shadedraw[shading=color wheel]
[l-system={Koch curve, step=2pt, angle=60, axiom=F++F++F, order=4}]
lindenmayer system -- cycle;
\end{tikzpicture}
&
\begin{tikzpicture}
\shadedraw [top color=white, bottom color=blue!80, draw=blue!80!black]
[l-system={Sierpinski triangle, step=2pt, angle=60, axiom=F, order=8}]
lindenmayer system -- cycle;
\end{tikzpicture}
\\
\begin{tikzpicture}
    \shadedraw [bottom color=white, top color=red!80, draw=red!80!black]
    [l-system={Hilbert curve, axiom=L, order=5, step=8pt, angle=90}]
    lindenmayer system;
\end{tikzpicture}
&
\begin{tikzpicture}
    \draw [green!50!black, rotate=90]
    [l-system={Fractal plant, axiom=X, order=6, step=2pt, angle=25}]
    lindenmayer system;
\end{tikzpicture}
\end{tabular}
\end{document
}
Beispiele für L-Systeme

Jetzt kann man selber Bäume basteln, berühmte Kurven wie z.B. die Piano-Kurve nachbauen, die Drachenkurve, oder eigene erfinden – viel Spaß beim Ausprobieren!

Schreibe einen Kommentar

Komplexe Fraktale mit TikZ

Neulich besann ich mich in nostalgischer Weise zurück an die Zeit der 80er, als ich auf einem 8-bit Kleincomputer Nächte hindurch Fraktale berechnete, angefangen mit dem “Apfelmännchen”. Unter dem Namen kennt man die Mandelbrot-Menge, eine sehr formenreiche Menge in der komplexen Zahlenebene. Das meinte ich mit komplex – ihre Struktur ist es aber auch. Faszinierend, dass innerhalb dieses chaotisch erscheinenden Konstrukts dennoch Ähnlichkeiten und Gesetzmäßigkeiten auftreten.

Wenn man früher einen Text über Fraktale schrieb, generierte man Grafiken mit speziellen Programmen, die man in sein Dokument hineinkopierte. Schreibe ich heute mit LaTeX einen Artikel über Fraktale, so könnte ich sie direkt im Dokument definieren und sie würden automatisch mit berechnet und im Text ausgegeben.

Das habe ich nun mal durchgezogen:

  • Berechnung des Fraktales durch einige eingebettete Lua-Zeilen
  • Ausgabe mit dem PGFPlots-Paket
  • Übersetzen mit LuaLaTeX

PGFPlots übernimmt gleich das Sampling, also das punktweise Durchgehen der Ebene als Ausgangswerte, Lua berechnet den jeweiligen Punkt, PGFplots färbt entsprechend ein und gibt aus. Wenn ich möchte, auch mit Achsen und Beschriftung.

Ich habe das einmal programmiert und auf TeXwelt gepostet, Christian brachte noch eine Verbesserung ein, so haben wir dieses Resultat:

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.8}
\usepackage{luacode}
\begin{luacode}
  function mandelbrot(cx, cy, max_iter, max)
    local x, y, xtemp, ytemp, squaresum, iter
    squaresum = 0
    x = 0
    y = 0
    iter = 0
    while (squaresum <= max) and (iter < max_iter) do
      xtemp = x * x - y * y + cx
      ytemp = 2 * x * y + cy
      x = xtemp
      y = ytemp
      iter = iter + 1
      squaresum = x * x + y * y
    end
    local result = 0
    if (iter < max_iter) then
        result = iter
    end
    tex.print(result);
  end
\end{luacode}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    colorbar,
    point meta max=30,
    tick label style={font=\tiny},
    view={0}{90}
]
    \addplot3 [surf, domain = -1.5:0.5, shader = interp,
      domain y = -1:1, samples = 200
] {
      \directlua{mandelbrot(\pgfmathfloatvalueof\x,
        \pgfmathfloatvalueof\y, 10000, 4)}
    };
  \end{axis}
\end{tikzpicture}
\end{document
}

Das ist sogar ein 3D-Plot, mit der Iterations-Zahl als dritte Dimension, die wir aber nur mit view={0}{90} als “Draufsicht” mit ihrer Farbigkeit darstellen. Wir erhalten mit der Standard-Colormap:

Mandelbrot-Menge

Mit kleiner Modifikation, der Code steht hier, erhalten wir eine verwandte Julia-Menge, diesmal mit anderer Einfärbung:

Julia-Menge

Nun kann man mit erhöhter Iterations-Zahl hinein zoomen, das benötigt mehr Rechenleistung. Doch dann kann man wieder hochperformante Tools wie FractInt zum Forschen verwenden und damit gefundene interessante Intervalle hiermit darstellen.

Schreibe einen Kommentar