我想用 TikZ 绘制一般的变形虫形状,但并不想过多考虑它的边界。基本上是一个具有平滑局部凸边界的封闭连通集。
有什么想法可以轻松做到这一点吗?
答案1
使用 PSTricks 制作的更加逼真的变形虫。
第一个版本
请跳过此第一个版本(因为有一个小故障)并跳至最终版本。
在这个版本中我使用了\psparametricplot
。在仔细研究了它的行为后,我注意到最后一个节点总是包含在创建封闭曲线中。因此,第一个节点和最后一个节点位于同一条径向线上,这使得曲线在连接它们的曲线上存在视觉缺陷。
我不知道如何在使用时排除最后一个节点\psparametricplot
。
\documentclass[pstricks]{standalone}
\usepackage{pst-plot}
\psset
{
plotstyle=ccurve,
fillstyle=solid,
fillcolor=gray,
}
\begin{document}
\begin{pspicture}(-3,-3)(3,3)
\psparametricplot[plotpoints=40]{0}{360}{/R rand 1001 mod 1000 div 1.5 add def R t PtoC}
\end{pspicture}
\end{document}
动画片
\documentclass[pstricks]{standalone}
\usepackage{pst-plot}
\psset
{
plotstyle=ccurve,
fillstyle=solid,
fillcolor=gray,
}
\begin{document}
\multido{\i=4+4}{20}{%
\begin{pspicture}(-3,-3)(3,3)
\psparametricplot[plotpoints=\i]{0}{360}{/R rand 1001 mod 1000 div 1.5 add def R t PtoC}
\end{pspicture}}
\end{document}
最终版本
在这个版本中,我用它\curvepnodes
来生成一个节点列表。\Pnodecount
表示最后一个元素的索引。
所以,
\multido{\i=0+1}{\Pnodecount}{\xdef\points{\points (P\i)}}
排除最后一个节点。
使用的一个优点\curvepnodes
是我们不需要计算角度步长。
\documentclass[pstricks]{standalone}
\usepackage{pst-node,pst-plot}
\psset{fillstyle=solid,fillcolor=gray}
\def\points{}
\pstVerb{666 srand}
\def\N{25}
\begin{document}
\begin{pspicture}(-3,-3)(3,3)
\curvepnodes[plotpoints=\N]{0}{360}{rand 16 mod 15 div 1.5 add t PtoC}{P}
\multido{\i=0+1}{\Pnodecount}{\xdef\points{\points (P\i)}}
\expandafter\psccurve\points
\end{pspicture}
\end{document}
动画片
\documentclass[pstricks]{standalone}
\usepackage{pst-node,pst-plot}
\usepackage{graphicx}
\newsavebox\IBox
\savebox\IBox{\includegraphics[width=6cm]{example-grid-100x100pt}}
\psset
{
fillstyle=solid,
fillcolor=gray,
xunit=\dimexpr\wd\IBox/6,
yunit=\dimexpr\ht\IBox/6,
}
\pstVerb{666 srand}
\begin{document}
\multido{\io=15+5}{10}{%
\def\points{}%
\begin{pspicture}(-3,-3)(3,3)
\curvepnodes[plotpoints=\io]{0}{360}{rand 16 mod 15 div 1.5 add t PtoC}{P}
\multido{\ii=0+1}{\Pnodecount}{\xdef\points{\points (P\ii)}}
\begin{psclip}{\expandafter\psccurve\points}
\rput(0,0){\usebox\IBox}
\end{psclip}
\end{pspicture}}
\end{document}
答案2
以下是使用 Peter Grill 链接的问题中的一个示例的示例。您需要来自TeX-SX 启动板站点:下载文件hobby.dtx
并运行tex hobby.dtx
以生成文件。运行pdflatex hobby.dtx
以生成文档。完成后,代码很简单:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{hobby}
\begin{document}
\begin{tikzpicture}
\fill[green!50] (0,0) .. (1,0) .. (1,3) .. (0,3) .. (0,1.5) .. cycle;
\fill[green!50] (3,0) .. +(1,0) .. +(1,2) .. +(1,3) .. +(0,3) .. cycle;
\fill[green!50] (6,0) .. +(1,0) .. +(1,1) .. +(1,2) .. +(1,3) .. +(0,3) .. +(0,1.5) .. cycle;
\end{tikzpicture}
\end{document}
生成:
(尽管您应该知道,我上面使用的特定语法可能会在 TikZ 的未来版本中失效;但有一种替代符号绝对不会失效)
答案3
我 [...] 并不想太深入地思考它的边界。基本上是一个具有光滑局部凸边界的封闭连通集。
每当我不愿意画曲线的时候对其边界进行过深入思考,我只是使用随机曲线。例如,这是一个使用 Metapost + Metafun 的解决方案(我发布了 ConTeXt 代码,但它也应该可以在独立的 metapost 中使用)
编辑正如 Karl 的学生的回答所示,如果你开始随机化更多点,你会得到更逼真的变形虫形状。基于这个想法,这里有另一个解决方案:(我认为有 20 个点的变形虫看起来相当逼真)。
\startMPdefinitions
vardef amoeba (expr n) =
(for i = 0 step 360/n until 360 - 360/n : (0.5*tand(i mod (30) + 20) randomized 0.1)*dir(i randomized 5) .. endfor cycle)
enddef;
\stopMPdefinitions
\starttext
\startMPpage[offset=2mm]
path a ;
for i = 1 upto 5 :
a := amoeba(10*i) scaled 2cm shifted (i*3cm,0);
fill a withcolor 0.8white;
draw a withpen pencircle scaled 2bp;
endfor
\stopMPpage
\stoptext
代码细目:
n
:点数。(0.5*tand(i mod (30) + 20) randomized 0.1)
:根据角度改变点与原点的距离i
。dir(i radnomized 5)
:i
表示角度。将角度随机化 5 度。
上一个答案
或随机性较低
这些曲线是使用
\startMPdefinitions
vardef amoeba =
(fullcircle randomized 0.8 cornered 0.15 randomized 0.1)
enddef;
\stopMPdefinitions
\starttext
\startMPpage[offset=2mm]
path a ;
for i = 1 upto 5 :
a := amoeba scaled 2cm shifted (i*3cm,0);
fill a withcolor 0.8white;
draw a withpen pencircle scaled 2bp;
endfor
\stopMPpage
\stoptext
在第二张图中,我将randomized 0.8
其改为randomized 0.3
。代码分解如下:
fullcircle
:以原点为中心绘制一个直径为 1 的圆randomized 0.8
:将圆的每个“点”随机化 0.8。由于圆的直径为 1,因此这会大大改变形状。降低此数字会产生更圆的形状。cornered 0.15
:用直线连接随机点,但不是用直角连接的线,而是用半径为 0.15 的角连接线。randomized 0.1
:再次随机化所有点,使其看起来分散。如果想要平滑的输出,请忽略此项。
除了从圆形开始,您还可以从更像变形虫的形状开始,以获得更真实的输出。