TikZ-PGF Arrows – Easy Method to Place Arrow Tips Outside Drawn Line

tikz-arrowstikz-pgf

I regularly need to represent mathematical intervals, and I find annoying to have to manually tweak the opened brackets (see MWE below).

Is there any way to :

  • define a new arrow tip that starts at the end of the line and extends further (thus exceeding the start and/or stop coordinates) ;
  • having this new arrow tip scalable, to avoid ugly rendering like the one of the MWE ;
  • bonus : having transparency group included by design in the code.

I've searched here, and finally found TikZ: Precisely controlling arrow tip position, but the syntax has changed and I'm not skilled enough to adapt it to the new one.

\documentclass{article}
\usepackage{tikz, amssymb}
\usetikzlibrary{arrows.meta}


\begin{document}
     \tikzset{
        interv oo/.style={{Bracket[reversed, sharp, length=.75ex]}-{Bracket[reversed, sharp, length=.75ex]}, shorten <=-.75ex, shorten >=-0.75ex},
        interv of/.style={{Bracket[reversed, sharp, length=.75ex]}-{Bracket[sharp, length=.75ex]}, shorten <=-.75ex},
        interv fo/.style={{Bracket[sharp, length=.75ex]}-{Bracket[reversed, sharp, length=.75ex]}, shorten >=-0.75ex},
        interv ff/.style={{Bracket[sharp, length=.75ex]}-{Bracket[sharp, length=.75ex]}},
        interv oi/.style={{Bracket[reversed, sharp, length=.75ex]}-, shorten <=-.75ex},
        interv io/.style={-{Bracket[sharp, length=.75ex]}, shorten >=-0.75ex},
        interv fi/.style={{Bracket[sharp, length=.75ex]}-},
        interv if/.style={-{Bracket[sharp, length=.75ex]}},
        label/.style={below, font=\footnotesize} }
    
    \begin{tikzpicture}
        \draw (-3,0) -- (3,0) node[anchor=south] {$\mathbb{R}$};
        \foreach \x in {-1,0,1} \draw (\x,2pt) -- (\x, -2pt) node[anchor=north] {$\x$};
        \begin{scope}[opacity=.5, transparency group]
            \draw[line width=3pt, blue, interv oo] (-1,0) -- (1,0);
        \end{scope}
    \end{tikzpicture}
\end{document}

enter image description here

Many thanks in advance.


Edit : here is what I finally came to. Seems satisfying enough to me. With usage of tabularray that was just put to my knowledge.

\documentclass[12pt,a4paper]{book}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{mathpazo}
\usepackage{geometry}
\usepackage[french]{babel}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, arrows}
\usepackage{tabularray}
\frenchbsetup{StandardLists=true}   % Resolves conflict between babel and enumitem

\geometry{
    top=1.5cm, bottom=1.5cm, left=1cm, right=1cm,
    headheight=1cm, headsep=0.5cm,
    footskip=1cm}

\setlength{\parindent}{0mm} % No paragraphe indentation

\begin{document}
    
    \tikzset{
        interv oo/.style={{Bracket[reversed, sharp, length=0pt 2, sep=0pt -1.5]}-{Bracket[reversed, sharp, length=0pt 2, sep=0pt -1.5]}},
        interv of/.style={{Bracket[reversed, sharp, length=0pt 2, sep=0pt -1.5]}-{Bracket[sharp, length=0pt 2]}},
        interv fo/.style={{Bracket[sharp, length=0pt 2]}-{Bracket[reversed, sharp, length=0pt 2, sep=0pt -1.5]}},
        interv ff/.style={{Bracket[sharp, length=0pt 2]}-{Bracket[sharp, length=0pt 2]}},
        interv oi/.style={{Bracket[reversed, sharp, length=0pt 2, sep=0pt -1.5]}-},
        interv io/.style={-{Bracket[reversed, sharp, length=0pt 2, sep=0pt -1.5]}},
        interv fi/.style={{Bracket[sharp, length=0pt 2]}-},
        interv if/.style={-{Bracket[sharp, length=0pt 2]}},
        label/.style={below, font=\footnotesize} }
    
    Compléter le tableau suivant:

    \begin{tblr}{hlines, vlines,
                cell{2-5}{1,4}={mode=dmath},
                colspec={X[1,c,m] X[3,c,m] X[2.2,c,m] X[1.2,c,m]},
                rowsep=10pt,
                row{1} = {font=\bfseries, rowsep=4pt},
            }
        Inégalité & Phrase & Représentation graphique & Intervalle \\

        \ldots x\ldots & {$x$ est un réel\\ strictement supérieur à $-2$\\ et strictement inférieur à $4$} & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
                % Bornes
                \def\xm{-4.9}
                \def\xM{-\xm}
                % Intervalle
                \draw[line width=4.5pt, green, interv oo] (-2,0) -- (4,0) ;
                % Repère
                \draw[thick,->] (\xm,0) -- (\xM,0) ;
                \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
                \node[label] at (0,0) {0} ;
                \node[label] at (1,0) {1} ;
                \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & x\in\ldots \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \draw[line width=2.5pt, red, interv of] (-2,0) -- (4,0) ;
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \draw[line width=2.5pt, orange, interv fo] (-2,0) -- (4,0) ;
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \draw[line width=2.5pt, yellow!70!orange, interv ff] (-2,0) -- (4,0) ;
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \begin{scope}[transparency group, opacity=.5]
                \draw[line width=2.5pt, cyan, interv oi] (-2,0) -- (\xM,0) ;
            \end{scope}
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \draw[line width=2.5pt, purple, interv io] (\xm,0) -- (4,0) ;
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \begin{scope}[transparency group, opacity=.5]
                \draw[line width=2.5pt, gray, interv fi] (-2,0) -- (\xM,0) ;
            \end{scope}
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    
        & & \begin{tikzpicture}[scale=0.5, >=stealth, baseline={([yshift=-.5ex]current bounding box.center)}]
            % Bornes
            \def\xm{-4.9}
            \def\xM{-\xm}
            % Intervalle
            \begin{scope}[transparency group, opacity=.5]
                \draw[line width=2.5pt, blue!50!white, interv if] (\xm,0) -- (4,0) ;
            \end{scope}
            % Repère
            \draw[thick,->] (\xm,0) -- (\xM,0) ;
            \foreach \x in {-4,...,4} { \draw (\x, -2mm) -- ++(0, 4mm) ; }
            \node[label] at (0,0) {0} ;
            \node[label] at (1,0) {1} ;
            \node[label, above, white] (0,0) {0} ; % Pour équilibrer le dessin verticalement
        \end{tikzpicture} & \\
    \end{tblr}

\end{document}

enter image description here

Best Answer

You can do that with the sep option(moves the arrow head away from the endpoint coordinate of the line) - it uses the same syntax as length. If you want absolute length of the head, you can change 0pt 1 back to .75ex (or maybe use em or pt for a horizontal distance)

\documentclass[tikz, border=1 cm]{standalone}
\usepackage{amssymb}
\usetikzlibrary{arrows.meta}
\begin{document}
     \tikzset{
        interv oo/.style={{Bracket[reversed, sharp, length=0pt 1, sep=0pt -1]}-{Bracket[reversed, sharp, length=0pt 1, sep=0pt -1]}},
}    
    \begin{tikzpicture}
        \draw (-3,0) -- (3,0) node[anchor=south] {$\mathbb{R}$};
        \foreach \x in {-1,0,1} \draw (\x,2pt) -- (\x, -2pt) node[anchor=north] {$\x$};
        \begin{scope}[opacity=.5, transparency group]
            \draw[line width=5pt, blue, interv oo] (-1,0) -- (1,0);
        \end{scope}
    \end{tikzpicture}
\end{document}

Line with brackets