如何使用 Tikz-3dplot 创建圆柱体?

如何使用 Tikz-3dplot 创建圆柱体?

我正在尝试使用 tikz-3dplot 重新创建下图。

我毫无问题地制作了立方体,但我无法在立方体内添加圆柱体。我需要在立方体内创建实心圆柱体,虚线只是为了显示圆柱体的起点和终点。有人知道吗?

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{69}{200}

\begin{tikzpicture}[scale=4,tdplot_main_coords]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\coordinate (O) at (0,0,0);
\coordinate (A0) at (0,5.5,0);
\coordinate (A1) at (1.3,5.5,0);
\coordinate (A2) at (1.3,7,0);
\coordinate (A3) at (2.7,7,0);
\coordinate (A4) at (2.7,5.5,0);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\coordinate (OB) at (0,0,1.5);
\coordinate (B0) at (0,5.5,1.5);
\coordinate (B1) at (1.3,5.5,1.5);
\coordinate (B2) at (1.3,7,1.5);
\coordinate (B3) at (2.7,7,1.5);
\coordinate (B4) at (2.7,5.5,1.5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\draw[fill=green!70,opacity=0.6] (B4) -- (B3) --(B2)--(B1)-- cycle;

\draw[fill=green!70,opacity=0.6] (A2) -- (B2) --(B3)--(A3)--cycle;

\draw[fill=green!70,opacity=0.6] (A2) -- (B2) --(B1)--(A1)--cycle;  

\draw[fill=green!70,opacity=0.6] (A4) -- (B4) --(B3)--(A3)--cycle;    

\draw[fill=green!70,opacity=0.6] (A4) -- (A3) --(A2)--(A1)-- cycle;

\end{tikzpicture}
\end{document}

答案1

要绘制圆柱体,我们需要计算圆柱体在 y 方向的临界角,x 方向也类似。球体上的圆周已经完成了这一计算(参见这里和非常好的包裹)和圆环(见这里)。此答案为您提供了圆柱体通用视角的类似表达式。(x 方向的圆柱体是类似的,z 方向很简单,例如可以找到这里)下面的动画是为了展示它的工作原理:

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\tikzset{declare function={
vcrity(\ph,\th)=atan2(sin(\th)*sin(\ph),min(cos(\ph),-1/sqrt(2))*cos(\th));% critical t value y cylinder
vcritz(\ph,\th)=\ph;% critical t value y cylinder
},pics/ycylinder/.style={code={
\tikzset{3d/cylinder/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/3d/cylinder/##1}}
\pgfmathsetmacro{\vmin}{vcrity(\tdplotmainphi,\tdplotmaintheta)}
\pgfmathsetmacro{\vmax}{\vmin-180}
\path[3d/cylinder/mantle]
  let \p1=($(0,1,0)-(0,0,0)$),\n1={atan2(\y1,\x1)} in
  [shading angle=\n1]
  plot[variable=\t,domain=\vmin:\vmax,smooth]
    ({\pv{r}*cos(\t)},0,{\pv{r}*sin(\t)})
    -- 
    plot[variable=\t,domain=\vmax:\vmin,smooth]
    ({\pv{r}*cos(\t)},\pv{h},{\pv{r}*sin(\t)})
    --cycle;
\pgfmathtruncatemacro{\itest}{sign(cos(\tdplotmainphi))}
\ifnum\itest=-1
    \path[3d/cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},\pv{h},{\pv{r}*sin(\t)}) ;
\fi
\ifnum\itest=1
    \path[3d/cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},0,{\pv{r}*sin(\t)}) ;
\fi
}},3d/.cd,cylinder/.cd,r/.initial=1,h/.initial=1,
mantle/.style={draw},top/.style={draw}}
\begin{document}
\foreach \X in {0,10,...,350}
{\tdplotsetmaincoords{69}{\X}
\begin{tikzpicture}[tdplot_main_coords]
 \path[tdplot_screen_coords,use as bounding box] (-4,-2.5) rectangle (4,2.5);
 \path pic{ycylinder={r=1,h=3,top/.append style={fill=gray}}};
\end{tikzpicture}}
\end{document}

在此处输入图片描述

这可用于绘制图片中的圆柱体。请注意,我重新排列了图片的平面。您可能想考虑简化这些内容,但由于我不知道您打算用它做什么,所以我暂时保留了它。

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\tikzset{declare function={
vcrity(\ph,\th)=atan2(sin(\th)*sin(\ph),min(cos(\ph),-1/sqrt(2))*cos(\th));% critical t value y cylinder
vcritz(\ph,\th)=\ph;% critical t value y cylinder
},pics/ycylinder/.style={code={
\tikzset{3d/cylinder/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/3d/cylinder/##1}}
\pgfmathsetmacro{\vmin}{vcrity(\tdplotmainphi,\tdplotmaintheta)}
\pgfmathsetmacro{\vmax}{\vmin-180}
\path[3d/cylinder/mantle]
  let \p1=($(0,1,0)-(0,0,0)$),\n1={atan2(\y1,\x1)} in
  [shading angle=\n1]
  plot[variable=\t,domain=\vmin:\vmax,smooth]
    ({\pv{r}*cos(\t)},0,{\pv{r}*sin(\t)})
    -- 
    plot[variable=\t,domain=\vmax:\vmin,smooth]
    ({\pv{r}*cos(\t)},\pv{h},{\pv{r}*sin(\t)})
    --cycle;
\pgfmathtruncatemacro{\itest}{sign(cos(\tdplotmainphi))}
\ifnum\itest=-1
    \path[3d/cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},\pv{h},{\pv{r}*sin(\t)}) ;
\fi
\ifnum\itest=1
    \path[3d/cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},0,{\pv{r}*sin(\t)}) ;
\fi
}},3d/.cd,cylinder/.cd,r/.initial=1,h/.initial=1,
mantle/.style={draw},top/.style={draw}}
\begin{document}
\tdplotsetmaincoords{69}{200}

\begin{tikzpicture}[scale=3,tdplot_main_coords]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\coordinate (O) at (0,0,0);
\coordinate (A0) at (0,5.5,0);
\coordinate (A1) at (1.3,5.5,0);
\coordinate (A2) at (1.3,7,0);
\coordinate (A3) at (2.7,7,0);
\coordinate (A4) at (2.7,5.5,0);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\coordinate (OB) at (0,0,1.5);
\coordinate (B0) at (0,5.5,1.5);
\coordinate (B1) at (1.3,5.5,1.5);
\coordinate (B2) at (1.3,7,1.5);
\coordinate (B3) at (2.7,7,1.5);
\coordinate (B4) at (2.7,5.5,1.5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% bottom
\draw[fill=green!70,opacity=0.6] (A4) -- (A3) --(A2)--(A1)-- cycle;

% left
\draw[fill=green!70,opacity=0.6] (A4) -- (B4) --(B3)--(A3)--cycle;    

\path[transform shape] 
 foreach \Z in {0.3,0.6,0.9,1.2} 
 {(2,5.5,\Z) pic{ycylinder={r=0.12,h=1.5,top/.append style={fill=gray}}}};

% right
\draw[fill=green!70,opacity=0.6] (A2) -- (B2) --(B1)--(A1)--cycle;  

% front
\draw[fill=green!70,opacity=0.6] (A2) -- (B2) --(B3)--(A3)--cycle;

% top
\draw[fill=green!70,opacity=0.6] (B4) -- (B3) --(B2)--(B1)-- cycle;

\end{tikzpicture}
\end{document}

在此处输入图片描述

附录:如果不需要轮廓,则可以不进行所有这些计算来绘制它。

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\foreach \X in {0,10,...,350}
{\tdplotsetmaincoords{69}{\X}
\begin{tikzpicture}[tdplot_main_coords]
 \path[tdplot_screen_coords,use as bounding box] (-4,-2.5) rectangle (4,2.5);
 \draw[blue,line width=2cm] (0,0,0) -- (0,3,0);
 \pgfmathtruncatemacro{\itest}{sign(cos(\tdplotmainphi))}
 \ifnum\itest=1
    \path[fill=blue] plot[variable=\t,domain=0:360,smooth cycle]
    ({cos(\t)},3,{sin(\t)}) ;
    \path[fill=gray] plot[variable=\t,domain=0:360,smooth cycle]
    ({cos(\t)},0,{sin(\t)}) ;
 \fi
 \ifnum\itest=-1
    \path[fill=blue] plot[variable=\t,domain=0:360,smooth cycle]
    ({cos(\t)},0,{sin(\t)}) ;
    \path[fill=gray] plot[variable=\t,domain=0:360,smooth cycle]
    ({cos(\t)},3,{sin(\t)}) ;
 \fi
\end{tikzpicture}}
\end{document}

在此处输入图片描述

相关内容