15

Could help me please, I tried to draw many polygons side by side without success!

This is what I want enter image description here

My MWE:

\documentclass{article}
\usepackage{xcolor}
\usepackage{pgf,tikz}
\usetikzlibrary{shapes,arrows,shadows,patterns,shapes.geometric,calc}
\begin{document}

\tikzset{poly/.style={regular polygon, regular polygon sides=6,fill=gray!10,minimum size=2 cm, draw}}

\tikzset{poly1/.style={regular polygon, regular polygon sides=6,fill=gray!30,minimum size =2cm, draw}}
\begin{tikzpicture}[scale=0.7]
\draw [help lines,gray!50,step =0.5] (-10,-10) grid (10,10);
\draw[red,-{stealth}](-10,0)--(10,0);
\draw[green!60!black,-{stealth}](0,-10)--(0,10);
\node [poly] at (2,2) {C7};
\node [poly] at (2,-0.5) {C6};
\node [poly1,rotate=-90] at (4.2,3.25) {C7};
\end{tikzpicture}
\end{document}

Any advice ?

  • Do you want the double color filling that two of the hexagons in the image show? – Gonzalo Medina Sep 14 '15 at 0:52
13

If you want to use the polygon nodes, you can use the .corner anchors to position them. Here is one set:

\documentclass[tikz,border=10mm]{standalone}
\usetikzlibrary{shapes.geometric,positioning}
\begin{document}

\tikzset{
  my poly/.style={regular polygon, regular polygon sides=6,fill=gray!#1,minimum size=2cm, draw},
}

\begin{tikzpicture}[node distance=0pt, every node/.style={outer sep=0pt}]
  \draw [help lines,gray!50,step =0.5] (-10,-10) grid (10,10);
  \node (1-C1) [my poly=10] {C1};
  \foreach \i/\j/\k/\m in {4/2/2/30,3/1/3/10,2/6/4/10,1/5/5/10,6/4/6/10,5/3/7/10}
  \node (1-C\k) [my poly=\m, anchor=corner \i] at (1-C1.corner \j) {C\k};
\end{tikzpicture}
\end{document}

one set of polygons

The nodes are named so that you can use the corners of the outer polygons to place the next one and so on. For example, (1-C1), (1-C2)....

Extension

In fact, if you use C2 as the initial node, rather than C1, then you can use a second, outer loop to position and draw further sets of 7 hexagons, building up the overall picture 7-by-7. For example:

\documentclass[tikz,border=10mm]{standalone}
\usetikzlibrary{shapes.geometric,positioning}
\begin{document}
\tikzset{
  my poly/.style={regular polygon, regular polygon sides=6,fill=gray!#1,minimum size=2cm, draw},
}
\begin{tikzpicture}[node distance=0pt, every node/.style={outer sep=0pt}]
  \foreach \a/\b/\c/\d [count=\hexset, remember=\hexset] in {2/0/0/0,2/1/4/6,1/1/5/3}
  {
    \ifnum\hexset>1
      \node (\hexset-C2) [my poly=30, anchor=corner \a] at (\b-C\c.corner \d) {C2};
    \else
      \node (1-C2) [my poly=30] {C2};
    \fi
    \foreach \i/\j/\k [remember=\k as \savedhex (initially 2)] in {3/5/3,2/4/4,1/3/5,5/3/6,5/1/7,3/5/1}
    \node (\hexset-C\k) [my poly=10, anchor=corner \i] at (\hexset-C\savedhex.corner \j) {C\k};
  }
\end{tikzpicture}
\end{document}

Hexagons 7-by-7

The outer loop (variables: \a/\b/\c/\d) is used to position each set of 7 hexagons relative to previous sets (except when the current set is the first set to be drawn). This is done using C2 as a kind of anchoring hexagon. So the variables specify which .corner anchor of C2 should be aligned with which .corner of which hexagon in which previous set of hexagons.

In the example, {2/0/0/0,2/1/4/6,1/1/5/3} draws 3 sets of 7 hexagons:

  • The first set is specified as 2/0/0/0 but the values here make no difference as there is nothing to align this set with.

  • The second is 2/1/4/6. This means that C2's corner 2 anchor in the new set of hexagons will be aligned with set 1: hexagon C4: corner 6 i.e. (1-C4.corner 6).

  • The third is 1/1/5/3. This means that C2's corner 1 anchor in the new set of hexagons will be aligned with set 1: hexagon C5: corner 3 i.e. (1-C5.corner 3). If we wanted to align with something from the second set instead, we would use ?/2/?/?.

The allows quite a concise specification of the hexagon structure.

  • The "thicker" inner lines can be avoided by outer sep=0pt in the style my poly. – Heiko Oberdiek Sep 13 '15 at 12:56
  • @HeikoOberdiek Thanks - I will fix that shortly. And thanks for correcting my code. Apparently, I was not paying enough attention. – cfr Sep 13 '15 at 13:01
  • @HeikoOberdiek OK. I can forget to do it even if the browser is open at the page. Done now. (As part of an update extending the example. I like playing with this!) – cfr Sep 13 '15 at 22:48
  • 1
    If cfr's answer is what you want then perhaps you should accept it.... – JPi Sep 14 '15 at 0:56
  • @JPi To ping another commenter, you need to do it explicitly. It is my answer, so I get pinged, but the asker of the question will not get pinged as far as I know. (I'm am not going to ping the OP because... well, just because.) – cfr Sep 14 '15 at 1:05
12

Here's one option:

enter image description here

The code:

\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,shapes.geometric,backgrounds}

\colorlet{darkfill}{gray}
\colorlet{lightfill}{gray!60}

\tikzset{myhex/.style={
  draw,
  outer sep=0pt,
  regular polygon,
  regular polygon sides=6,
  minimum size=2cm,
  font=\sffamily,
%  xscale=1.5
  }
}
\newcommand\FillHexagon[2]{
\begin{pgfonlayer}{background}
\fill[darkfill]
  (#1.corner 1) --
  (#1.corner 2) --
  (#1.corner 3) --
  (#1.corner 4) --
  (#1.corner 5) --
  (#1.corner 6);
\ifdim#2pt=0pt\relax
\else
  \ifdim#2pt<0.5pt\relax
  \fill[lightfill]
    (#1.corner 4) --
    ( $ (#1.corner 4)!2*#2!(#1.corner 3) $ ) --
    ( $ (#1.corner 5)!2*#2!(#1.corner 6) $ ) --
    (#1.corner 5) -- cycle;
  \else
    \ifdim#2pt>0.5pt\relax
  \fill[lightfill]
    (#1.corner 4) --
    (#1.corner 3) -- 
    ( $ (#1.corner 3)!2*#2-1!(#1.corner 2) $ ) --
    ( $ (#1.corner 6)!2*#2-1!(#1.corner 1) $ ) --
    (#1.corner 6) -- 
    (#1.corner 5) -- cycle; 
    \else
      \ifdim#2pt=0.5pt\relax
        \fill[lightfill]
          (#1.corner 4) --
          (#1.corner 3) --
          (#1.corner 6) --
          (#1.corner 5) -- cycle;
      \else
      \fi
    \fi  
  \fi
\fi
\end{pgfonlayer}
}

\begin{document}

\begin{tikzpicture}
\foreach \Nombre/\Shift in {1/{(0:0cm)},2/{(-49.2:4.58cm)},3/{(250.8:4.58cm)}}
{
  \node[myhex,shift={\Shift}]
    (center\Nombre)
    {C1};
  \foreach \Valor 
    [evaluate=\Valor as \Anchor using {int(mod(\Valor+2,6)+1)}] in {1,2,3,4,5,6}
    {
      \node[myhex,anchor=side \Anchor] 
        at (center\Nombre.side \Valor)
        (center\Nombre-\Valor) 
        {C\pgfmathprint{int(2+mod(6-mod(\Valor+5,6),6))}};  
    }
}
\FillHexagon{center1-1}{0}
\FillHexagon{center2-1}{0.1}
\FillHexagon{center3-1}{0.56}
\end{tikzpicture}

\end{document}
  • The command

    \FillHexagon{<name>}{<factor>}
    

    allows to fill a given hexagon using two different colors (as two of the hexagons in the image of the question). <factor> allows to specify the fraction of the hexagon that will be filled with the second color. The two colors are controlled by lightfill and darkfill; using 0 fills the hexagon with just darkfill and using 1 fills it completely using lightfill.

  • Uncomment the line % xscale=1.5 (and used the desired factor) if you want to elongate the hexagons along the x-component.

  • 1
    It seems that the borders are drawn “all inside” the polygons, which creates a bad thickness effect where two of them meet. Do you think it's possible to draw the borders “half out and half in”? – egreg Sep 13 '15 at 12:39
  • (+1) but the fills for the darker hexagons look strange. One is even, but the other 2 seem to have two different parts filled in two different shades. Is this intended? – cfr Sep 13 '15 at 22:51
  • 1
    @cfr Yes, is intended. I reproduced the image in the questio. Two of the hexagons have two-color fillings. – Gonzalo Medina Sep 13 '15 at 23:20
  • Hmmm.... Interesting. I couldn't think you'd done it accidentally but I can hardly see that in the original image (until looking very carefully now you've said it is there). Obviously it did not occur to me to do it this way since I didn't even see it this way in the first place. – cfr Sep 13 '15 at 23:33
  • @egreg Yes it's a simple change in outer sep. Fixed. – Gonzalo Medina Sep 14 '15 at 0:12
7

Compile with lualatex

\documentclass{article}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usepackage{luacode}



\begin{document}


\begin{tikzpicture}
\begin{luacode*}
cs=math.cos(math.pi/3)
ss=math.sin(math.pi/3)

function printcoord(x,y,s)
 tex.print(" (" .. x .. "," .. y .. ") " .. s )
 end

function drawpoly(tlx,tly,s,c)
 tex.print("\\draw[fill,color=" .. c .."] ")
 ox={0,1,1+cs,1,0,-cs}
 oy={0,0,-ss,-2*ss,-2*ss,-ss}
 for j=1,6  do printcoord(tlx+ox[j],tly+oy[j],"--") end
 tex.print("cycle; \\draw")
 printcoord(tlx+0.5,tly-ss," node{C" .. s .. "};")
 end

offx={ 0,0,1+cs,1+cs,0,-1-cs,-1-cs}
offy={ 0,2*ss,ss,-ss,-2*ss,-ss,ss}
col={"Beige","Green","Blue","Orange","Yellow","Magenta","Purple"}
coord= { {x=0, y=0 }, { x=1+cs, y=5*ss }, {x=3+3*cs, y=ss} }
for i,v in ipairs(coord) do for j=1,7 do  drawpoly(v.x+offx[j],v.y+offy[j],j,col[j])   end  end
 \end{luacode*}
\end{tikzpicture}

\end{document}

enter image description here

  • 1
    Short and colorful! (The labels for "C6" and "C7" are swapped.) – Gonzalo Medina Sep 13 '15 at 4:23
  • I have no idea what this does but (+1) anyway ;). – cfr Sep 13 '15 at 22:53
  • @cfr: thanks. It just draws each set of seven hexagons from first principles. I'd already +1d yours and Gonzalo's. – JPi Sep 13 '15 at 23:04
7

For this specific diagram, fooling around with some basic geometry can makes things reasonably compact using two simple loops.

\documentclass[tikz,border=5]{standalone} 
\usetikzlibrary{shapes.geometric}
\begin{document} 
\begin{tikzpicture}[every hexagon/.style={
  shape=regular polygon, regular polygon sides=6, inner sep=0, 
  minimum size=1cm, font=\sffamily, fill=gray!20, draw=white, thick},
  hexagon 2/.style={fill=blue!20}]
\foreach \j in {1,...,3}
  \foreach \i [evaluate={\a=210-\j*120+atan(sec(30)/6); \r=sqrt(7)/2;}] 
      in {1,...,7}
    \node [every hexagon/.try, hexagon \i/.try, shift=(\a:\r)]  
      at (210-\i*60:{(\i > 1)*cos(30)}) {C\i};
\end{tikzpicture}
\end{document}

enter image description here

  • 1
    nice ! You don't need /.try in every hexagon/.try I think. – Kpym Sep 15 '15 at 10:41
  • @Kpym nope, it isn't necessary in this case, just force of habit. – Mark Wibrow Sep 15 '15 at 17:42

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.