Qual é a melhor maneira no TikZ de desenhar uma estrutura hexagonalem 3D? Por exemplo,cristais de grafite, favos de mel ou racks estáveis feitos de reforços hexagonais alinhados.
Eu já encontrei esta boa solução:Desenhando hexágonos. Mas isso é apenas para hexágonos 2D.
Atualmente estou apenas anotando todos os nós separadamente com coordenadas (x,y,z). Mas isso tem as desvantagens de ser (a) muito chato, (b) as linhas de conexão não se importam com as camadas (as linhas não vão "atrás" do plano 2 se eu conectar os planos 1 e 3, é apenas desenhado em cima) .
Qual é a melhor maneira de realizar um3Destrutura hexagonal no TikZ que cuida das camadas e não precisa de todas as coordenadas inseridas manualmente, mas sim por um algoritmo?
Responder1
Aqui está outra opção, usando esse tempo regular polygon
da shapes
biblioteca; cada um dos \hexgrid...
comandos possui dois argumentos obrigatórios: o primeiro, dá um nome à grade e o segundo, controla o deslocamento vertical; o argumento opcional permite passar opções adicionais:
\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}
O código ainda admite melhorias, mas o principal é que ele pode ser usado como ponto de partida para definir facilmente grades hexagonais. Osiunitx
pacote foi usado para compor as unidades (graças aSvend Tveskægpara o lembrete).
Responder2
Não sei exatamente o que você quer porque existem várias possibilidades para desenhar uma estrutura hexagonal 3D. aqui um exemplo com tkz-berge
O próximo código pode ser adaptado:
\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}
Este outro exemplo (Autor: Andreas Menge) usa outro método com tkz-berge e é fácil de adaptar
\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}
Responder3
Aqui outra resposta sem tkz-berge
. Usei grande parte do código do Gonzalo mas sem, xslant,yslant
mas usei um style current plane
. Este estilo define em qual plano quero desenhar alguns objetos. Você precisa definir o ângulo (angle de fuite French terme em perspectiva). Se você alterar esse ângulo, às vezes será necessário alterar a opacidade de alguns lados.
Aqui eu uso um ângulo de 175° e depois 145°
Atualizar
Eu adicionei alguns estilos show
e hidden
. É mais legível.
\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}
Responder4
Ao adaptar o código doresposta aceitaparaDesenhando hexágonose seguindo o conselho de Qrrbrbirlbel, você pode fazer isso:
\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}