答案1
欢迎!问题如何绘制圆环有很多答案,我从中选择这个首先。这是因为它带有圆环在屏幕坐标上的投影参数化,不需要外部软件。不过,如果你想批量制作 3D 图纸,你最终可能会更好地使用渐近线。有了这些参数化,绘制就相当容易了
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\tikzset{declare function={%
torusx(\u,\v,\R,\r)=cos(\u)*(\R + \r*cos(\v));
torusy(\u,\v,\R,\r)=(\R + \r*cos(\v))*sin(\u);
torusz(\u,\v,\R,\r)=\r*sin(\v);
vcrit1(\u,\th)=atan(tan(\th)*sin(\u));% first critical v value
vcrit2(\u,\th)=180+atan(tan(\th)*sin(\u));% second critical v value
thetacritA(\R,\r)=atan(sqrt(\R/\r-1));
thetacritB(\R,\r)=acos(\r/\R);
ucritA(\R,\r,\th)=180+(90/pi)*sqrt(abs(-(\R^2*pow(cot(\th),2))+4*pow(\r,2)/pow(sin(2*\th),2)))/\R;
ucritB(\R,\r,\th)=540-ucritA(\R,\r,\th);
umaxA(\R,\r,\th)=asin(sqrt(abs(-pow(cot(\th),2)+4*pow(\r,2)/(pow((sin(2*\th)*\R),2)))));
umaxB(\R,\r,\th)=180-umaxA(\R,\r,\th);}}
\tikzset{3d torus/.style n
args={2}{/utils/exec=\pgfmathsetmacro{\DDA}{int(sign(sin(thetacritA(#1,#2))-sin(\tdplotmaintheta)))}
\pgfmathsetmacro{\DDB}{int(sign(sin(thetacritB(#1,#2))-sin(\tdplotmaintheta)))},
insert path={
plot[variable=\x,domain=1:359,smooth cycle,samples=71]
({torusx(\x,vcrit1(\x,\tdplotmaintheta),#1,#2)},
{torusy(\x,vcrit1(\x,\tdplotmaintheta),#1,#2)},
{torusz(\x,vcrit1(\x,\tdplotmaintheta),#1,#2)})
\ifnum\DDA=1
plot[variable=\x,domain=0:360,smooth cycle,samples=71]
({torusx(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusy(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusz(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)})
\else
\ifnum\DDB=1
plot[variable=\x,domain={umaxA(#1,#2,\tdplotmaintheta)}:{umaxB(#1,#2,\tdplotmaintheta)},smooth,samples=71]
({torusx(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusy(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusz(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)}) --
plot[variable=\x,domain={180+umaxA(#1,#2,\tdplotmaintheta)}:{180+umaxB(#1,#2,\tdplotmaintheta)},smooth,samples=71]
({torusx(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusy(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusz(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)}) -- cycle
\fi
\fi
}},3d torus stretch/.style n args={2}{/utils/exec=\pgfmathsetmacro{\DDA}{int(sign(thetacritA(#1,#2)-\tdplotmaintheta))},
insert path={\ifnum\DDA=-1
plot[variable=\x,domain={ucritA(#1,#2,\tdplotmaintheta)}:{ucritB(#1,#2,\tdplotmaintheta)},smooth,samples=71]
({torusx(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusy(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)},
{torusz(\x,vcrit2(\x,\tdplotmaintheta),#1,#2)})
\fi
}}}
\begin{document}
\tdplotsetmaincoords{65}{0}
\begin{tikzpicture}[tdplot_main_coords,declare function={
rfib(\x)=3*\x/sqrt(5+\x*\x);}]
\pgfmathsetmacro{\RadiusA}{3}
\pgfmathsetmacro{\RadiusB}{1}
\clip[tdplot_screen_coords]
(-\RadiusA-1.5*\RadiusB,{-(\RadiusA+1.5*\RadiusB)*sin(\tdplotmaintheta)})
rectangle
(\RadiusA+1.5*\RadiusB,{(\RadiusA+1.5*\RadiusB)*sin(\tdplotmaintheta)});
\draw (0,0,{-(\RadiusA+1.3*\RadiusB)*sin(\tdplotmaintheta)}) -- (0,0,0);
\begin{scope}[canvas is xz plane at y=0]
\foreach \X in {1.5,2.5,...,8.5}
{\draw ({-\RadiusA+rfib(\X)},0) arc(360:180:\X)
({\RadiusA-rfib(\X)},0) arc(180:360:\X);}
\end{scope}
\draw[thick,samples=71,fill=gray,fill opacity=0.8,even odd
rule,3d torus={\RadiusA}{\RadiusB}] ;
\draw[thick,samples=71,3d torus stretch={\RadiusA}{\RadiusB}];
\begin{scope}[canvas is xz plane at y=0]
\foreach \X in {1.5,2.5,...,8.5}
{\draw ({-\RadiusA+rfib(\X)},0) arc(0:180:\X)
({\RadiusA-rfib(\X)},0) arc(180:0:\X);}
\end{scope}
\draw[-stealth] (0,0,0)-- (0,0,{(\RadiusA+1.3*\RadiusB)*sin(\tdplotmaintheta)}) ;
\end{tikzpicture}
\end{document}
如果您告诉我圆环上的曲线的用途是什么,我也可能会添加它。
我正在寻找真实的霍普夫纤维,并发现
https://i.stack.imgur.com/yFMf0.jpg
;-)
答案2
我完全明白原作者想用 LaTeX(tikz...)来寻找答案,但有时你必须意识到有更好的工具可以完成工作。我用不到五分钟就绘制了下面的图表数学,具有透明度等......可以轻松将图形作为 .eps 文件包含在 LaTeX 文档中。
如果您有其他平面曲线的数学形式,那么也可以轻松添加它们。
如果有人感兴趣:
myTorus =
ParametricPlot3D[
{Cos[v] (2 + Cos[u]), Sin[v] (2 + Cos[u]), Sin[u]},
{v, 0, 2 Pi}, {u, 0, 2 Pi},
PlotStyle -> Opacity[0.5],
Mesh -> None,
Boxed -> False,
Axes -> None];
myCurve =
ParametricPlot3D[
{Cos[2 t] (2 + Cos[3 t]), Sin[2 t] (2 + Cos[3 t]), Sin[3 t]},
{t, 0, 2 \[Pi]},
PlotStyle -> {Red, Thickness[0.02]}];
Show[myTorus, myCurve]