我如何用 tikz 绘制许多不相交的 3D 圆柱体,就像 3D 织物一样,无需编织?

我如何用 tikz 绘制许多不相交的 3D 圆柱体,就像 3D 织物一样,无需编织?

下面的代码制作了一组圆柱体(可接受)。我正尝试制作另外两组与此圆柱体成直角的圆柱体。第二组圆柱体位于平行平面上,因此从两个圆柱体中垂直看,可以看到空的方形孔。第三组圆柱体垂直于平面,穿透方形孔。

我尝试了各种旋转但似乎无法掌握所需的变换。

目标是创建一个可以参数化的网格,使得圆柱体很薄并且在一个表达式中不会接近接触,或者圆柱体很厚并且在另一个表达式中重叠。

思考这一问题的一种方式是,看看纽约地铁的布置,地铁管道必须互不接触地通过,包括通往站台的电梯井。

平均能量损失

\documentclass[12pt]{article}

\usepackage{tikz}

\usetikzlibrary{backgrounds,shapes}

\listfiles
\begin{document}

\newcommand\Cylinder[3]{%
    \begin{scope}
        \tikzset{every node/.style={
            cylinder,
            rotate=#3,
            draw,
            cylinder uses custom fill,
            cylinder end fill=white!25!black,
            cylinder body fill=white!60!black,
            minimum height=10cm,
            minimum width=0.1cm,
            opacity=.4}}
        \node at (#1,#2) {};
    \end{scope}
}
    \begin{tikzpicture}
    [background rectangle/.style={fill=yellow!45!white},
    show background rectangle]
    \foreach \y in {0,1,2,3,4,5,6,7,8,9}{
        \Cylinder{0}{\y}{0}
    }
\end{tikzpicture}

\end{document}

谢谢 Sc!!!!!! 在 Sc 的指导下,MWE 几乎完全按照我的要求完成了工作。

\documentclass[12pt]{article}

\usepackage{tikz}
\usepackage{tikz-3dplot}

\usetikzlibrary{backgrounds,shapes}

\tikzset{pics/simple 3d cylinder/.style={code={ 
\tikzset{simple 3d cylinder/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/simple 3d cylinder/##1}}%
\tdplotsetrotatedcoords{\pv{alpha}}{\pv{beta}}{0}
\begin{scope}[tdplot_rotated_coords]
    \draw[simple 3d cylinder/mantle,line width=2*\pv{r}*1cm]
        (0,0,-\pv{h}/2) -- (0,0,\pv{h}/2);
    \pgfmathtruncatemacro{\itest}{sign(
    sin(\tdplotmaintheta)*sin(\tdplotmainphi)*cos(\pv{alpha})*sin(\pv{beta})
 -1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)*sin(\pv{alpha})*sin(\pv{beta})
   +cos(\tdplotmaintheta)*cos(\pv{beta})
    )}
 \unless\ifnum\itest=0
 \path[fill,simple 3d cylinder/mantle]
    plot[variable=\t,domain=0:360,smooth cycle]
        ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{-\itest*\pv{h}/2});
 \path[fill,simple 3d cylinder/top]
    plot[variable=\t,domain=0:360,smooth cycle]
        ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{\itest*\pv{h}/2});
 \fi
\end{scope}
}},
    simple 3d cylinder/.cd,
    r/.initial=0.1,
    h/.initial=10,
    alpha/.initial=0,
    beta/.initial=0,
    top/.style={fill=gray},
    mantle/.style={black}
}

\listfiles
\begin{document}

% TODO build chopstick mesh up from the bottom to satisfy hiddenness
\tdplotsetmaincoords{70}{126}

\noindent
\begin{tikzpicture}[tdplot_main_coords,scale=0.95]
    % actin vertical
    \path foreach \X in {0,...,10} {
        (-0.5,\X-0.5,-5)
            pic{
                simple 3d cylinder=
                {mantle/.style={blue},h=12}
            }
    };
    % actin horizontal
    \path foreach \X in {0,...,10} {
        (0,4.5,-\X)
            pic{
                simple 3d cylinder=
                {mantle/.style={red},h=12,alpha=90,beta=90}
            }
    };
    % Calcium crosslink
    \foreach \Z in {0,...,10} { \foreach \Y in {0,...,10} {
        \shade [ball color=gray] (-0.2,\Y-0.3,-\Z-0.1)
            circle [radius=0.2cm]; % 0.2 some, 0.7 complete
    }}
    % neurofibril
    \path foreach \X in {1,...,10} {
        (3.5,-0.5,-\X)
            pic{
                simple 3d cylinder=
                {h=9.2,beta=90}
            }
    };
\end{tikzpicture}

\noindent\rule{\textwidth}{1pt}

\end{document}

答案1

这是一个完全可旋转的“简单”圆柱体版本,其中“简单”意味着我们稍微作弊,只画一条粗线,并确保两端没问题。我们在这个版本中没有轮廓(但可以找到轮廓这里)。然而,这些圆柱体是完全可旋转的。旋转角度为alphabeta。(显然,我们只需要两个旋转角度,因为圆柱体绕其轴具有旋转对称性。)但是,这个答案(目前)没有任何 3d 排序。(可能)可以根据圆柱体的质心坐标对其进行排序。我不认为 TiZ 是超越这一点的正确工具。

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\tikzset{pics/simple 3d cylinder/.style={code={ 
 \tikzset{simple 3d cylinder/.cd,#1}
 \def\pv##1{\pgfkeysvalueof{/tikz/simple 3d cylinder/##1}}%
 \tdplotsetrotatedcoords{\pv{alpha}}{\pv{beta}}{0}
 \begin{scope}[tdplot_rotated_coords]
 \draw[simple 3d cylinder/mantle,line width=2*\pv{r}*1cm] (0,0,-\pv{h}/2) --
 (0,0,\pv{h}/2);
 \pgfmathtruncatemacro{\itest}{sign(
    sin(\tdplotmaintheta)*sin(\tdplotmainphi)*cos(\pv{alpha})*sin(\pv{beta})
    -1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)*sin(\pv{alpha})*sin(\pv{beta})
    +cos(\tdplotmaintheta)*cos(\pv{beta})
    )}
 \unless\ifnum\itest=0
    \path[fill,simple 3d cylinder/mantle] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{-\itest*\pv{h}/2}) ;
    \path[fill,simple 3d cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{\itest*\pv{h}/2});
 \fi
 \end{scope}
}},simple 3d cylinder/.cd,r/.initial=0.2,h/.initial=2,
    alpha/.initial=0,beta/.initial=0,
    top/.style={fill=gray},mantle/.style={blue}}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords]
 \path foreach \X in {1,...,10}
 {(0,4,-\X) pic{simple 3d cylinder={alpha=90,beta=90,h=6,mantle/.style={red}}}
 (4,0,-\X) pic{simple 3d cylinder={alpha=0,beta=90,h=6}}
 (\X,\X,3) pic{simple 3d cylinder={alpha=0,beta=0,h=6,mantle/.style={orange}}}
 };
\end{tikzpicture}
\end{document}

在此处输入图片描述

您可以手动进行 3d 排序,例如逐层绘制网格。

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\tikzset{pics/simple 3d cylinder/.style={code={ 
 \tikzset{simple 3d cylinder/.cd,#1}
 \def\pv##1{\pgfkeysvalueof{/tikz/simple 3d cylinder/##1}}%
 \tdplotsetrotatedcoords{\pv{alpha}}{\pv{beta}}{0}
 \begin{scope}[tdplot_rotated_coords]
 \draw[simple 3d cylinder/mantle,line width=2*\pv{r}*1cm] (0,0,-\pv{h}/2) --
 (0,0,\pv{h}/2);
 \pgfmathtruncatemacro{\itest}{sign(
    sin(\tdplotmaintheta)*sin(\tdplotmainphi)*cos(\pv{alpha})*sin(\pv{beta})
    -1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)*sin(\pv{alpha})*sin(\pv{beta})
    +cos(\tdplotmaintheta)*cos(\pv{beta})
    )}
 \unless\ifnum\itest=0
    \path[fill,simple 3d cylinder/mantle] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{-\itest*\pv{h}/2}) ;
    \path[fill,simple 3d cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{\itest*\pv{h}/2});
 \fi
 \end{scope}
}},simple 3d cylinder/.cd,r/.initial=0.15,h/.initial=12,
    alpha/.initial=0,beta/.initial=0,
    top/.style={fill=gray},mantle/.style={blue}}
\begin{document}
\tdplotsetmaincoords{70}{120}
\begin{tikzpicture}[tdplot_main_coords]
 \foreach \X in {1,...,5}
 {\path foreach \Z in {1,...,5}
 {(-1+2*\X-6,0,2*\Z-6) 
    pic{simple 3d cylinder={alpha=90,beta=90,mantle/.style={red}}}
 };
 \path foreach \Y in {1,...,5}
  { foreach \Z in {1,...,5}
   {(2*\X-5,2*\Y-7,2*\Z-5)
    pic{simple 3d cylinder={alpha=0,beta=90,h=2,mantle/.style={blue}}}
    }
  (2*\X-6,2*\Y-6,0) 
    pic{simple 3d cylinder={alpha=0,beta=0,mantle/.style={orange}}} 
 };}
\end{tikzpicture}
\end{document}

在此处输入图片描述

下面的动画是为了说明“逐层”的含义。

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\tikzset{pics/simple 3d cylinder/.style={code={ 
 \tikzset{simple 3d cylinder/.cd,#1}
 \def\pv##1{\pgfkeysvalueof{/tikz/simple 3d cylinder/##1}}%
 \tdplotsetrotatedcoords{\pv{alpha}}{\pv{beta}}{0}
 \begin{scope}[tdplot_rotated_coords]
 \draw[simple 3d cylinder/mantle,line width=2*\pv{r}*1cm] (0,0,-\pv{h}/2) --
 (0,0,\pv{h}/2);
 \pgfmathtruncatemacro{\itest}{sign(
    sin(\tdplotmaintheta)*sin(\tdplotmainphi)*cos(\pv{alpha})*sin(\pv{beta})
    -1*sin(\tdplotmaintheta)*cos(\tdplotmainphi)*sin(\pv{alpha})*sin(\pv{beta})
    +cos(\tdplotmaintheta)*cos(\pv{beta})
    )}
 \unless\ifnum\itest=0
    \path[fill,simple 3d cylinder/mantle] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{-\itest*\pv{h}/2}) ;
    \path[fill,simple 3d cylinder/top] plot[variable=\t,domain=0:360,smooth cycle]
    ({\pv{r}*cos(\t)},{\pv{r}*sin(\t)},{\itest*\pv{h}/2});
 \fi
 \end{scope}
}},simple 3d cylinder/.cd,r/.initial=0.15,h/.initial=12,
    alpha/.initial=0,beta/.initial=0,
    top/.style={fill=gray},mantle/.style={blue}}
\begin{document}
\tdplotsetmaincoords{70}{120}
\foreach \Step in {1,...,15}
{\begin{tikzpicture}[tdplot_main_coords]
\path[tdplot_screen_coords,use as bounding box] (-8,-8) rectangle (8,8);
 \foreach \X in {1,...,5}
 {\path foreach \Z in {1,...,5}
 {(-1+2*\X-6,0,2*\Z-6) \ifnum\numexpr3*\X-3<\Step
    pic{simple 3d cylinder={alpha=90,beta=90,mantle/.style={red}}}
    \fi
 };
 \path foreach \Y in {1,...,5}
  { foreach \Z in {1,...,5}
   {(2*\X-5,2*\Y-7,2*\Z-5) \ifnum\numexpr3*\X-1<\Step
    pic{simple 3d cylinder={alpha=0,beta=90,h=2,mantle/.style={blue}}}
    \fi
    }
  (2*\X-6,2*\Y-6,0) \ifnum\numexpr3*\X-2<\Step
    pic{simple 3d cylinder={alpha=0,beta=0,mantle/.style={orange}}} 
    \fi
 };}
\end{tikzpicture}}
\end{document}

在此处输入图片描述

显然,对于(非常)不同的视角,需要改变图层。

相关内容