Dibujando Toro con una línea semidiscontinua

Dibujando Toro con una línea semidiscontinua

Me gustaria dibujar:

ingrese la descripción de la imagen aquí

Para dibujar el toroide anterior, he utilizado los siguientes códigos:

\documentclass[margin=2mm,tikz]{standalone}
\usepackage{pgfplots}
\begin{document}
%Oberflächenproblem
\begin{tikzpicture}[rotate=180]
%Torus
\draw (0,0) ellipse (1.6 and .9);
%Hole
\begin{scope}[scale=.8]
\path[rounded corners=24pt] (-.9,0)--(0,.6)--(.9,0) (-.9,0)--(0,-.56)--(.9,0);
\draw[rounded corners=28pt] (-1.1,.1)--(0,-.6)--(1.1,.1);
\draw[rounded corners=24pt] (-.9,0)--(0,.6)--(.9,0);
\end{scope}
%Cut 1
\draw[densely dashed] (0,-.9) arc (270:90:.2 and .365);
\draw (0,-.9) arc (-90:90:.2 and .365);
%Cut 2
\draw (0,.9) arc (90:270:.2 and .348);
\draw[densely dashed] (0,.9) arc (90:-90:.2 and .348);
\end{tikzpicture}
\end{document}  

Produce:

ingrese la descripción de la imagen aquí

Esto no es lo mismo que quiero. ¿Cómo puedo hacer el toroide deseado?

Respuesta1

La pregunta decómo dibujar un toroide con Tikzes bastante antiguo y tiene varias respuestas excelentes. Y los resultados más espectaculares (en mi humilde opinión) se han logrado con asíntota, que, a diferencia de TikZ, un motor 3d. Sin embargo, resulta que si uno apunta a gráficos vectoriales 3D, elLos esfuerzos requeridos para dibujar tori 3D son más sustanciales de lo que uno podría esperar ingenuamente..

Esto plantea la cuestión de si es posible o no hacer TikZ discrimina entre puntos visibles y "ocultos" en la superficie del toro. Después de todo, la discriminación análogase ha logrado para esferas. La respuesta es sí.

Parte I de la respuesta: ¿cómo se puede dibujar el contorno de un toroide? Dada una parametrización del toroide, T(\u,\v)=(cos(\u)*(\R + \r*cos(\v),(\R + \r*cos(\v))*sin(\u),\r*sin(\v))se pueden calcular las tangentes y luego la normal en un punto dado. El límite del toroide está determinado por el requisito de que la normal sea ortogonal a la normal de la pantalla. La curva resultante es entonces una función T(\u,vcrit(\u)). Los valores críticos \vtienen una representación muy simple:

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

Determinan dónde comienzan o terminan las piezas visibles y/u ocultas de los ciclos que envuelven el toroide. Sin embargo, tenga en cuenta que vcrit2, dependiendo del ángulo de visión , el contorno puede \tdplotmainthetatener interacciones propias. Es por eso que hay un discriminante en el siguiente código.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{0}
\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
disc(\th,\R,\r)=((pow(\r,2)-pow(\R,2))*pow(cot(\th),2)+% 
pow(\r,2)*(2+pow(tan(\th),2)))/pow(\R,2);% discriminant
umax(\th,\R,\r)=ifthenelse(disc(\th,\R,\r)>0,asin(sqrt(abs(disc(\th,\R,\r)))),0);
}}

\begin{tikzpicture}[tdplot_main_coords]
\pgfmathsetmacro{\R}{4}
\pgfmathsetmacro{\r}{1}
 \draw[thick,fill=gray,even odd rule,fill opacity=0.2] plot[variable=\x,domain=0:360,smooth,samples=71]
 ({torusx(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)}) 
 plot[variable=\x,
 domain={-180+umax(\tdplotmaintheta,\R,\r)}:{-umax(\tdplotmaintheta,\R,\r)},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)})
 plot[variable=\x,
 domain={umax(\tdplotmaintheta,\R,\r)}:{180-umax(\tdplotmaintheta,\R,\r)},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)});
 \draw[thick] plot[variable=\x,
 domain={-180+umax(\tdplotmaintheta,\R,\r)/2}:{-umax(\tdplotmaintheta,\R,\r)/2},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)});
 \foreach \X  in {240,300}  
 {\draw[thick,dashed] 
  plot[smooth,variable=\x,domain={360+vcrit1(\X,\tdplotmaintheta)}:{vcrit2(\X,\tdplotmaintheta)},samples=71]   
 ({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)});
 \draw[thick] 
  plot[smooth,variable=\x,domain={vcrit2(\X,\tdplotmaintheta)}:{vcrit1(\X,\tdplotmaintheta)},samples=71]   
 ({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)})
 node[below]{$C\ifnum\X=300 '\fi$};
 }
 \draw[thick] plot[smooth,variable=\x,domain=60:420,samples=71]   
 ({torusx(-15+15*cos(\x),80+45*sin(\x),\R,\r)},
 {torusy(-15+15*cos(\x),80+45*sin(\x),\R,\r)},
 {torusz(-15+15*cos(\x),80+45*sin(\x),\R,\r)})
 node[above left]{$C''$};
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Como puede ver, los contornos visibles (sólidos) u ocultos (discontinuos) se encuentran entre vcrit1y vcrit2, que son funciones de \uy el ángulo de visión.

Luego se pueden variar las posiciones de los ciclos y el ángulo de visión.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\foreach \X in {0,10,...,350}
{\tdplotsetmaincoords{65+10*sin(\X)}{0}
\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
disc(\th,\R,\r)=((pow(\r,2)-pow(\R,2))*pow(cot(\th),2)+% 
pow(\r,2)*(2+pow(tan(\th),2)))/pow(\R,2);% discriminant
umax(\th,\R,\r)=ifthenelse(disc(\th,\R,\r)>0,asin(sqrt(abs(disc(\th,\R,\r)))),0);
}}

\begin{tikzpicture}[tdplot_main_coords]
 \pgfmathsetmacro{\R}{4}
 \pgfmathsetmacro{\r}{1}
 \path[tdplot_screen_coords,use as bounding box]
  (-1.3*\R,-1.3*\R) rectangle (1.3*\R,1.3*\R);
 \draw[thick,fill=gray,even odd rule,fill opacity=0.2] plot[variable=\x,domain=0:360,smooth,samples=71]
 ({torusx(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)}) 
 plot[variable=\x,
 domain={-180+umax(\tdplotmaintheta,\R,\r)}:{-umax(\tdplotmaintheta,\R,\r)},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)})
 plot[variable=\x,
 domain={umax(\tdplotmaintheta,\R,\r)}:{180-umax(\tdplotmaintheta,\R,\r)},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)});
 \draw[thick] plot[variable=\x,
 domain={-180+umax(\tdplotmaintheta,\R,\r)/2}:{-umax(\tdplotmaintheta,\R,\r)/2},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)});
 \draw[thick,dashed] 
  plot[smooth,variable=\x,domain={360+vcrit1(\X,\tdplotmaintheta)}:{vcrit2(\X,\tdplotmaintheta)},samples=71]   
 ({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)});
 \draw[thick] 
  plot[smooth,variable=\x,domain={vcrit2(\X,\tdplotmaintheta)}:{vcrit1(\X,\tdplotmaintheta)},samples=71]   
 ({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)});
\end{tikzpicture}}
\end{document}

ingrese la descripción de la imagen aquí

Las limitaciones actuales son:

  1. El ángulo theta debe ser mayor de 90 grados y lo suficientemente grande como para que el toroide tenga un agujero. (Esta restricción ha sido levantadaen esta publicación.)
  2. El ángulo phi es 0. Esto no es una verdadera limitación debido a la simetría del toroide. Podría superarse cambiando todos \vlos valores en menos \tdplotmainphi, si es necesario (pero en este punto no veo una motivación para esto).

Con todos estos preparativos podemos abordar la segunda parte de la cuestión, es decir, cómo conseguir un sombreado. Mientras no se insista en unarealistasombreado, se puede utilizar, por ejemploesta respuesta. El objetivo principal de esta discusión no es el sombreado, sino la cuestión de cómo utilizar lo anterior con pgfplots. Para mi sorpresa, es absolutamente sencillo. Esto se debe a que pgfplotsestá muy bien escrito y todos los ángulos necesarios están almacenados en claves pgf.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\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
disc(\th,\R,\r)=((pow(\r,2)-pow(\R,2))*pow(cot(\th),2)+% 
pow(\r,2)*(2+pow(tan(\th),2)))/pow(\R,2);% discriminant
umax(\th,\R,\r)=ifthenelse(disc(\th,\R,\r)>0,asin(sqrt(abs(disc(\th,\R,\r)))),0);
}}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\R}{4}
\pgfmathsetmacro{\r}{1}
    \begin{axis}[colormap/blackwhite,
       view={30}{60},axis lines=none
       ]
       \addplot3[surf,shader=interp,
       samples=61, point meta=z+sin(2*y),
       domain=0:360,y domain=0:360,
       z buffer=sort]
       ({torusx(x,y,\R,\r)}, 
        {torusy(x,y,\R,\r)}, 
        {torusz(x,y,\R,\r)});
        \pgfplotsinvokeforeach{300,360}{%
          \draw[thick,dashed] 
            plot[smooth,variable=\x,domain={360+vcrit1(#1-\pgfkeysvalueof{/pgfplots/view/az},\pgfkeysvalueof{/pgfplots/view/el})}:{vcrit2(#1-\pgfkeysvalueof{/pgfplots/view/az},\pgfkeysvalueof{/pgfplots/view/el})},samples=71]   
            ({torusx(#1-\pgfkeysvalueof{/pgfplots/view/az},\x,\R,\r)},{torusy(#1-\pgfkeysvalueof{/pgfplots/view/az},\x,\R,\r)},{torusz(#1-\pgfkeysvalueof{/pgfplots/view/az},\x,\R,\r)});
          \draw[thick] 
           plot[smooth,variable=\x,domain={vcrit2(#1-\pgfkeysvalueof{/pgfplots/view/az},\pgfkeysvalueof{/pgfplots/view/el})}:{vcrit1(#1-\pgfkeysvalueof{/pgfplots/view/az},\pgfkeysvalueof{/pgfplots/view/el})},samples=71]   
          ({torusx(#1-\pgfkeysvalueof{/pgfplots/view/az},\x,\R,\r)},{torusy(#1-\pgfkeysvalueof{/pgfplots/view/az},\x,\R,\r)},{torusz(#1-\pgfkeysvalueof{/pgfplots/view/az},\x,\R,\r)})
          node[below]{$C\ifnum#1=360 '\fi$};
        }
        \draw[thick] plot[smooth,variable=\x,domain=60:420,samples=71]   
        ({torusx(25+15*cos(\x),80+45*sin(\x),\R,\r)},
        {torusy(25+15*cos(\x),80+45*sin(\x),\R,\r)},
        {torusz(25+15*cos(\x),80+45*sin(\x),\R,\r)})
        node[above left]{$C''$};
   \end{axis}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada