我想创建一个装饰,用灰色透明云装饰一条路径,云的移动、喷发数量和缩放大小都是随机的。这个想法是让它看起来像冒烟一样。
我尝试定义自己的装饰,尝试使用形状背景和标记,但都没有真正起作用。最后,我设法在循环中绘制云,但这当然不是最优雅的解决方案。所以这是我的解决方案和尝试的代码,以及预期的结果:
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.pathmorphing, decorations.markings, decorations.shapes}
\usetikzlibrary{shapes,calc}
\makeatletter
\newdimen\cloud@sep
\cloud@sep=0.2cm\relax
\pgfdeclaredecoration{smoke}{initial}{
\state{initial}[width=\cloud@sep]
{
\pgfsetfillopacity{0.3}
\def\tikz@fillcolor{mygray}
\tikz@mode@filltrue
\pgfnode{cloud}{center}{}{}{}
\pgfmathsetlength\cloud@sep{0.2cm + rand*0.2cm}
\global\cloud@sep=\cloud@sep
}
\state{final}
{
\pgfpathmoveto{\pgfpointdecoratedpathlast}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\foreach \i [evaluate={\j=\i-1;}] in {1,2,...,20} {%
\node[shape=cloud, cloud puffs=9+5*rnd, fill=gray, opacity=0.4, %
minimum width=4+\j, minimum height=3+0.5*\j] at %
($(60:1) + 0.09*(\i,0) + 0.1*(0,\i) + 0.25*(rand,0) + 0.1*(0,rand)$) {}; }
\end{tikzpicture}
%% the code that does not work
\begin{tikzpicture}
\path[decorate,decoration={smoke, shape start width=1.5mm, shape end
width=2.5mm, shape start height=2mm, shape end height=3mm},
decoration={shape scaled}, fill=gray] (60:1.5) -- (50:3);
\end{tikzpicture}
\begin{tikzpicture}
\path[decorate,decoration={shape backgrounds, shape=cloud, shape
width=4mm+rand, shape height=3mm+rand}, cloud puffs=11+3*rand, fill=gray,
opacity=0.3] (60:1.5) -- (50:3);
\end{tikzpicture}
\end{document}
是否可以定义/指定这样的装饰?请注意,最好有一个装饰,其中每个云都在不同的透明度组中,也就是说,人们可以看到它们的重叠。
答案1
第一个版本
以下是通过装饰实现的可能解决方案markings
(灰色云在一条线上,橙色云在一圈上):
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.markings,shapes,calc}
\tikzset{
random clouds/.style={
decoration={markings,mark=between positions 0 and 1 step 5mm with {
\pgfmathsetmacro\myh{5mm+ rnd*1cm}
\pgfmathsetmacro\myw{\myh + 5mm + rnd*1cm}
\node[shape=cloud, cloud puffs={10+int(5*rnd)}, fill=#1, opacity=0.4,
minimum width=\myw,minimum height=\myh]
at (rand * 1cm,rand * 1cm) {};
}},
},
}
\begin{document}
\begin{tikzpicture}
\path[decorate,random clouds=gray]
(0,0) -- (10,10);
\path[decorate,random clouds=red]
(5,5) circle (3cm);
\end{tikzpicture}
\end{document}
第二个版本(淡出淡出)
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.markings,shapes,calc}
\tikzset{
random clouds/.style={
decoration={markings,mark=between positions 0 and 1 step 5mm with {
\pgfmathsetmacro\myh{15mm + rnd*1cm}
\pgfmathsetmacro\myw{\myh + 5mm + rnd*1cm}
\pgfkeysgetvalue{/pgf/decoration/mark info/distance from start}{\currdist}
\pgfmathsetmacro\myop{1-\currdist/\pgfdecoratedpathlength}
\node[shape=cloud, cloud puffs={10+int(5*rnd)}, fill=#1, opacity=\myop,
minimum width=\myw,minimum height=\myh]
at (rand * 1cm,rand * 1cm) {};
}},
},
}
\begin{document}
\begin{tikzpicture}
\path[decorate,random clouds=orange]
(0,0) -- (10,10);
\end{tikzpicture}
\end{document}
第三版(带有控制大小和颜色的按键)
在这个版本中,云的大小不是随机的。
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.markings,shapes,calc}
\makeatletter
\tikzset{
random clouds/.is family,
random clouds,
color/.store in=\randomclouds@c,
start width/.store in=\randomclouds@startw,
start height/.store in=\randomclouds@starth,
end width/.store in=\randomclouds@endw,
end height/.store in=\randomclouds@endh,
color=gray,
start width=22mm,start height=12mm,
end width=14mm,end height=8mm
}
\tikzset{
random clouds decoration/.style={
decoration={markings,mark=between positions 0 and 1 step 5mm with {
\tikzset{random clouds,#1}
\pgfkeysgetvalue{/pgf/decoration/mark info/distance from start}{\currdist}
\pgfmathsetmacro\myop{1-\currdist/\pgfdecoratedpathlength}
\pgfmathsetmacro\myw{\randomclouds@endw+\myop*(\randomclouds@startw-\randomclouds@endw)}
\pgfmathsetmacro\myh{\randomclouds@endh+\myop*(\randomclouds@starth-\randomclouds@endh)}
\node[shape=cloud, cloud puffs={10+int(5*rnd)},fill=\randomclouds@c, opacity=\myop,
minimum width=\myw,minimum height=\myh]
at (rand * 1cm,rand * 1cm) {};
}},
},
}
\makeatother
\pgfmathsetseed{\pdfuniformdeviate 1000000}
\begin{document}
\begin{tikzpicture}
\path[decorate,random clouds decoration]
(0,0) -- (10,10);
\path[decorate,random clouds decoration={
color=orange,
start width=12mm,end width=5mm,
start height=22mm,end height=10mm,
}]
(5,0) -- (15,10);
\end{tikzpicture}
\end{document}
答案2
我开始尝试做需要做的事情,但后来偏离了主题。结果看起来很酷(只要你看得不太仔细),但是完全地不切实际的:
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.pathmorphing,backgrounds}
\begin{document}
\begin{tikzpicture}[background rectangle/.style={fill=black},
show background rectangle]
\foreach \i in {1,...,10}
\fill [gray, even odd rule, opacity=0.125,rounded corners=2pt, decoration={random steps, amplitude=.125cm, segment length=.125cm}, decorate]
(0,0) plot [domain=0:360, samples=50] ({sin(\x*4)/500*\x+rand/(2.9-\x/180)}, \x/100+rand/2) --
plot [domain=360:0, samples=50] ({sin(\x*4)/500*\x+rand/(2.9-\x/180)}, \x/100+rand/2);
\end{tikzpicture}
\end{document}
在编译完成之前,你可能需要抽好几斗烟:
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.pathmorphing,backgrounds}
\begin{document}
\foreach \n in {1,1.1,...,4}{
\begin{tikzpicture}[background rectangle/.style={fill=black},
show background rectangle]
\useasboundingbox (-5,4) rectangle (5,10);
\foreach \i in {1,...,10}
\fill [gray, even odd rule, opacity=0.125, decoration={random steps, amplitude=.125cm*\n, segment length=.125cm}, decorate]
(\n,\n*3) arc (0:360:\n\space and \n/4) arc (360:0:\n\space and \n/4) -- cycle;
\end{tikzpicture}
}
\end{document}