42

Is there an easy way to draw a triangular grid in TikZ, like this?

1
  • Just a pointer. Sorry for not offering real code. I'd draw it just like there were no grid. Use foreach to draw the three sets of lines.
    – Leo Liu
    Aug 18, 2010 at 12:54

10 Answers 10

36

Like Leo said: use \foreach and some math:

\usetikzlibrary{calc}

\newcommand*\rows{10}
\begin{tikzpicture}
    \foreach \row in {0, 1, ...,\rows} {
        \draw ($\row*(0.5, {0.5*sqrt(3)})$) -- ($(\rows,0)+\row*(-0.5, {0.5*sqrt(3)})$);
        \draw ($\row*(1, 0)$) -- ($(\rows/2,{\rows/2*sqrt(3)})+\row*(0.5,{-0.5*sqrt(3)})$);
        \draw ($\row*(1, 0)$) -- ($(0,0)+\row*(0.5,{0.5*sqrt(3)})$);
    }
\end{tikzpicture}
2
  • 8
    If I'm not mistaken, for an equilateral triangle, those should all be sqrt(3), not sqrt(2). (Though maybe you didn't want an equilateral one, in which case, ignore me.) Aug 19, 2010 at 4:28
  • 13
    Well, that is rather embarrassing. Don't tell anyone! ;)
    – Caramdir
    Aug 19, 2010 at 8:39
38

A funny solution (have you ever used lindenmayersystems library?):

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\begin{document}
\begin{tikzpicture}
  \pgfdeclarelindenmayersystem{triangular grid}{\rule{F->F-F+++F--F}}
  \path[draw=black,
  l-system={triangular grid,step=1cm,
    angle=-60,axiom=F--F--F,order=4,
  }]
  lindenmayer system -- cycle;
\end{tikzpicture}
\end{document}
4
  • Wow, that's pretty clever!
    – Jake
    Jun 26, 2012 at 0:25
  • 2
    Great example of lateral thinking -- congratulations! Jun 26, 2012 at 10:30
  • 8
    The question is not "have you ever used lindenmayersystems library", but "did you even know about it's existence". Very nice! Jun 26, 2012 at 10:42
  • 1
    @TomBombadil How to use TikZ without reading the manual? How to read pgfmanual without reading all chapters? ;-) Jun 26, 2012 at 22:10
16

A slightly different solution using a matrix transformation and clipping:

\newcommand*{\rows}{10}
\pgfmathsetmacro{\xcoord}{cos(60)}
\pgfmathsetmacro{\ycoord}{sin(60)}

\begin{tikzpicture}
    \pgftransformcm{1}{0}{\xcoord}{\ycoord}{\pgfpointorigin} 

    \path[clip,preaction = {draw=black}] (\rows,0) -- (0,0) -- (0,\rows) -- cycle;
    \draw (0,0) grid (\rows,\rows);
    \foreach \x in {1,2,...,\rows} {
        \draw (0,\x) -- (\x,0);
    } 
\end{tikzpicture}
3
  • Very beautiful! Jun 26, 2012 at 0:28
  • 2
    Nice. (nitpick: the last (\rows,0) can be cycle :P)
    – percusse
    Jun 26, 2012 at 9:44
  • Very nice (and very convenient when one needs to draw something on triangular grid).
    – Grigory M
    Dec 8, 2014 at 15:43
6

You could abuse the pgfplots tenary plot feature for this. On the plus side it allows you to easily plot data in that grid.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{ternary}
\begin{document}
\begin{tikzpicture}
  \begin{ternaryaxis}[
    xticklabels={},
    yticklabels={},
    zticklabels={},
    major tick length=0,
    minor tick length=0,
    minor tick num=2,
    every axis grid/.style={},
    grid=both,
    ]
  \end{ternaryaxis}
\end{tikzpicture}
\end{document}

enter image description here

4

Next code defines command \grid which draws a triangular grid made with triangular nodes. \grid's parameter is the number of rows. minimum size in tri/.style is the diameter of triangle's circumscribed circle.

With nodes instead of just lines, it's easier to use the grid as base for nice TiKZ drawings.

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{shapes}

\newcommand{\grid}[1]{
\foreach \i [count=\row from 0, remember=\row as \lastrow (initially 0)] in {0,...,#1}{
    \foreach \j [count=\column from 0, remember=\column as \lastcolumn (initially 0)] in {0,...,\i}{
        \ifnum\row=0
            \node[tri](0-0){0-0};
        \else
            \ifnum\column=0
                \node[tri, anchor=north](\row-0) at (\lastrow-0.corner 2) {\row-0};
            \else
                \node[tri, anchor=north](\row-\column) at (\lastrow-\lastcolumn.corner 3) {\row-\column};
            \fi
        \fi}}
}

\begin{document}
\begin{tikzpicture}[tri/.style={draw=gray, regular polygon, regular polygon sides=3, 
                            minimum size=2cm, inner sep=0pt, outer sep=0pt}]

\grid{5}

\begin{scope}[draw=yellow!30!black, very thick, fill=yellow!80!black]
\filldraw[fill opacity=.7] (5-2.corner 2)--(4-0.corner 1)--(4-1.corner 1)--
         (2-1.corner 1)--(3-2.corner 3)--(4-4.corner 1)--(5-4.corner 2)--cycle;

\draw (4-1.corner 1) -- (4-3.corner 1) (4-2.corner 1)--(2-1.corner 1);
\end{scope}


\end{tikzpicture}

\end{document}

enter image description here

1
  • 1
    Perhaps one should call it \trid instead of \grid ;)
    – Carel
    Aug 25, 2015 at 17:33
4

A MetaPost version, as a complement. It is based on a recursion inspired by Paul Gaborit's use of the lindenmayersystems library. I borrowed much code from my answer to a related question.

Note that at each recursion only the midpoints triangle is drawn, in order not to draw the same segments more than once (which would result in a much thicker rendering of these segments).The main, biggest triangle being drawn only once, before the recursion takes place.

To be run with LuaLaTeX.

\documentclass{article}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
vardef triangular_grid(expr A, B, C, n) = % Recursive macro à la MetaPost
   if n>0:
      save midAC, midBC, midAB; pair midAC, midBC, midAB;
      midAC = .5[A, C]; midBC = .5[B, C]; midAB = .5[A, B];
      triangular_grid(A, midAB, midAC, n-1);
      triangular_grid(midAB, B, midBC, n-1);
      triangular_grid(midBC, midAC, midAB, n-1);
      triangular_grid(midAC, midBC, C, n-1);
      draw midAB--midAC--midBC--cycle;
   fi;
enddef;
beginfig(1);
   u := 14cm; pair A, B, C; A = origin; B =  (u, 0); C = u*dir 60;
   draw A--B--C--cycle; 
   triangular_grid(A, B, C, 4);
endfig;
\end{mplibcode}  
\end{document}

enter image description here

3

At risk of starting a "code golf" war, but in the spirit of "TIMTOWTDI",

\documentclass{standalone}\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[yscale=sqrt(.75),xslant=.5]
\def\n{12}
\clip[preaction=draw](0,0)--(\n,0)--(0,\n)--cycle;
\draw(0,0)grid(\n,\n)[xslant=-1](0,0)grid(\n,\n);
\end{tikzpicture}
\end{document}

If you want to avoid double-drawn grid lines, then line 4 is

\draw(0,0)grid(\n,\n)[xslant=-1](0,0)grid[ystep=\n](\n,\n);

Notes:

  • No point including a picture here, as it looks like those above.
  • Yes, this is similar to answer contributed by @finite
1
  • I am guesing the meaning of TIMTOWTDI Is it in VNese? `
    – Black Mild
    Aug 27, 2023 at 18:58
2

I am eager to join the code party. The question is natural - a kind of should-be-asked one. Below are simple solutions with plain TikZ and Asymptote, based on the same simple idea: the for loop; without using tricks, sin, slant, etc.

enter image description here

TikZ code (use scale=1.5 for scaling as desired)

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[declare function={n=8;}]
\foreach \i[parse=true] in {0,...,(n-1)}
\foreach \j[parse=true] in {0,...,(n-\i-1)}
\draw[shift={(60:\i)},shift={(\j,0)}] (0,0)--(0:1)--(60:1)--cycle;
\end{tikzpicture}
\end{document} 

Combining [shift={($(60:\i)+(\j,0)$)}] is possible with \usetikzlibrary{calc}.

Asymptote code (run on http://asymptote.ualberta.ca/)

size(6cm);
int n=8;
path p=(0,0)--(1,0)--dir(60)--cycle;
for (int i=0; i<n; ++i)
for (int j=0; j<n-i; ++j)
draw(shift(i*dir(60)+(j,0))*p);
1

Probably not the most elegant, but slightly simplified (from my perspective) variant of Caramdir's answer.

\documentclass[10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shapes.misc}

\begin{document}

\newcommand*\gridsize{10}

\begin{figure}[!htb]
\resizebox{\linewidth}{!}{
    \begin{tikzpicture}
        \tikzstyle{every node}=[draw,thin]

        \foreach \a in {1,...,\gridsize}{
            \draw[dotted] (0, 0) -- (\a, 0) -- ({cos(60)*\a}, {sin(60)*\a}) -- cycle;
            \draw[dashed] ({\gridsize-\a}, 0) -- (\gridsize, 0) -- ({\gridsize-cos(60)*(\a)}, {sin(60)*(\a)}) -- cycle;
            \draw[red] ({cos(60)*(\gridsize-\a)}, {sin(60)*(\gridsize-\a)}) -- ({(\gridsize/2)+cos(60)*\a}, {sin(60)*(\gridsize-\a)}) -- ({cos(60)*\gridsize}, {sin(60)*\gridsize}) -- cycle;
        }
    \end{tikzpicture}
}

\caption{Triangular grid}
\end{figure}

\end{document}

Charles Staats contributed to this solution in Drawing scaled triangles with their bottom left corner at the same coordinates in TikZ as I became fixated on using polygons.

1

This is a full-page triangular grid I created recently. My approach was to slant vertical lines in both directions.

\documentclass{article}
\usepackage[margin={0.4in,0.8in}]{geometry}
\usepackage{tikz}
\usepackage{nopageno}

\begin{document}

\pgfmathsetmacro{\cols}{60}
\pgfmathsetmacro{\rows}{55}
\pgfmathsetmacro{\slant}{cot(60)}
\pgfmathsetmacro{\height}{0.5 * \rows * tan(60)}

\begin{tikzpicture}[scale=0.38,rotate=90]
    \clip       (0, 0) rectangle (\cols, \height);
    \draw[gray] (0, 0) rectangle (\cols, \height);

    \pgfmathsetmacro{\from}{-2 *\cols}
    \pgfmathsetmacro{\to}{2 * \cols}
    \foreach\i in {\from, ..., \to} {
        \draw[gray, dotted, xslant=\slant]  (\i, 0) -- (\i, \height);
        \draw[gray, dotted, xslant=-\slant] (\i, 0) -- (\i, \height);
    }

    \foreach\j in {0, ..., \rows} {
        \pgfmathsetmacro{\y}{0.5 * \j * tan(60)}
        \draw[gray, dotted] (0, \y) -- (\cols, \y);
    }
\end{tikzpicture}

\end{document}

Full-page triangular grid

You must log in to answer this question.

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