6

I am trying to draw this picture enter image description here My code

\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz,tikz-3dplot} 
\usepackage{fouriernc}
\usetikzlibrary{folding}
\begin{document}
\tdplotsetmaincoords{60}{135}
    \begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round, line cap = round]
\pgfmathsetmacro\a{4}
\pgfmathsetmacro{\b}{\a/2}
\path
coordinate (A) at (\b,0,-\a) 
coordinate (B) at (0,\b,-\a) 
coordinate (C) at (-\b,0,-\a)
coordinate (D) at (0,-\b,-\a)
coordinate (I) at (\b,\a,0) 
coordinate (J) at (0,\a,-\b)
coordinate (K) at (-\b,\a,0) 
coordinate (L) at (0,\a,\b)
coordinate (P) at (\a,-\b,0) 
coordinate (Q) at (\a,0,-\b)
coordinate (R) at (\a,\b,0) 
coordinate (S) at (\a,0,\b)

coordinate (A') at ($(A)+ (0,0,2*\a)$) 
coordinate (B') at ($(B)+ (0,0,2*\a)$)  
coordinate (C') at ($(C)+ (0,0,2*\a)$) 
coordinate (D') at ($(D)+ (0,0,2*\a)$)

coordinate (I') at ($(I)+ (0,-2*\a,0)$) 
coordinate (J') at ($(J)+ (0,-2*\a,0)$)  
coordinate (K') at ($(K)+ (0,-2*\a,0)$) 
coordinate (L') at ($(L)+ (0,-2*\a,0)$)

coordinate (P') at ($(P)+ (-2*\a,0,0)$)
coordinate (Q') at ($(Q)+ (-2*\a,0,0)$)
coordinate (R') at ($(R)+ (-2*\a,0,0)$)
coordinate (S') at ($(S)+ (-2*\a,0,0)$);

\draw [ultra thick] 
(A) --(B)--(J)--(I) -- (R) -- (Q) --cycle
(I) --(J)--(K) --(L)--cycle
(K) --(L)--(B') --(C')--(S')--(R')--cycle 
(A') --(B')--(C')--(D') --cycle
(P) --(Q)--(R)--(S) --cycle
(S) --(P)--(I')--(L')--(D') --(A')--cycle
;

\draw [dashed]  (A) --(D) -- (C) --(B)
(C) -- (Q') -- (P') --(K')--(J') --(D)
(J') --(I') (K')-- (L') (P') --(S') (Q') --(R')

;
\foreach \point/\position in {A/below,B/below,C/below,D/left,I/below,J/below,K/right,L/above,P/right,Q/above,R/left,S/below,I'/below,J'/below,K'/right,L'/above,P'/right,Q'/above,R'/left,S'/below,A'/below,B'/below,C'/below,D'/left}
{\fill (\point) circle (0.0pt);
    %\node[\position=2pt] at (\point) {$\point$};
}

\end{tikzpicture}
\end{document}

How can I reduce my code?

  • 3
    Your code works very well. The length is not a great problem in LaTeX. So I don't see any problem with your code. – user156344 Feb 11 at 10:49
  • I suppose you could remove \usetikzlibrary{folding}, since you don't appear to be using it :). (I assume you're using it elsewhere in your document though.) – Circumscribe Feb 11 at 14:46
  • 1
    You could make shape (hexagon+ rectangle) and rotate it two times over 120°, but it want make a big difference in number of lines, I think. – Arne Timperman Feb 11 at 16:28
6

You can reduce the code for the coordinate definitions using four rotations around the vertical axis and a \foreach. (To save two lines, I gave directly the sine and cosine values to the foreach, as those are only -1, 0 and +1.)

Unfortunately, I don't know an easy (and automatic) way to know if and edge should be dashed or not, so I drew every edge by hand...

\documentclass[border=2mm,12pt,tikz]{standalone}
\usepackage{tikz,tikz-3dplot} 
\begin{document}

\tdplotsetmaincoords{60}{135}
\pgfmathsetmacro\a{4}
\pgfmathsetmacro{\b}{\a/2}    
\begin{tikzpicture}[tdplot_main_coords]

%% Coordinate definitions
\foreach \n/\vcos/\vsin in { 0/1/0, 1/0/1, 2/-1/0, 3/0/-1 }{
  \coordinate (A\n) at (\b*\vcos          , \b*\vsin          , -\a);
  \coordinate (B\n) at (\a*\vcos          , \a*\vsin          , -\b);
  \coordinate (C\n) at (\a                ,       \b          , 0  );
  \coordinate (C\n) at (\a*\vcos-\b*\vsin , \vcos*\b+\a*\vsin , 0  );
  \coordinate (D\n) at (\a*\vcos+\vsin*\b , \a*\vsin-\vcos*\b , 0  );
  \coordinate (E\n) at (\a*\vcos          , \vsin*\a          , \b );
  \coordinate (F\n) at (\b*\vcos          , \b*\vsin          , \a );
}

%% Edge with thick and dashed
\draw[ultra thick] (F0) edge(E0) -- (F1) edge (E1) -- (F2) edge (E2)
-- (F3) edge (E3) -- (F0) (E0) edge (D0) -- (C0) edge (D1) -- (B0) -- (A0)
-- (A1) -- (B1) -- (D1) -- (E1) -- (C1) edge (B1) -- (D2) -- (E2)
(E3) -- (C3) -- (D0) -- (B0);
\draw[dashed] (A1) -- (A2) -- (A3) edge (A0) -- (B3) edge (C3)
-- (D3) edge (E3) -- (C2) edge (E2)--(B2) edge (D2)--(A2);

\end{tikzpicture}
\end{document}
3

Just for fun. This draws hexagons in various rotated coordinates. This would in principle be enough if there were not the obnoxious dashed lines. To have some edges not (!) dashed, this requires some extra effort (last bit of the code).

\documentclass[border=3.14mm,tikz]{standalone}
\usepackage{tikz-3dplot} 
\usetikzlibrary{calc}
\tikzset{hexagon defined by/.style args={#1 and #2 with label #3}{insert path={
 -- ++ ($-1*#2$) coordinate (#3-2) 
-- ++ #1 coordinate (#3-3) --++ ($#1+#2$) coordinate (#3-4) 
-- ++ #2 coordinate (#3-5) -- ++ ($-1*#1$) coordinate (#3-6) 
-- ++ ($-1*#1-1*#2$) coordinate (#3-1)
}}}
\begin{document}
\tdplotsetmaincoords{60}{135}
\begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round, line cap = round]
 \pgfmathsetmacro\a{4}
 \pgfmathsetmacro{\b}{\a/2}
 \foreach \X/\Y/\Z [count=\NN] in {0/0/0,%back
 90/90/-90,% back bottom
 -30/0/-60,%back upper left
 30/0/60,%back upper right
 0/00/180,% top (first visible)
 90/90/0,%front lower right
 -90/90/00,%front lower left
 90/180/0%front
 }
 {\tdplotsetrotatedcoords{\X}{\Y}{\Z}
 \begin{scope}[tdplot_rotated_coords]
  \ifnum\NN<5
   \draw[very thick,dashed,fill opacity=0.5] (\a,0,\b) 
   [hexagon defined by={(\b-\a,\a-\b,0)} and {(0,-\b,\b)} with label H\NN];
  \else
   \draw[very thick,fill=white,fill opacity=0.5] (\a,0,\b) 
   [hexagon defined by={(\b-\a,\a-\b,0)} and {(0,-\b,\b)} with label H\NN];
  \fi 
 \end{scope}}
 \draw[very thick,fill=white,fill opacity=0.5] (H5-4) -- (H7-5) -- (H7-6) -- (H5-3) --cycle
 (H5-1) -- (H6-4) -- (H6-3) -- (H5-2) --cycle
 (H7-1) -- (H6-2) -- (H6-1) -- (H7-2) --cycle;
\end{tikzpicture}
\end{document}

enter image description here

And since the dash patterns do not necessarily match, one has unfortunately some not so nicely dashed lines as some lines get drawn twice.

If you do not insist on dashed lines (but are happy with the hidden lines being covered by an opaque surface), you could just do

\documentclass[border=3.14mm,tikz]{standalone}
\usepackage{tikz-3dplot} 
\usetikzlibrary{calc}
\tikzset{hexagon defined by/.style args={#1 and #2 with label #3}{insert path={
 -- ++ ($-1*#2$) coordinate (#3-2) 
-- ++ #1 coordinate (#3-3) --++ ($#1+#2$) coordinate (#3-4) 
-- ++ #2 coordinate (#3-5) -- ++ ($-1*#1$) coordinate (#3-6) 
-- ++ ($-1*#1-1*#2$) coordinate (#3-1)
}}}
\begin{document}
\tdplotsetmaincoords{60}{135}
\begin{tikzpicture}[tdplot_main_coords,scale=1,line join = round, line cap = round]
 \pgfmathsetmacro\a{4}
 \pgfmathsetmacro{\b}{\a/2}
 \foreach \X/\Y/\Z [count=\NN] in {0/0/0,%back
 90/90/-90,% back bottom
 -30/0/-60,%back upper left
 30/0/60,%back upper right
 0/00/180,% top (first visible)
 90/90/0,%front lower right
 -90/90/00,%front lower left
 90/180/0%front
 }
 {\tdplotsetrotatedcoords{\X}{\Y}{\Z}
 \begin{scope}[tdplot_rotated_coords]
   \draw[very thick,fill=white,fill opacity=0.7] (\a,0,\b) 
   [hexagon defined by={(\b-\a,\a-\b,0)} and {(0,-\b,\b)} with label H\NN];
 \end{scope}}
  \draw[very thick,fill=white,fill opacity=0.7] (H5-4) -- (H7-5) -- (H7-6) -- (H5-3) --cycle
 (H5-1) -- (H6-4) -- (H6-3) -- (H5-2) --cycle
 (H7-1) -- (H6-2) -- (H6-1) -- (H7-2) --cycle;
\end{tikzpicture}
\end{document}

enter image description here

This approach would in principle allow for an automatized determination which lines are hidden, something I do not want to pursue here since this post has a very nice accepted answer, which deserves to stay the accepted answer.

  • I didn't thought of "transparent white fill" to mark the hidden edge! This is really cool! – Vinzza Feb 13 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.