我想使用 TikZ/PGF 创建以下类型的图表:
用文字来说:由粗的“随机”曲线组成的圆圈。
这种波浪线样式来自 David Mumford 对方案通用点的描述。另一个示例是:
与我想要的最近的现有答案是此主题,但它仍然有很大不同。具体来说,我希望它能循环回到自身。如果能够轻松控制圆的密度和宽度就更好了。不过,在中间画一个点并不是重点。
答案1
这是一个可能的 TikZ 解决方案:
\documentclass[tikz,border=7mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
% create \n random points around the circle with radious 5
\def\n{50}
\xdef\pts{}
\foreach \i in {1,...,\n}{
\xdef\pts{\pts ({\i/\n*360}:{5+rnd})}
}
\begin{tikzpicture}
%draw random curve with some tension
\draw[red, thick, smooth, tension=10] plot coordinates {\pts}--cycle;
\end{tikzpicture}
\end{document}
答案2
波浪线
以下示例在极
坐标系中随机绘制波浪线。它绘制了 12 个圆圈,每个圆圈有 500 个点。每个点都
指定为极坐标。半径允许在半个半径到
半个半径的范围内。向前或
向后的角度最大可达十度。更改参数可以配置
“波浪线”。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\def\radius{2cm}
\pgfmathsetseed{1000}
\draw
plot[
smooth cycle,
samples=500,
domain=0:360*12,
variable=\t,
]
(\t + rand*10:{\radius*(1 + rand*.5)})
;
\fill circle[radius=1mm];
\end{tikzpicture}
\end{document}
具有更清晰的参数化和中间点的示例:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\def\InnerRadius{1cm}
\def\OuterRadius{3cm}
\def\PointsPerCircle{30}
\def\NumOfCircles{15}
\def\DeltaAngle{10}
\pgfmathsetseed{2000}
\draw[]
plot[
smooth cycle,
samples=\PointsPerCircle*\NumOfCircles + 1,
domain=0:360*\NumOfCircles,
variable=\t,
]
( \t + rand*\DeltaAngle:
{\InnerRadius + random*(\OuterRadius-\InnerRadius)})
;
\fill circle[radius=1mm];
\end{tikzpicture}
\end{document}
线
以下示例为第二个示例提供了建议。该线从左向右移动,随机变化X方向(向前和向后)。随机 x-delta 和随机振幅均使用 sin 2函数在 0 到 180 的范围内建模。因此,振幅在中间达到最大值。
前一点的距离遵循几何级数。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\fill[radius=1mm]
\foreach \prim [count=\i] in {2, 3, 5, 7, 11, 13, {}, {}, {}, {}} {
({\i*1.8 - \i*(\i-1)*.5*0.175}, 0) circle[]
node[below=1mm] (p\prim) {\prim}
}
++(1mm, 0) coordinate (endofline)
++(25mm, 0) coordinate (end)
;
\pgfmathsetseed{2000}
\draw[semithick]
(0, 0) -- (endofline)
[shift=(endofline)]
-- plot[
smooth,
tension=1.8,
variable=\t,
samples=140,
domain=0:180,
]
({\t*25mm/180 + rand*sin(\t)*sin(\t)*3.5mm}, {sin(\t)*sin(\t)*rand*4mm})
-- (end)
;
\end{tikzpicture}
\end{document}
带有“模糊”点标签的线
可以使用通常的 TikZ 方法( , ...)将标签“通用点”放在“模糊”点下方\node
。以下示例测量线的边界框(无标签)以获取放置标签的右下角坐标。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\fill[radius=1mm]
\foreach \prim [count=\i] in {2, 3, 5, 7, 11, 13, {}, {}, {}, {}} {
({\i*1.8 - \i*(\i-1)*.5*0.175}, 0) circle[]
node[below=1mm] (p\prim) {\prim}
}
++(1mm, 0) coordinate (endofline)
++(25mm, 0) coordinate (end)
;
\begin{pgfinterruptboundingbox}
\pgfmathsetseed{2000}
\draw[semithick]
(0, 0) -- (endofline)
[shift=(endofline)]
-- plot[
smooth,
tension=1.8,
variable=\t,
samples=140,
domain=0:180,
]
({\t*25mm/180 + rand*sin(\t)*sin(\t)*3.5mm}, {sin(\t)*sin(\t)*rand*4mm})
-- (end)
(current bounding box.south west) coordinate (LowerLeft)
(current bounding box.north east) coordinate (UpperRight)
;
\end{pgfinterruptboundingbox}
\path
(LowerLeft) (UpperRight) % update bounding box
(LowerLeft -| UpperRight) node[below left, yshift=1mm] {generic point}
;
\end{tikzpicture}
\end{document}
答案3
这没用Tikz
,但是这里有一个解决方案asymptote
。
unitsize(1inch);
int numPoints = 150;
path p;
for (int i = 0; i < numPoints; ++i)
{
p = p..dir(i*360.0/numPoints)+scale(0.25)*(unitrand()-0.5, unitrand()-0.5);
}
p = p..cycle;
dot((0,0), 4+black);
draw(unitcircle, 1+green);
draw(p);
dot(p, 2+red);