我的代码
\begin{tikzpicture}
\def\a{1} % bán trục lớn = bán kính trụ
\def\b{0.3} % bán trục nhỏ
\def\h{3} % chiều cao trụ
\shadedraw[left color=gray,right color=white, draw=none]
(-\a,1) -- (-\a,0) arc [x radius=\a, y radius=\b, start angle=180, end angle=360] (\a,0)--(\a,1)arc [x radius=\a, y radius=\b, start angle=0, end angle=180];
\draw (\a,0)--(\a,\h) (-\a,0)--(-\a,\h);
\draw[dashed] (\a,0) arc [x radius=\a, y radius=\b, start angle=0, end angle=180];
\draw (-\a,0) arc [x radius=\a, y radius=\b, start angle=180, end angle=360];
\draw[dashed] (\a,1) arc [x radius=\a, y radius=\b, start angle=0, end angle=180];
\draw (-\a,1) arc [x radius=\a, y radius=\b, start angle=180, end angle=360];
\draw (0,\h) ellipse (\a cm and \b cm);
\end{tikzpicture}
\begin{tikzpicture}[rotate=-70]
\def\a{1} % bán trục lớn = bán kính trụ
\def\b{0.3} % bán trục nhỏ
\def\h{3} % chiều cao trụ
\draw (\a,0)--(\a,\h) (-\a,0)--(-\a,\h);
\tkzDefPoints{-\a/0/A,\a/0/B,-\a/\h/a}
\tkzDefMidPoint(A,B)\tkzGetPoint{O}
\coordinate(M) at ([shift={(O)}]-70:\a cm and \b cm);
\draw[draw=none,name path=elip] (O) ellipse (\a cm and \b cm);
\tkzDefPointBy[rotation=center O angle 180](M)\tkzGetPoint{N}
\coordinate(C) at ([shift={(O)}]0:\a cm and \b cm);
\tkzDefPointBy[translation=from A to a](C)\tkzGetPoint{C'}
\fill[color=gray!50, draw=none]
(O) -- (M) .. controls (0.8,1.6) and (1,2.8) .. (C');
\fill[color=gray!50, draw=none]
(O) -- (N) .. controls (0.6,2.6) and (0.8,3.3) .. (C');
\tkzFindAngle(B,O,M)\tkzGetAngle{angBOM}
\fill[color=gray!40, draw=none]
(M) .. controls (0.8,1.5) and (1,2.6) .. (C')--(B);
\fill[color=gray!40, draw=none]
(M) arc [x radius=\a, y radius=\b, start angle=0, end angle=\angBOM]--(B);
\draw[dashed](M)--(N) (O)--(C');
\draw[name path=elip1] (M) .. controls (0.8,1.6) and (1,2.8) .. (C');
\draw[dashed,name path=elip2] (N) .. controls (0.6,2.6) and (0.8,3.3) .. (C');
\draw[dashed] (\a,0) arc [x radius=\a, y radius=\b, start angle=0, end angle=180];
\draw (-\a,0) arc [x radius=\a, y radius=\b, start angle=180, end angle=360];
\draw (0,\h) ellipse (\a cm and \b cm);
\end{tikzpicture}
请帮助我!非常感谢!
答案1
这绘制了部分填充的旋转圆柱体。水面的顶部表面是椭圆形,可能会被圆柱体的顶部和/或底部截断。如果查看合适的投影,相关角度的计算相当简单。我要感谢 minhthien_2016 提醒我这个好问题。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\tikzset{pics/filled cylinder/.style={code={\tikzset{filled cylinder/.cd,#1}
\newcommand*{\pv}[1]{\pgfkeysvalueof{/tikz/filled cylinder/##1}}
\pgfmathsetmacro\angVis{atan(sin(\pv{rot})*cos(\tdplotmaintheta)/sin(\tdplotmaintheta))}% see tex.stackexchange.com/a/49589/
\draw[dashed] plot[variable=\t,domain=\angVis:\angVis-180,smooth] ({\pv{radius}*cos(\pv{rot})*cos(\t)},
{\pv{radius}*sin(\t)},
{\pv{radius}*sin(\pv{rot})*cos(\t)});
\pgfmathtruncatemacro{\itestU}{sign(\pv{radius}-(\pv{height}-\pv{level})*cos(\pv{rot})/cos(90-\pv{rot})}
\pgfmathsetmacro{\alphaU}{acos(min(1,abs(((\pv{height}-\pv{level})*cos(\pv{rot})/cos(90-\pv{rot}))/\pv{radius})))}
\pgfmathsetmacro{\angU}{ifthenelse(\alphaU>0,\alphaU,\angVis)}
\pgfmathsetmacro{\alphaL}{acos(min(1,abs(((\pv{level})*cos(\pv{rot})/cos(90-\pv{rot}))/\pv{radius})))}
\pgfmathsetmacro{\angL}{ifthenelse(\alphaL>0,180-\alphaL,\angVis+180)}
\ifdim\alphaU pt>0pt % distinguish between cut at top end and not
\path[fill=blue!50,fill opacity=0.5]
plot[variable=\t,domain=\angVis:-1*\angU,smooth]
({\pv{radius}*cos(\pv{rot})*cos(\t) -sin(\pv{rot})*\pv{height}},
{\pv{radius}*sin(\t)},
{\pv{radius}*sin(\pv{rot})*cos(\t) +cos(\pv{rot})*\pv{height}}) --
plot[variable=\t,domain=\angU:\angL,smooth]
({-\pv{level}*sin(\pv{rot})+\pv{radius}*cos(\t)/cos(\pv{rot})},{\pv{radius}*sin(\t)},{zprime(0,\pv{level},-1*\pv{rot})})
-- plot[variable=\t,domain=\angL:\angVis,smooth] ({\pv{radius}*cos(\pv{rot})*cos(\t)},
{\pv{radius}*sin(\t)},{\pv{radius}*sin(\pv{rot})*cos(\t)})
-- cycle;
\else
\path[fill=blue!50,fill opacity=0.5]
plot[variable=\t,domain=\angU:\angL,smooth]
({-\pv{level}*sin(\pv{rot})+\pv{radius}*cos(\t)/cos(\pv{rot})},{\pv{radius}*sin(\t)},{zprime(0,\pv{level},-1*\pv{rot})})
-- plot[variable=\t,domain=\angL:\angVis,smooth] ({\pv{radius}*cos(\pv{rot})*cos(\t)},
{\pv{radius}*sin(\t)},{\pv{radius}*sin(\pv{rot})*cos(\t)})
-- cycle;
\fi
\draw[fill=blue,fill opacity=0.5]
plot[variable=\t,domain=\alphaU:180-\alphaL,smooth]
({-\pv{level}*sin(\pv{rot})+\pv{radius}*cos(\t)/cos(\pv{rot})},{\pv{radius}*sin(\t)},{zprime(0,\pv{level},-1*\pv{rot})})
-- plot[variable=\t,domain=180+\alphaL:360-\alphaU,smooth]
({-\pv{level}*sin(\pv{rot})+\pv{radius}*cos(\t)/cos(\pv{rot})},{\pv{radius}*sin(\t)},{zprime(0,\pv{level},-1*\pv{rot})})
-- cycle;
\draw plot[variable=\t,domain=\angVis:\angVis+180,smooth] ({\pv{radius}*cos(\pv{rot})*cos(\t)},
{\pv{radius}*sin(\t)},
{\pv{radius}*sin(\pv{rot})*cos(\t)})
-- plot[variable=\t,domain=\angVis+180:\angVis-360,smooth] ({\pv{radius}*cos(\pv{rot})*cos(\t)
-sin(\pv{rot})*\pv{height}},
{\pv{radius}*sin(\t)},
{\pv{radius}*sin(\pv{rot})*cos(\t)
+cos(\pv{rot})*\pv{height}}) -- cycle;
}}}
\begin{document}
\tdplotsetmaincoords{110}{0}
\foreach \Angle in {-5,-10,...,-80,-75,-70,...,-10}
{\begin{tikzpicture}[tdplot_main_coords,
declare function={zprime(\x,\z,\a)=\z*cos(\a)-\x*sin(\a);
xprime(\x,\z,\a)=\x*cos(\a)+\z*sin(\a);},
filled cylinder/.cd,radius/.initial=1,height/.initial=4,
level/.initial=1.5,rot/.initial=-50]
\path[tdplot_screen_coords,use as bounding box] (-1.5,-1) rectangle (4.5,5);
\path pic{filled cylinder={rot=\Angle}};
\end{tikzpicture}}
\end{document}