我正在尝试使用 TIKZ 绘制下图。我的问题是,是否可以在 TIKZ 中弯曲 3D 对象。我想在下面给出的代码中弯曲圆柱体对象并生成下图。
到目前为止,我已经完成了使用 tikz 绘制一个圆柱体 -
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\radius}{0.25}
\pgfmathsetmacro{\length}{5}
\fill[fill=white] (\radius,0) -- (\radius,\length) arc (360:180:\radius cm and 0.5*\radius cm) -- (-\radius,0) arc (180:360:\radius cm and \radius cm);
\fill[top color=gray!90!,bottom color=gray!2,middle color=gray!30,shading=axis,opacity=0.25] (0,\length) circle (\radius cm and 0.5*\radius cm);
\draw[ultra thick,gray!90] (-\radius,\length) -- (-\radius,0) arc (180:360:\radius cm and \radius cm) -- (\radius,\length) ++ (-\radius,0) circle (\radius cm and 0.5*\radius cm);
\end{tikzpicture}
\end{document}
谢谢 !
答案1
这是一个您可以用作起点的想法。
方法是在圆柱体的尖端处生成随机角度和随机“强度”(我无法想出更好的术语),并使用这些量来放置贝塞尔曲线的控制点,这些控制点位于相对于这些尖端的相对极坐标中。圆柱体的两个边缘使用相同的角度和强度,以确保它们保持平行。
为了在不同位置、角度和比例绘制这类圆柱体,所有代码都存储在pic
(需要 PGF 3.0.0)中。
还有改进的空间,特别是我认为应该将圆柱体的长度和半径等参数作为图片的键,以及变形的角度和强度的“随机性”给出。
图片样式的代码:
\pgfmathsetmacro{\radius}{0.25}
\pgfmathsetmacro{\length}{5}
\tikzset {
bent cylinder/.pic={
\pgfmathsetmacro{\anglebottom}{90-20+40*rnd}
\pgfmathsetmacro{\strengthbottom}{\length*(0.3+rnd/3)}
\pgfmathsetmacro{\angletop}{90-20+40*rnd}
\pgfmathsetmacro{\strengthtop}{\length*(0.3+rnd/3)}
\fill[fill=white]
(\radius,0)
.. controls +(\anglebottom:\strengthbottom)
and +(-\angletop:\strengthtop)
.. (\radius,\length)
arc (360:180:\radius cm and 0.5*\radius cm)
.. controls +(-\angletop:\strengthtop)
and +(\anglebottom:\strengthbottom)
.. (-\radius,0)
arc (180:360:\radius cm and \radius cm);
\draw[gray!90, ultra thick, line join=round]
(\radius,0)
.. controls +(\anglebottom:\strengthbottom)
and +(-\angletop:\strengthtop)
.. (\radius,\length)
arc (360:180:\radius cm and 0.5*\radius cm)
.. controls +(-\angletop:\strengthtop)
and +(\anglebottom:\strengthbottom)
.. (-\radius,0)
arc (180:360:\radius cm and \radius cm);
\filldraw[ultra thick, draw=gray!90,
top color=gray!90,
bottom color=gray!2,
middle color=gray!30,
shading=axis]
(0,\length) circle (\radius cm and 0.5*\radius cm);
}
}
使用示例
垂直圆柱体的“序列”,用于查看每个圆柱体如何弯曲成不同的形状和程度:
\begin{tikzpicture}
\fill[left color=black!40, right color=white] (0,-2) rectangle (16,7);
\foreach \x in {1,...,10}
\draw (2*\x,0) pic {bent cylinder};
\end{tikzpicture}
类似于您发布的图形的“意大利面条乱象”。每个圆柱体放置在随机位置并旋转随机角度:
\begin{tikzpicture}
\fill[left color=black!40, right color=white] (0,-2) rectangle (15,7);
\foreach \x in {1,...,60}
\draw (10*rnd,4*rnd) pic[rotate=360*rnd] {bent cylinder};
\end{tikzpicture}
更新
通过泊松采样可以实现“混乱”中管道的更好放置。使用我在另一个答案,圆柱体的中心可以放置在随机的格子中,以确保它们之间的最小距离。
在下面的代码中,我改变了图片的定义bent cylinder
,将点 (0,0) 放在圆柱体的中心(而不是其底部),并删除了一些不必要的代码。我曾经将\poissonpointslist{15}{7}{1}{20}
随机坐标放置在 15x7 的矩形中,并确保点之间的最小距离为 1(参数 20 在此处无关紧要),并\foreach
使用这些坐标将圆柱体放置在该点,并围绕它随机旋转。
为了更好地理解结果,我在包含圆柱体中心的 15x7 矩形中放置了一个橙色背景,并在每个中心放置了一个黄色圆圈。
\documentclass{standalone}
\usepackage{tikz}
\usepackage{poisson}
\begin{document}
\pgfmathsetmacro{\radius}{0.25}
\pgfmathsetmacro{\length}{5}
\tikzset {
bent cylinder/.pic={
\pgfmathsetmacro{\anglebottom}{90-20+40*rnd}
\pgfmathsetmacro{\strengthbottom}{\length*(0.3+rnd/3)}
\pgfmathsetmacro{\angletop}{90-20+40*rnd}
\pgfmathsetmacro{\strengthtop}{\length*(0.3+rnd/3)}
\filldraw[fill=white, draw=gray!90, ultra thick, line join=round]
(\radius,-\length/2)
.. controls +(\anglebottom:\strengthbottom)
and +(-\angletop:\strengthtop)
.. (\radius,\length/2)
arc (360:180:\radius cm and 0.5*\radius cm)
.. controls +(-\angletop:\strengthtop)
and +(\anglebottom:\strengthbottom)
.. (-\radius,-\length/2)
arc (180:360:\radius cm and \radius cm);
\filldraw[ultra thick, draw=gray!90,
top color=gray!90,
bottom color=gray!2,
middle color=gray!30,
shading=axis]
(0,\length/2) circle (\radius cm and 0.5*\radius cm);
}
}
\edef\positions{\poissonpointslist{15}{7}{1}{20}}
\begin{tikzpicture}
\fill[black!30] (-2.5,-2.5) rectangle (17.5,9.5);
\fill[orange!20] (0,0) rectangle (15,7);
\foreach \x/\y in \positions
\draw (\x,\y) pic[rotate=360*rnd] {bent cylinder};
\foreach \x/\y in \positions
\fill[yellow!50!orange, opacity=0.7] (\x,\y) circle(0.3);
\end{tikzpicture}
\end{document}