![TikZ-Dekoration: Steuerung der Dekorationsamplitude entlang der Kurve](https://rvso.com/image/392325/TikZ-Dekoration%3A%20Steuerung%20der%20Dekorationsamplitude%20entlang%20der%20Kurve.png)
Arbeiten mit Pfaddekorationen basierend aufdiese Lösungbereitgestellt von Marmot. Ich suche nach einer Möglichkeit, die Dekorationsamplitude entlang des Diagramms zu ändern.
Mit diesem Grundstück
die Anwendung der genannten Dekoration gibt
und genau das ist der Zweck der Dekoration.
Tatsächlich sollte die erforderliche Kurve wie folgt aussehen:
Die letzte Ausgabe wurde durch manuelles Suchen der richtigen Positionen zur Manipulation der Amplitude erstellt, was eine "Versuch und Irrtum"-Methode ist. Das Ändern der Dimensionen tikzpicture
führt dann zu einem falschen Ergebnis, z. B.
Die Grundidee besteht nun darin, einen separaten Pfad bereitzustellen (der während der Entwicklung sichtbar gemacht werden kann), um die Dekorationsamplitude entlang der ursprünglichen (blauen) Kurve zu steuern. In diesem Fall wäre der Steuerpfad (rot) ganz einfach:
Der Regelweg kann als Faktor für die über einstellbare Dekorationsamplitude interpretiert werden decoration={amplitude=}
.
Obwohl diese Methode ganz praktisch wäre, bin ich etwas verblüfft, dass sie nicht verfügbar ist TikZ
- oder habe ich sie übersehen? Und wenn nicht: Wie kann ich den y-Wert der Kontrollkurve innerhalb des \state{step}
Teils der Dekorationsdefinition erhalten?
Der MWE erzeugt alle oben genannten Grafiken (auch wenn sie im Hinblick auf Effizienz und strukturelle Schönheit nicht schön codiert sind):
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing}
\newcounter{randymark}
\newcommand{\amplitudesetter}{}
\pgfdeclaredecoration{mark random y steps}{start}
{%
\state{start}[width=+0pt,next state=step,persistent precomputation={\pgfdecoratepathhascornerstrue\setcounter{randymark}{0}}]
{\stepcounter{randymark}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpoint{0pt}{0pt}}
}%
\state{step}[auto end on length=1.5\pgfdecorationsegmentlength,
auto corner on length=1.5\pgfdecorationsegmentlength,
width=+\pgfdecorationsegmentlength]
{\stepcounter{randymark}\amplitudesetter
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpoint{\pgfdecorationsegmentlength}{rand*\pgfdecorationsegmentamplitude}}
}%
\state{final}
{\stepcounter{randymark}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpointdecoratedpathlast}%
}%
}%
\begin{document}
\begin{tikzpicture}[x=5mm,y=5mm,decoration={mark random y steps,segment length=1.5mm,amplitude=0.75mm}]% original curve
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\draw[blue!80!black,thick] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\end{tikzpicture}
\vspace{2ex}
\begin{tikzpicture}[x=5mm,y=5mm,decoration={mark random y steps,segment length=1.5mm,amplitude=0.75mm}]% original curve
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\draw[black] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\path[decorate] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\draw[blue!80!black,thick] plot[variable=\x,samples at={1,...,\arabic{randymark}},smooth] (randymark\x);
\end{tikzpicture}
\vspace{2ex}
\begin{tikzpicture}[x=5mm,y=5mm,decoration={mark random y steps,segment length=1.5mm,amplitude=0.75mm}]% original curve
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\renewcommand{\amplitudesetter}{%
\pgfdecorationsegmentamplitude=0.75mm
\ifnum\value{randymark}<48\pgfdecorationsegmentamplitude=0.7mm\fi%
\ifnum\value{randymark}<46\pgfdecorationsegmentamplitude=0.6mm\fi%
\ifnum\value{randymark}<44\pgfdecorationsegmentamplitude=0.5mm\fi%
\ifnum\value{randymark}<42\pgfdecorationsegmentamplitude=0.4mm\fi%
\ifnum\value{randymark}<40\pgfdecorationsegmentamplitude=0.3mm\fi%
\ifnum\value{randymark}<38\pgfdecorationsegmentamplitude=0.2mm\fi%
\ifnum\value{randymark}<36\pgfdecorationsegmentamplitude=0.1mm\fi%
\ifnum\value{randymark}<34\pgfdecorationsegmentamplitude=0mm\fi%
\ifnum\value{randymark}<8\pgfdecorationsegmentamplitude=0.75mm\fi%
}
\draw[black] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\path[decorate] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\draw[blue!80!black,thick] plot[variable=\x,samples at={1,...,\arabic{randymark}},smooth] (randymark\x);
\end{tikzpicture}
\vspace{2ex}
\begin{tikzpicture}[x=2.5mm,y=2.5mm,decoration={mark random y steps,segment length=1.5mm,amplitude=0.75mm}]% original curve
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\renewcommand{\amplitudesetter}{%
\pgfdecorationsegmentamplitude=0.75mm
\ifnum\value{randymark}<48\pgfdecorationsegmentamplitude=0.7mm\fi%
\ifnum\value{randymark}<46\pgfdecorationsegmentamplitude=0.6mm\fi%
\ifnum\value{randymark}<44\pgfdecorationsegmentamplitude=0.5mm\fi%
\ifnum\value{randymark}<42\pgfdecorationsegmentamplitude=0.4mm\fi%
\ifnum\value{randymark}<40\pgfdecorationsegmentamplitude=0.3mm\fi%
\ifnum\value{randymark}<38\pgfdecorationsegmentamplitude=0.2mm\fi%
\ifnum\value{randymark}<36\pgfdecorationsegmentamplitude=0.1mm\fi%
\ifnum\value{randymark}<34\pgfdecorationsegmentamplitude=0mm\fi%
\ifnum\value{randymark}<8\pgfdecorationsegmentamplitude=0.75mm\fi%
}
\draw[black] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\path[decorate] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\draw[blue!80!black,thick] plot[variable=\x,samples at={1,...,\arabic{randymark}},smooth] (randymark\x);
\end{tikzpicture}
\vspace{2ex}
\begin{tikzpicture}[x=5mm,y=5mm,decoration={mark random y steps,segment length=1.5mm,amplitude=0.75mm}]
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\draw [red,thick,name=amplitudecontrol] (0,1) -- (2,1) -- (2,0) -- (7,0) -- (12,1) -- (25,1);
\draw[blue!80!black,thick] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\end{tikzpicture}
\end{document}
Antwort1
Lassen Sie mich zunächst sagen, dass mir diese Frage wirklich gefällt und ich wirklich beeindruckt bin von dem, was Sie erreicht haben. Hier ist ein Vorschlag zur Skalierbarkeit. Definieren Sie eine Funktion, die die Amplitude steuert,
varyingamp(x) = whatever you like
wobei x
der Bruchteil des dekorierten Pfades ist (um Skalierbarkeit zu gewährleisten). (Eine solche Funktion wurde bereits verwendetHierum variable Linienbreiten zu haben. Es würde mich überhaupt nicht überraschen, wenn ähnliche Dinge schon einmal verwendet worden wären.) Dies ist das MWE.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathmorphing}
\newcounter{randymark}
%\newcommand{\amplitudesetter}{}
\pgfdeclaredecoration{mark random y steps}{start}
{%
\state{start}[width=+0pt,next state=step,persistent precomputation={
\pgfdecoratepathhascornerstrue\setcounter{randymark}{0}}]
{\stepcounter{randymark}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpoint{0pt}{0pt}}
}%
\state{step}[auto end on length=1.5\pgfdecorationsegmentlength,
auto corner on length=1.5\pgfdecorationsegmentlength,
width=+\pgfdecorationsegmentlength]
{\stepcounter{randymark}%\amplitudesetter
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpoint{\pgfdecorationsegmentlength}{rand*\pgfdecorationsegmentamplitude}}
}%
\state{final}
{\stepcounter{randymark}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpointdecoratedpathlast}%
}%
}%
\pgfdeclaredecoration{mark varying random y steps}{start}
{%
\state{start}[width=+0pt,next state=step,persistent precomputation={
\pgfdecoratepathhascornerstrue\setcounter{randymark}{0}}]
{\stepcounter{randymark}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpoint{0pt}{0pt}}
}%
\state{step}[auto end on length=1.5\pgfdecorationsegmentlength,
auto corner on length=1.5\pgfdecorationsegmentlength,
width=+\pgfdecorationsegmentlength]
{\stepcounter{randymark}
\pgfmathsetmacro{\myfraction}{\the\pgfdecorationsegmentlength*\value{randymark}/\pgfdecoratedpathlength}
\pgfmathsetmacro{\myamplitude}{varyingamp(\myfraction)}
%\typeout{\myfraction,\myamplitude}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpoint{\pgfdecorationsegmentlength}{rand*\myamplitude*\pgfdecorationsegmentamplitude}}
}%
\state{final}
{\stepcounter{randymark}
\pgfcoordinate{randymark\arabic{randymark}}{\pgfpointdecoratedpathlast}%
}%
}%
\begin{document}
\begin{tikzpicture}[x=5mm,y=5mm,decoration={mark random y steps,segment length=1.5mm,amplitude=0.75mm}]% original curve
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\draw[blue!80!black,thick] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\end{tikzpicture}
\vspace{2ex}
\begin{tikzpicture}[x=5mm,y=5mm,decoration={mark varying random y steps,segment
length=1.5mm,amplitude=0.75mm},declare function={
varyingamp(\x)=ifthenelse(\x<0.08,1,ifthenelse(\x<0.28,0,ifthenelse(\x<0.48,5*(\x-0.28),1)));}]%
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\draw[red,thick] plot[variable=\x,domain=0:25,samples=101] ({\x},{varyingamp(\x/25)});
\pgfmathsetseed{2}
\draw[black] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\path[decorate] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\draw[blue!80!black,thick] plot[variable=\x,samples at={1,...,\arabic{randymark}},smooth] (randymark\x);
\end{tikzpicture}
\vspace{2ex}
\begin{tikzpicture}[x=2.5mm,y=2.5mm,decoration={mark varying random y
steps,segment length=0.75mm,amplitude=0.75mm},declare function={
varyingamp(\x)=ifthenelse(\x<0.08,1,ifthenelse(\x<0.28,0,ifthenelse(\x<0.48,5*(\x-0.28),1)));}]
\draw[style=help lines] (0,-4) grid[step=5mm] (25,1);
\pgfmathsetseed{2}
\draw[black] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\path[decorate] (0,0) -- (2,0) to [out=0,in=180](4,-3.5) to [out=0,in=225](6,-1.75) to [out=45,in=180](11,0) -- (24.25,0);
\draw[blue!80!black,thick] plot[variable=\x,samples at={1,...,\arabic{randymark}},smooth] (randymark\x);
\end{tikzpicture}
\end{document}
Die Funktion wird im zweiten Diagramm rot dargestellt. Das dritte Diagramm zeigt die Skalierbarkeit. (Natürlich müssen Sie auch die Segmentlängen neu skalieren. Beachten Sie auch, dass diese Verzierung diskrete Schritte hat. Wenn Sie also eine stark variierende Funktion, aber nur wenige Schritte haben, wird die Funktion möglicherweise nicht vollständig „geschätzt“, da sie nur an wenigen Punkten ausgewertet wird.)