12

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.)

Torbjørn T.
  • 206,688
Ivo
  • 131

5 Answers5

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

Paul Gaborit
  • 70,770
  • 10
  • 176
  • 283
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}
Torbjørn T.
  • 206,688
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

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

Shade
  • 443
  • 2
  • 10
  • 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

Bernard
  • 271,350