11

I'm trying to line up a few isosceles triangles, but I cannot get all of them to align at their top (or bottom) properly. Following is the MWE:

\documentclass{article}

\usepackage{tikz}

\usetikzlibrary{shapes,arrows}
\tikzstyle{tri} = [draw, isosceles triangle, shape border rotate=-90,inner sep=0pt, minimum width=4em]

\begin{document}
\begin{center}
\begin{tikzpicture}[node distance=1.8cm,>=latex']
    \node [tri] (gain3) {$4$};
    \node [tri,left of=gain3] (gain2) {$3$};
    \node [tri,left of=gain2] (gain1) {$-2$};
    \node [tri,left of=gain1] (gain0) {$1$};
\end{tikzpicture}
\end{center}
\end{document}

And the result is this: Result: 4 images not properly aligned

And yes, if the minus sign in front of the 2 is dropped, everything lines up properly. How can this be fixed in an elegant way? (i.e., without putting the contents of the triangle nodes inside an \mbox of predefined size, etc.)

  • Add the shape border uses incircle option to each triangle. – Paul Gaborit Mar 19 '18 at 13:56
11

Simple solution

Here is a very simple solution (using the shape border uses incircle option). But this solution is not robust (try with $-245$ instead of $-2$).

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,positioning}
\tikzset{
  tri/.style={
    minimum width=4em,
    draw,
    isosceles triangle,
    shape border uses incircle,
    shape border rotate=-90,
    inner sep=0pt,
  },
}
\begin{document}
\begin{tikzpicture}[node distance=1cm,>=latex']
    \node [tri] (gain3) {$4$};
    \node [tri,left=of gain3] (gain2) {$3$};
    \node [tri,left=of gain2] (gain1) {$-2$};
    \node [tri,left=of gain1] (gain0) {$1$};
\end{tikzpicture}
\end{document}

enter image description here

General solution

The robust solution no longer uses the minimum width option but the text width and align options.

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes,positioning}
\tikzset{
  tri width of/.style={
    draw,
    isosceles triangle,
    shape border uses incircle,
    shape border rotate=-90,
    inner sep=0pt,
    align=flush center,text width={width("#1")},
  },
}
\begin{document}
  \begin{tikzpicture}[node distance=1cm]
    \tikzset{tri2/.style={tri width of=$-2$}}
    \node [tri2] (gain3) {$4$};
    \node [tri2,left=of gain3] (gain2) {$3$};
    \node [tri2,left=of gain2] (gain1) {$-2$};
    \node [tri2,left=of gain1] (gain0) {$1$};
  \end{tikzpicture}
  \begin{tikzpicture}[node distance=1cm]
    \tikzset{tri3/.style={tri width of=$-345$}}
    \node [tri3] (gain3) {$4$};
    \node [tri3,left=of gain3] (gain2) {$3$};
    \node [tri3,left=of gain2] (gain1) {$-345$};
    \node [tri3,left=of gain1] (gain0) {$678$ $-345$};
  \end{tikzpicture}
\end{document}

enter image description here enter image description here

  • Very elegant indeed!! :) – Ivo Mar 19 '18 at 14:14
9

Possibly, the quickest fix is to add text width=2em,align=center to the tri style, this makes the box containing the text the same width in all cases, which gives the same result.

In the code below I made some other changes as well:

output of code

\documentclass{article}

\usepackage{tikz}

\usetikzlibrary{
  shapes.geometric,
  arrows.meta, % supersedes arrows
  positioning
}
\tikzset{
 tri/.style={
   draw,
   isosceles triangle,
   shape border rotate=-90,
   inner sep=0pt,
   text width=2em, % added
   align=center,   % added
   minimum width=4em
 }
}

\begin{document}
\begin{center}
\begin{tikzpicture}[>=Latex]
    \node [tri] (gain3) {$4$};

% alternative, setting anchors explicitly (requires larger node distance)
%    \node [tri,left=of gain3.north, anchor=north] (gain2) {$3$};
%    \node [tri,left=of gain2.north, anchor=north] (gain1) {$-2$};
%    \node [tri,left=of gain1.north, anchor=north] (gain0) {$1$};

    \node [tri,left=of gain3] (gain2) {$3$};
    \node [tri,left=of gain2] (gain1) {$-2$};
    \node [tri,left=of gain1] (gain0) {$1$};
\end{tikzpicture}
\end{center}
\end{document}
  • Very nice. Upvote, also, your answer. – Sebastiano Mar 19 '18 at 13:26
6

One possibility: use the positioning library and anchors.

\documentclass{article}

\usepackage{tikz}

\usetikzlibrary{shapes,arrows,positioning}
\tikzset{tri/.style={draw, isosceles triangle, shape border rotate=-90,inner
sep=0pt, minimum width=4em}}

\begin{document}
\begin{center}
\begin{tikzpicture}[node distance=1.8cm,>=latex']
    \node [tri] (gain3) {$4$};
    \node [tri,left=of gain3.north,anchor=north] (gain2) {$3$};
    \node [tri,left=of gain2.north,anchor=north] (gain1) {$-2$};
    \node [tri,left=of gain1.north,anchor=north] (gain0) {$1$};
\end{tikzpicture}
\end{center}
\end{document}

enter image description here

  • I upvote your answer. But is it possible align the numbers? – Sebastiano Mar 19 '18 at 13:25
  • @Sebastiano This would essentially amount to copying Torbjørn T.'s nice code (which I of course upvoted). – user121799 Mar 19 '18 at 14:09
3

The problem is that $-2$ uses more space. Solved with

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,positioning}
\tikzstyle{tri} = [draw, isosceles triangle, shape border rotate=-90,inner sep=0pt, minimum width=4em,minimum height= 2cm]
\begin{document}
\begin{center}
\begin{tikzpicture}[node distance=1.8cm,>=latex']
    \node (g4) {$4$};
    \node (g3) [left of= g4] {$3$};
    \node (g2) [left of= g3] {$-2$};
    \node (g1) [left of=g2] {$1$};
    \node [tri] at (g4) {};
    \node [tri] at (g3) {};
    \node [tri] at (g2) {};
    \node [tri] at (g1) {};
\end{tikzpicture}
\end{center}
\end{document}

That way, the triangle is seperated from the text.

enter image description here

  • Very nice also your answer. +1. – Sebastiano Mar 19 '18 at 13:30
  • I like to first set everthing properly and then add things. Makes it (IMHO) easier to change things later, although it is more work in the beginning. – Shade Mar 19 '18 at 13:36
  • This solution should've crossed my mind! I did think about separating text from triangle, but thought I'd end up disconnecting their positions. Stupid me :) – Ivo Mar 19 '18 at 14:13
3

A simple hack with makebox:

\documentclass{article}
\usepackage{eqparbox, makebox, mathtools}
\usepackage{tikz}

\usetikzlibrary{shapes,arrows}
\tikzstyle{tri} = [draw, isosceles triangle, shape border rotate=-90,inner sep=0pt, minimum width=4em]

\begin{document}

\begin{center}
\begin{tikzpicture}[node distance=1.8cm,>=latex']
    \node [tri] (gain3) {$4$};
    \node [tri,left of=gain3] (gain2) {$3$};
    \node [tri,left of=gain2] (gain1) {\makebox[0.6em]{$-2$}};
    \node [tri,left of=gain1] (gain0) {$1$};
\end{tikzpicture}
\end{center}

\end{document} 

enter image description here

  • Vote +1 also your answer. :-) good all answers. – Sebastiano Mar 19 '18 at 13:47
  • Appreciate the answer, but I explicitly mentioned that I did not want to make use of spacing tweaks using \mbox. – Ivo Mar 19 '18 at 14:11
  • Sorry, I didn't see that. – Bernard Mar 19 '18 at 14:17

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.