我正在尝试使用 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}