38

I have a case where I need to draw a hexagonal grid in LaTeX. I am considering just reading the grid from an eps file.

Is there an alternative way to do it completely within LaTeX?

4
  • 1
    You can use TikZ and adopt the code from this triangular grid.
    – Caramdir
    Commented Nov 26, 2010 at 23:14
  • 1
    as usual tikz or pstricks or metapost among others
    – pluton
    Commented Nov 26, 2010 at 23:17
  • 3
    By the way, I was quite amused by your no-so-veiled "threat" to LaTeX: "I am considering just reading the grid from an eps file.".... :-) Commented Nov 28, 2010 at 9:18
  • Thanks for mentioning TikZ. I want to typeset some astrology charts and this might be just the thing. Commented Nov 28, 2010 at 23:14

5 Answers 5

57

Here's a quick option:

\begin{tikzpicture}
  \foreach \i in {0,...,3} 
  \foreach \j in {0,...,3} {
  \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{tikzpicture}

Which results in

alt text

9
  • That is an amazingly good solution!
    – yannisl
    Commented Nov 27, 2010 at 12:48
  • I have to give you the checkmark. You did exactly how I dreamt it.
    – John Smith
    Commented Nov 29, 2010 at 0:13
  • Took a bit of searching for the code to do this (but faster than doing it myself) but thanks. It's helped me too. Commented Apr 8, 2013 at 23:09
  • I would like to number your hexagons following an order that I set. It's possible to do this?
    – benedito
    Commented Nov 11, 2015 at 21:58
  • How to set the hexagons larger?
    – bmv
    Commented Mar 18, 2018 at 20:18
50

With TikZ, you can define a pattern which allows to fill any shape with a hexagonal grid by adding the option pattern=hexagons:

alt text

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{patterns}

\def\hexagonsize{0.5cm}
\pgfdeclarepatternformonly
  {hexagons}% name
  {\pgfpointorigin}% lower left
  {\pgfpoint{3*\hexagonsize}{0.866025*2*\hexagonsize}}%  upper right
  {\pgfpoint{3*\hexagonsize}{0.866025*2*\hexagonsize}}%  tile size
  {% shape description
   \pgfsetlinewidth{0.4pt}
   \pgftransformshift{\pgfpoint{0mm}{0.866025*\hexagonsize}}
   \pgfpathmoveto{\pgfpoint{0mm}{0mm}}
   \pgfpathlineto{\pgfpoint{0.5*\hexagonsize}{0mm}}
   \pgfpathlineto{\pgfpoint{\hexagonsize}{-0.866025*\hexagonsize}}
   \pgfpathlineto{\pgfpoint{2*\hexagonsize}{-0.866025*\hexagonsize}}
   \pgfpathlineto{\pgfpoint{2.5*\hexagonsize}{0mm}}
   \pgfpathlineto{\pgfpoint{3*\hexagonsize+0.2mm}{0mm}}
   \pgfpathmoveto{\pgfpoint{0.5*\hexagonsize}{0mm}}
   \pgfpathlineto{\pgfpoint{\hexagonsize}{0.866025*\hexagonsize}}
   \pgfpathlineto{\pgfpoint{2*\hexagonsize}{0.866025*\hexagonsize}}
   \pgfpathlineto{\pgfpoint{2.5*\hexagonsize}{0mm}}
   \pgfusepath{stroke}
  }
\begin{document}

\begin{tikzpicture}
\fill[pattern=hexagons] (0,0) rectangle (10,5);
\end{tikzpicture}

\begin{tikzpicture}
\fill[pattern=hexagons] (0,0) circle (3cm);
\end{tikzpicture}

\end{document}

You can change the size of the hexagons by modifying the value of the macro \hexagonsize.

3
  • I like it! Nice solution. Commented Nov 29, 2010 at 8:16
  • Ah finally found it. I was looking for this nice snippet for a while with bad keywords :-) Would you like to write an answer to the open question tex.stackexchange.com/questions/54358/… ? I think this would be the perfect example.
    – percusse
    Commented Jun 17, 2012 at 21:32
  • @percusse: thanks for notifying me. I'll add an answer later on. Commented Jun 18, 2012 at 6:34
14

Another way could be to draw hexagonal nodes over an adjusted coordinate system. The idea came adapting Paul Gaborit's Pascal triangle for How can I draw Pascal's triangle with some its properties?.

shapes.geometric library helps to draw hexagon where the minimum size is the diameter of the circumcircle. Therefore, selecting adjusted values for x (x=1.5*{minimum size}) and y (y=\sqrt{.75}*{minimum size}/2) the hexagonal grid can be drawn placing an node centered in every pair (x,y).

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

%
% x=3*(minimum size)/2
% x=\sqrt{3/4}*(minimum size)/2
%
\begin{tikzpicture}[x=7.5mm,y=4.34mm]
  % some styles
  \tikzset{
    box/.style={
      regular polygon,
      regular polygon sides=6,
      minimum size=10mm,
      inner sep=0mm,
      outer sep=0mm,
      rotate=0,
    draw
    }
  }

\foreach \i in {0,...,5} 
    \foreach \j in {0,...,5} {
            \node[box] at (2*\i,2*\j) {};
            \node[box] at (2*\i+1,2*\j+1) {};
        }

\end{tikzpicture}

\end{document}

enter image description here

4
  • What are the [x=7.5mm,y=4.34mm] parameters for the Tikz package?
    – jvriesem
    Commented Jan 6, 2016 at 1:13
  • @jvriesem They define base vectors for the coordinate system. By default,x=1cm and y=1cm. When you say (2,3), TiKZ reads (2*x,3*y). Better explanation can be found in Coordiante system in TiKZ documentation.
    – Ignasi
    Commented Jan 6, 2016 at 21:11
  • @Ignasi How to set the hexagons larger?
    – bmv
    Commented Mar 18, 2018 at 20:18
  • @bmv Change minimum size and values of x and y accordingly
    – Ignasi
    Commented Mar 18, 2018 at 21:31
10

And a Metapost approach...

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

% r = side of hexagon, n = repetitions of the grid (- and +)
r = 5mm; n=10;

% make a shape to draw
path tri; tri = for t=0 step 120 until 359: origin -- (r,0) rotated t -- endfor cycle;

% save the pattern as a picture centered on the origin
picture grid; grid = image(
  for i=-n upto n:
    for j=-n upto n: 
      draw tri shifted (i*3/2r,j*r*sqrt(3)) if (i mod 2)=1: shifted (0,r/2*sqrt(3)) fi ; 
    endfor
  endfor);

% clip the pattern as required (to get rid of the rough edges...)
clip grid to fullcircle scaled (2*n*r);

% draw as needed
draw grid; 
draw grid rotated 30 shifted (2n*r,0) withcolor .67 red;

endfig;
end.
4
  \documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc,patterns}
\newlength{\dodamnet}
\newcommand{\bankinh}{}
\newcommand{\maumot}{}
\newcommand{\mauhai}{}
\newcommand{\mauba}{}
\newcommand{\maubon}{}
\tikzset{
            do dam net/.code={\setlength{\dodamnet}{#1}},
            ban kinh/.code={\renewcommand{\bankinh}{#1}},
            mau mot/.code={\renewcommand{\maumot}{#1}},
            mau hai/.code={\renewcommand{\mauhai}{#1}},
            mau ba/.code={\renewcommand{\mauba}{#1}},
            mau bon/.code={\renewcommand{\maubon}{#1}}
           }
\tikzset{
             do dam net=0.5pt,
             mau mot=red,
             mau hai=blue,
             mau ba=pink,
             mau bon=yellow,
             ban kinh =1
            }
\begin{document}
\pgfdeclarepatternformonly[\bankinh,\maumot,\mauhai,\mauba,\maubon,\dodamnet]{luc giac mau}
{\pgfmathsetmacro{\x}{1.5* \bankinh}
\pgfmathsetmacro{\y}{\bankinh *sqrt(3)}
\pgfqpoint{-\x mm}{-\y mm}}%Dưới trái
{\pgfmathsetmacro{\x}{1.5* \bankinh}
\pgfmathsetmacro{\y}{\bankinh *sqrt(3)}
\pgfqpoint{\x mm}{\y mm}}%Trên phải
{\pgfmathsetmacro{\x}{3* \bankinh}
\pgfmathsetmacro{\y}{2*\bankinh *sqrt(3)}
\pgfqpoint{\x mm}{\y mm}}
%======================
{\pgfsetlinewidth{\dodamnet}
\pgfmathsetmacro{\nuabk}{\bankinh/2}
\pgfmathsetmacro{\cao}{\nuabk *sqrt(3)}
\pgfmathsetmacro{\y}{2*\cao}
\pgfmathsetmacro{\x}{1.5* \bankinh}
\pgfsetfillcolor{\maumot}
\pgfpathmoveto{\pgfqpoint{-\nuabk mm}{-\cao mm}}
\pgfpathlineto{\pgfqpoint{-\bankinh mm}{0 mm}}
\pgfpathlineto{\pgfqpoint{-\nuabk mm}{\cao mm}}
\pgfpathlineto{\pgfqpoint{\nuabk mm}{\cao mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{0 mm}}
\pgfpathlineto{\pgfqpoint{\nuabk mm}{-\cao mm}}
\pgfpathlineto{\pgfqpoint{-\nuabk mm}{-\cao mm}}
\pgfusepath{fill}
\pgfsetfillcolor{\mauhai}
\pgfpathmoveto{\pgfqpoint{-\x mm}{-\y mm}}
\pgfpathlineto{\pgfqpoint{-\bankinh mm}{-\y mm}}
\pgfpathlineto{\pgfqpoint{-\nuabk mm}{-\cao mm}}
\pgfpathlineto{\pgfqpoint{-\bankinh mm}{0 mm}}
\pgfpathlineto{\pgfqpoint{-\x mm}{0 mm}}
\pgfpathmoveto{\pgfqpoint{\x mm}{-\y mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{-\y mm}}
\pgfpathlineto{\pgfqpoint{\nuabk mm}{-\cao mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{0 mm}}
\pgfpathlineto{\pgfqpoint{\x mm}{0 mm}}
\pgfusepath{fill}
\pgfsetfillcolor{\mauba}
\pgfpathmoveto{\pgfqpoint{-\x mm}{\y mm}}
\pgfpathlineto{\pgfqpoint{-\bankinh mm}{\y mm}}
\pgfpathlineto{\pgfqpoint{-\nuabk mm}{\cao mm}}
\pgfpathlineto{\pgfqpoint{-\bankinh mm}{0 mm}}
\pgfpathlineto{\pgfqpoint{-\x mm}{0 mm}}
\pgfpathmoveto{\pgfqpoint{\x mm}{\y mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{\y mm}}
\pgfpathlineto{\pgfqpoint{\nuabk mm}{\cao mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{0 mm}}
\pgfpathlineto{\pgfqpoint{\x mm}{0 mm}}
\pgfusepath{fill}
\pgfsetfillcolor{\maubon}
\pgfpathmoveto{\pgfqpoint{-\bankinh mm}{\y mm}}
\pgfpathlineto{\pgfqpoint{-\nuabk mm}{\cao mm}}
\pgfpathlineto{\pgfqpoint{\nuabk mm}{\cao mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{\y mm}}
\pgfpathmoveto{\pgfqpoint{-\bankinh mm}{-\y mm}}
\pgfpathlineto{\pgfqpoint{-\nuabk mm}{-\cao mm}}
\pgfpathlineto{\pgfqpoint{\nuabk mm}{-\cao mm}}
\pgfpathlineto{\pgfqpoint{\bankinh mm}{-\y mm}}
\pgfusepath{fill}
}
\begin{tikzpicture}
 \draw[pattern=luc giac mau] (0,0) rectangle (4,1);
 \draw[pattern=luc giac mau,mau mot=gray,mau hai=purple,mau ba=orange,mau bon=pink] (0,2) rectangle (4,3);
\end{tikzpicture}
\end{document}

enter image description here

4
  • Hi, welcome. Your code is not compileable.
    – AndréC
    Commented Oct 26, 2019 at 17:59
  • 1
    Thanks! This is my first post Commented Oct 26, 2019 at 18:03
  • 1
    @ThíchThìLàm: How about adding some comments that explains your code so it can be of help to a broader audience... can you do that?
    – Werner
    Commented Oct 26, 2019 at 18:05
  • 1
    I do not know much English so it is difficult to explain, using google translation to exchange should be a bit difficult. mau mot, mau hai, mau ba, mau bon to change the colors of the hexagons, to change the size of the hexagon Commented Oct 26, 2019 at 18:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .