如何用TikZ繪製3D六邊形結構?

如何用TikZ繪製3D六邊形結構?

TikZ中繪製六邊形結構的最佳方法是什麼3D 形式?例如,石墨晶體、蜂窩狀或由六角形排列的加強筋製成的穩定架。

我已經找到了這個不錯的解決方案:繪製六邊形。但這僅適用於二維六邊形。

目前我只是用 (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但我使用了 style 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}

相關內容