我需要绘制大量不同尺寸的 3D 圆柱体。有人可能已经定义过类似的命令吗\3Dcylinder{x}{y}{z}
?
我发现TikZ 中的 3D 物体 并尝试了第三个答案。但我不明白参数是如何工作的。
我还发现在 TikZ 中绘制简单的 3D 圆柱体。但我不知道如何使用它轻松地绘制一堆不同的圆柱体。
答案1
当我必须绘制爆炸视图时,我也遇到过这个问题。安德鲁·史黛西您提到的第二个链接中的答案是正确的,因此我调整了以下宏:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\pgfmathsetmacro{\xdeg}{30}
\pgfmathsetmacro{\xx}{cos(\xdeg)}
\pgfmathsetmacro{\xy}{sin(\xdeg)}
\pgfmathsetmacro{\ydeg}{120}
\pgfmathsetmacro{\yx}{cos(\ydeg)}
\pgfmathsetmacro{\yy}{sin(\ydeg)}
\pgfmathsetmacro{\zdeg}{80}
\pgfmathsetmacro{\zx}{cos(\zdeg)}
\pgfmathsetmacro{\zy}{sin(\zdeg)}
\newcommand{\tdcyl}[5]{% origin x, origin y, origin z, radius, height
\path (1,0,0);
\pgfgetlastxy{\cylxx}{\cylxy}
\path (0,1,0);
\pgfgetlastxy{\cylyx}{\cylyy}
\path (0,0,1);
\pgfgetlastxy{\cylzx}{\cylzy}
\pgfmathsetmacro{\cylt}{(\cylzy * \cylyx - \cylzx * \cylyy)/ (\cylzy * \cylxx - \cylzx * \cylxy)}
\pgfmathsetmacro{\ang}{atan(\cylt)}
\pgfmathsetmacro{\ct}{1/sqrt(1 + (\cylt)^2)}
\pgfmathsetmacro{\st}{\cylt * \ct}
\filldraw[fill=white] (#4*\ct+#1,#4*\st+#2,#3) -- ++(0,0,#5) arc[start angle=\ang,delta angle=-180,radius=#4] -- ++(0,0,-#5) arc[start angle=\ang+180,delta angle=180,radius=#4];
\filldraw[fill=white] (#1,#2,#3+#5) circle[radius=#4];
}
\begin{document}
\begin{tikzpicture}[x={(\xx*1cm,\xy*1cm)},y={(\yx*1cm,\yy*1cm)},z={(\zx*1cm,\zy*1cm)}]
\tdcyl{0}{0}{0}{1}{3}
\draw (-3,0,0) -- (3,0,0) node[circle,fill=white] {x};
\draw (0,-3,0) -- (0,3,0) node[circle,fill=white] {y};
\draw (0,0,-3) -- (0,0,3) node[circle,fill=white] {z};
\end{tikzpicture}
\end{document}
但请注意,这仅适用于沿 z 方向增长的圆柱体和“右手”坐标系,例如,顺时针方向的矢量为 yzx、zxy 或 xyz,但不是 yxz、zxy 或 xzy。
编辑1:我记得我还必须绘制 y 向增长圆柱体,所以我查了一下。由于懒得概括宏,所以我只是在本地重新定义了坐标轴,从而改变了输入含义的顺序(从xyz
rh 表示 z 向增长变为xzy
rh 表示 y 向增长,yzx
rh 表示 x 向增长),而且我还必须修改原始宏。也许可以统一这些(可能涉及类似ifthenelse
来自xifthen
包的内容)。现在,这是丑陋的 hackish 版本,我建议不要使用它或很好地记录你所做的:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\pgfmathsetmacro{\xdeg}{30}
\pgfmathsetmacro{\xx}{cos(\xdeg)}
\pgfmathsetmacro{\xy}{sin(\xdeg)}
\pgfmathsetmacro{\ydeg}{150}
\pgfmathsetmacro{\yx}{cos(\ydeg)}
\pgfmathsetmacro{\yy}{sin(\ydeg)}
\pgfmathsetmacro{\zdeg}{90}
\pgfmathsetmacro{\zx}{cos(\zdeg)}
\pgfmathsetmacro{\zy}{sin(\zdeg)}
\newcommand{\tdcyl}[5]{% origin x, origin y, origin z, radius, height
\path (1,0,0);
\pgfgetlastxy{\cylxx}{\cylxy}
\path (0,1,0);
\pgfgetlastxy{\cylyx}{\cylyy}
\path (0,0,1);
\pgfgetlastxy{\cylzx}{\cylzy}
\pgfmathsetmacro{\cylt}{(\cylzy * \cylyx - \cylzx * \cylyy)/ (\cylzy * \cylxx - \cylzx * \cylxy)}
\pgfmathsetmacro{\ang}{atan(\cylt)}
\pgfmathsetmacro{\ct}{1/sqrt(1 + (\cylt)^2)}
\pgfmathsetmacro{\st}{\cylt * \ct}
\filldraw[fill=white] (#4*\ct+#1,#4*\st+#2,#3) -- ++(0,0,#5) arc[start angle=\ang,delta angle=-180,radius=#4] -- ++(0,0,-#5) arc[start angle=\ang+180,delta angle=180,radius=#4];
\filldraw[fill=white] (#1,#2,#3+#5) circle[radius=#4];
}
\newcommand{\tdcylxy}[5]{% origin x, origin y, origin z, radius, height
\path (1,0,0);
\pgfgetlastxy{\cylxx}{\cylxy}
\path (0,1,0);
\pgfgetlastxy{\cylyx}{\cylyy}
\path (0,0,1);
\pgfgetlastxy{\cylzx}{\cylzy}
\pgfmathsetmacro{\cylt}{(\cylzy * \cylyx - \cylzx * \cylyy)/ (\cylzy * \cylxx - \cylzx * \cylxy)}
\pgfmathsetmacro{\ang}{atan(\cylt)}
\pgfmathsetmacro{\ct}{1/sqrt(1 + (\cylt)^2)}
\pgfmathsetmacro{\st}{\cylt * \ct}
\filldraw[fill=white] (#4*\ct+#1,#4*\st+#2,#3) -- ++(0,0,#5) arc[start angle=\ang,delta angle=180,radius=#4] -- ++(0,0,-#5) arc[start angle=\ang+180,delta angle=180,radius=#4];
\filldraw[fill=white] (#1,#2,#3) circle[radius=#4];
}
\begin{document}
\begin{tikzpicture}[x={(\xx*1cm,\xy*1cm)},y={(\yx*1cm,\yy*1cm)},z={(\zx*1cm,\zy*1cm)}]
\tdcyl{0}{0}{3}{1}{3} % x y z r h
\begin{scope}[x={(\xx*1cm,\xy*1cm)},z={(\yx*1cm,\yy*1cm)},y={(\zx*1cm,\zy*1cm)}]
% This is a y-growing cylinder
\tdcylxy{0}{0}{3}{1.5}{3} % x z y r h
\end{scope}
\begin{scope}[z={(\xx*1cm,\xy*1cm)},x={(\yx*1cm,\yy*1cm)},y={(\zx*1cm,\zy*1cm)}]
% This is a x-growing cylinder
\tdcylxy{0}{0}{3}{0.5}{3} % y z x r h
\end{scope}
\draw (-3,0,0) -- (3,0,0) node[circle,fill=white] {x};
\draw (0,-3,0) -- (0,3,0) node[circle,fill=white] {y};
\draw (0,0,-3) -- (0,0,3) node[circle,fill=white] {z};
\end{tikzpicture}
\end{document}
答案2
您也可以使用圆柱体形状。以下是两个示例,直接取自 tikz 手册。
\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}
\node[cylinder, draw, shape aspect=.5] {ABC};
\end{tikzpicture}
\begin{tikzpicture}
\node [cylinder, gray!50, rotate=30, draw,
minimum height=2cm, minimum width=1cm] (c) {Cylinder};
\draw[red, <->] (c.top) -- (c.bottom)
node [at end, below, black] {height};
\draw[red, <->] (c.north) -- (c.south)
node [at start, above, black] {width};
\end{tikzpicture}
\end{document}
结果是: