如何用 TikZ 绘制 3D 六边形结构?

如何用 TikZ 绘制 3D 六边形结构?

在 TikZ 中绘制六边形结构的最佳方法是什么3D 模式? 例如,石墨晶体、由六角形排列的加强筋制成的蜂窝或稳定的架子。

我已经找到了这个好的解决方案:绘制六边形。但这仅适用于 2D 六边形。

目前我只是用 (x,y,z) 坐标分别写下所有节点。但这样做的缺点是 (a) 非常烦人,(b) 连接线不关心层(如果我连接平面 1 和 3,线不会“在”平面 2 后面,它只是画在顶部)。

实现3DTikZ 中的六边形结构负责处理图层,并且不需要手动输入所有坐标,而是通过算法?

答案1

这是另一个选项,这次使用库regular polygon中的选项shapes;每个命令\hexgrid...都有两个强制参数:第一个为网格命名,第二个控制垂直移动;可选参数允许传递附加选项:

\documentclass{article}
\usepackage{tikz}
\usepackage{siunitx}
\usetikzlibrary{arrows,positioning,shapes}

\newcommand\xsla{-1.2}
\newcommand\ysla{0.505}

\newcommand\hexgridv[3][]{%
\begin{scope}[%
  #1
  xscale=-1,
  yshift=#3,
  yslant=\ysla,
  xslant=\xsla,
  every node/.style={anchor=west,regular polygon, regular polygon sides=6,draw,inner sep=0.5cm},
  transform shape
]
\node (A#2) {};
\node (B#2) at ([xshift=-\pgflinewidth,yshift=-\pgflinewidth]A#2.corner 1) {};
\node (C#2) at ([xshift=-\pgflinewidth]B#2.corner 5) {};
\node (D#2) at ([xshift=-\pgflinewidth]A#2.corner 5) {};
\node (E#2) at ([xshift=-\pgflinewidth]D#2.corner 5) {};
\foreach \hex in {A,...,E}
{
  \foreach \corn in {1,...,6}
    \draw[fill=white] (\hex#2.corner \corn) circle (2pt); 
}
\end{scope}
}

\newcommand\hexgridiv[3][]{%
\begin{scope}[%
  #1,
  xscale=-1,
  yshift=#3,
  yslant=\ysla,
  xslant=\xsla,
  every node/.style={anchor=west,regular polygon, regular polygon sides=6,draw,inner sep=0.5cm},
  transform shape
]
\node (A#2) {};
\node (B#2) at (A#2.corner 5) {};
\node[xscale=-1] (C#2) at (B#2.corner 4) {};
\node (D#2) at (C#2.corner 4) {};
\foreach \hex in {A,...,D}
{
  \foreach \corn in {1,...,6}
    \draw[fill=white] (\hex#2.corner \corn) circle (2pt); 
}
\end{scope}
}

\begin{document}

\begin{tikzpicture}[>=latex]
% the three grids
\hexgridv{a}{0}
\hexgridiv[xshift=0.43cm]{b}{-60}
\hexgridv{c}{-160}

% the red lines
\foreach \corn in {2,4}
  \draw[ultra thick,red!80!black] (Aa.corner \corn) -- (Ac.corner \corn);
\draw[ultra thick,red!80!black,opacity=0.4] (Aa.corner 6) -- (Ac.corner 6);
\draw[ultra thick,red!80!black] (Da.corner 4) -- (Dc.corner 4);
\foreach \hexg in {a,c}
  \draw[thick,red!80!black] (A\hexg.corner 2) -- (A\hexg.corner 4) -- (D\hexg.corner 4);
\foreach \hexg/\opac in {a/1,c/0.4}
  \draw[thick,red!80!black,opacity=\opac] (A\hexg.corner 2) -- (A\hexg.corner 6) -- (D\hexg.corner 4);

% the red vertices
\begin{scope}[  yslant=\ysla,xslant=\xsla]
\foreach \hex/\corn in {Aa/2,Aa/4,Aa/6,Ab/3,Ac/2,Ac/4,Da/4,Cb/6,Cb/4,Dc/4} 
  \draw[fill=red!80!black] (\hex.corner \corn) circle (2pt);
\draw[fill=red!80!black,fill opacity=0.4] (Ac.corner 6) circle (2pt);
\draw[fill=red!80!black,fill opacity=0.4] (Cb.corner 2) circle (2pt);
\end{scope}

% The arrows and labels
\draw[help lines] 
  (Aa.corner 2) -- +(2.5,0) coordinate[pos=0.75] (aux1);
\draw[help lines] 
  (Ac.corner 2) -- +(2.5,0) coordinate[pos=0.75] (aux2);
\draw[<->,help lines] 
  (aux1) -- node[pos=0.25,fill=white,font=\footnotesize] {\SI{6.708}{\angstrom}} (aux2);
\draw[help lines] 
  (Ab.corner 2) -- +(1,0) coordinate[pos=0.5] (aux3);
\draw[<->,help lines] 
  (aux3) -- node[fill=white,font=\footnotesize,align=center] {b\\\SI{3.354}{\angstrom}} (aux3|-aux2);
\draw[help lines] 
  (Ac.corner 3) -- +(0,-0.45) coordinate[pos=0.5] (aux4);
\draw[help lines] 
  (Ac.corner 4) -- +(0,-0.4) coordinate[pos=0.5] (aux5);
\draw[<->,help lines] 
  (aux4) -- node[fill=white,font=\footnotesize,align=center,below=1pt] {a\\\SI{1.421}{\angstrom}} (aux5|-aux4);
\end{tikzpicture}

\end{document}

在此处输入图片描述

该代码仍有改进空间,但主要的一点是它可以作为轻松定义六边形网格的起点。siunitx包用于排版单位(感谢斯文德·特韦斯凯格以作提醒)。

答案2

我不知道你到底想要什么,因为有几种绘制 3D 六边形结构的可能性。这里有一个 tkz-berge 的例子

下一个代码可以修改:

\documentclass{article}
\usepackage{tkz-berge}
\usetikzlibrary{3d}
\newcommand\pgfmathsinandcos[3]{% 
  \pgfmathsetmacro#1{sin(#3)}% 
  \pgfmathsetmacro#2{cos(#3)}% 
}

\begin{document}

    \pgfmathsetmacro\angFuite{155}
    \pgfmathsetmacro\coeffReduc{1}
    \pgfmathsinandcos\sint\cost{\angFuite}

\begin{tikzpicture}[current plane/.estyle=%
        {cm={1,0,\coeffReduc*\cost,-\coeffReduc*\sint,(0,#1)}}]

\GraphInit[vstyle=Shade]

      \begin{scope}[current plane=0 cm]
         \SetGraphShadeColor{white}{teal}{gray}
         \grEmptyCycle[Math,prefix=a]{6}
     \end{scope}

      \begin{scope}[current plane=6 cm]
         \SetGraphShadeColor{white}{teal}{gray}
         \grEmptyCycle[Math,prefix=b]{6}
     \end{scope}

 \SetGraphShadeColor{white}{teal}{gray}
 \EdgeIdentity*[style={opacity=.3}]{a}{b}{3,4}
 \EdgeInGraphSeq{a}{0}{1}  
 \EdgeInGraphSeq[style={opacity=.3}]{a}{1}{4}
 \Edge(a0)(a5)
 \EdgeInGraphLoop{b}{6}
 \EdgeIdentity*{a}{b}{0,1,2,5}
\end{tikzpicture}
\end{document}

在此处输入图片描述

这个例子(作者:Andreas Menge)使用了另一种方法,即 tkz-berge,而且很容易适应

\documentclass[10pt]{article}
\usepackage{tkz-berge}

\newcommand{\myGlobalTransformation}[2]
{
    \pgftransformcm{1}{0}{0.6}{0.2}{\pgfpoint{#1cm}{#2cm}}
}

\begin{document}
\pagestyle{empty}

\begin{tikzpicture}

  \GraphInit[vstyle=Art]
  \begin{scope}
    \myGlobalTransformation{0}{0}
    \grCycle[prefix=a]{5}
  \end{scope}

  \begin{scope}
    \myGlobalTransformation{0}{2}
    \grCycle[prefix=b]{5}
  \end{scope}

  \EdgeIdentity{a}{b}{5}

  \begin{scope}
    \myGlobalTransformation{0}{-2}
    \Vertex{x}
  \end{scope}

  \begin{scope}
    \myGlobalTransformation{0}{4}
    \Vertex{y}
  \end{scope}

  \EdgeFromOneToAll{x}{a}{}{5}
  \EdgeFromOneToAll{y}{b}{}{5}
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案3

这里还有另一个没有 的答案tkz-berge。我使用了 Gonzalo 的大部分代码,但没有,xslant,yslant但我使用了一种样式current plane。此样式定义了我想在哪个平面上绘制一些对象。您需要定义角度(透视图中的 angle de fuite french terme)。如果更改此角度,有时您需要更改某些侧面的不透明度。

这里我使用了 175° 的角度,然后是 145°

更新

我添加了一些样式showhidden。它更具可读性。

\documentclass{article}
\usepackage{tikz,fullpage}
\usetikzlibrary{arrows,positioning,shapes}

\newcommand\hexgridv[2][]{%
\begin{scope}[%
  #1,
  every node/.style={anchor=west,regular polygon, regular polygon sides=6,draw,inner sep=0.5cm},transform shape
]
\node (A#2) {};
\node (B#2) at ([xshift=-\pgflinewidth,yshift=-\pgflinewidth]A#2.corner 1) {};
\node (C#2) at ([xshift=-\pgflinewidth]B#2.corner 5) {};
\node (D#2) at ([xshift=-\pgflinewidth]A#2.corner 5) {};
\node (E#2) at ([xshift=-\pgflinewidth]D#2.corner 5) {};
\foreach \hex in {A,...,E}
{
  \foreach \corn in {1,...,6}
    \draw[fill=white] (\hex#2.corner \corn) circle (2pt); 
}
\end{scope}
}

\newcommand\pgfmathsinandcos[3]{% 
  \pgfmathsetmacro#1{sin(#3)}% 
  \pgfmathsetmacro#2{cos(#3)}% 
}

\begin{document}

    \pgfmathsetmacro\angFuite{145}
    \pgfmathsetmacro\coeffReduc{.75}
    \pgfmathsinandcos\sint\cost{\angFuite}

\begin{tikzpicture}[scale=2,
current plane/.estyle={cm={1,0,\coeffReduc*\cost,-\coeffReduc*\sint,(0,#1)}},
show/.style={ultra thick,red!80!black,opacity=1},
hidden/.style={ultra thick,red!80!black,opacity=.4,dashed}]

      \begin{scope}[current plane=0 cm]
        \hexgridv[color=blue]{a}
        \draw[blue!20] (-1,-2) grid (5,2);
     \end{scope}

      \begin{scope}[current plane=3 cm]
        \draw[orange!20] (-1,-2) grid (5,2);
        \hexgridv[color=orange]{c}
     \end{scope}


\begin{scope}[current plane=3 cm]
\foreach \hex/\corn in {Ac/2,Ac/4,Dc/4} 
  \draw[fill=red!80!black] (\hex.corner \corn) circle (2pt);
\draw[fill=red!80!black,fill opacity=0.4] (Ac.corner 6) circle (2pt);
\end{scope}

% the red lines
  \draw[hidden] (Aa.corner 4) -- (Ac.corner 4);
  \draw[hidden] (Da.corner 4) -- (Aa.corner 4) -- (Aa.corner 2) ; 
  \draw[show] (Ac.corner 2) -- (Ac.corner 6) -- (Dc.corner 4) -- (Ac.corner 4) -- (Ac.corner 2);
   \draw[show] (Aa.corner 2) -- (Aa.corner 6) -- (Da.corner 4) 
               (Da.corner 4) -- (Dc.corner 4);
  \foreach \corn in {2,6}
    \draw[show] (Aa.corner \corn) -- (Ac.corner \corn);

% the red vertices
\begin{scope}[current plane=0 cm]
\draw[hidden] (Ac.corner 6) circle (2pt);
\foreach \hex/\corn in {Aa/2,Aa/4,Aa/6,Da/4} 
  \draw[show] (\hex.corner \corn) circle (2pt);
\end{scope}

\end{tikzpicture}
\end{document}

在此处输入图片描述

在此处输入图片描述

答案4

通过改编接受的答案绘制六边形按照 Qrrbrbirlbel 的建议,您可以这样做:

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\newcommand\hexagonalstructure[1]{    \begin{scope}[%
        yshift=#1,
        yslant=0.5,%
        xslant=-1.7,%
    ]
        \foreach \i in {0,...,2} 
        \foreach \j in {0,...,2} {
        \foreach \a in {0,120,-120} \draw (3*\i,2*sin{60}*\j) -- +(\a:1);
        \foreach \a in {0,120,-120} \draw (3*\i+3*cos{60},2*sin{60}*\j+sin{60}) -- +(\a:1);}
    \end{scope}
}

\begin{document}
\begin{tikzpicture}[scale=.5]
    \hexagonalstructure{0}
    \hexagonalstructure{-170}
    \hexagonalstructure{-340}
\end{tikzpicture}
\end{document}

相关内容