Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have found that I cannot make decorations apply to (most) curves drawn using the "to" path operation. Here is a working example:

\documentclass[a4paper, reqno]{amsart}

\usepackage{tikz}
\usetikzlibrary{decorations.markings, topaths}

\makeatletter
\tikzset{nomorepostaction/.code = \let\tikz@postactions\pgfutil@empty}
\makeatother
\tikzset{bigdiagramarrow/.style = {
    decoration = {markings, mark = at position 1 with {\arrow[thick]{latex}}},
    postaction = {nomorepostaction, decorate}
}}

\begin{document}
    \begin{tikzpicture}
        \node [draw] (A) at (0, 0) {$A$};
        \node [draw] (B) at (0, 1) {$B$};
        \node [draw] (C) at (2, 1) {$C$};
        \draw [bigdiagramarrow] (A) -- (B);
        \draw [out = 0, in = 180, bigdiagramarrow] (A) to (C);
    \end{tikzpicture}
\end{document}

Here is what I get when I compile it:

As you can see, an arrowhead is drawn on the end of the path drawn using the -- path operation, but no arrowhead is drawn on the end of the path drawn using the to path operation.

Strangely, in the document in which I encountered this issue, I found that some curves created using the "to" path operation will display the decoration. To be more precise, 3 of the 12 curves in the document I am actually trying to typeset display the decoration. It is the same 3 every time I compile the document. I do not know what sets these 3 apart from the rest.

At first it appeared that this question might be relevant, but I do not appear to be encountering the same "gotcha" so far as I can see, since I am not passing options to the to path operation but rather to the \draw macro.

NB. The nomorepostaction key comes from Ulrich Schwarz's answer to this question.

share|improve this question
    
It works with at position .9999. –  Qrrbrbirlbel Jan 4 '13 at 3:53
    
\draw (A) and (A) to (C) are two distinct paths. So you are not doing anything to the to path as it is. –  percusse Jan 4 '13 at 4:02
    
    
@percusse And \draw [bigdiagramarrow] (A) to (B);? –  Qrrbrbirlbel Jan 4 '13 at 4:09
    
@Qrrbrbirlbel The same –  percusse Jan 4 '13 at 4:10
show 3 more comments

2 Answers

up vote 7 down vote accepted

I found two more or less appropriate ways to change the arrow size (which is not a solution of the actual problem at hand, namely that at position 1 is not calculated correct):

  • less appropriate:
    • New arrow head: _latex
    • New style: arrow line width that takes a length (the new \pgflinewidth)
    • and arrow ultra thin, arrow very thin, …, arrow ultra thick that set arrow line width
  • more appropriate:
    • Re-defining a macro that locally (!) sets a new line width for the arrows.
    • New style: arrow line width that takes a factor
    • and arrow ultra thin, arrow very thin, …, arrow ultra thick that set arrow line width

(They could even be combined.)

less appropriate:  New Arrow Head

I chose to define a new arrow _latex that is the same as latex only that \pgflinewidth is replaced by \pgflinewidth@arrow.

The length \pgflinewidth@arrow is per default \pgflinewidth so the arrow acts as usual unless the key arrow line width is used explicitly with an arbitrary length. (Sadly, thick and so on cannot be used, but arrow thick.)

Improvements could be made that one could use the already existing arrows without any change by finding a good hook to set \pgflinewidth locally.

For many other way to change the arrow size: Is it possible to change the size of an arrowhead in TikZ/PGF?

Code

\documentclass[tikz,border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\makeatletter
\tikzset{nomorepostaction/.code = \let\tikz@postactions\pgfutil@empty}
\newdimen\pgflinewidth@arrow
\pgfarrowsdeclare{_latex}{_latex}
{
  \pgfutil@tempdima=0.28pt%
  \pgfutil@tempdimb=\pgflinewidth@arrow%
  \ifdim\pgfinnerlinewidth>0pt%
    \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth@arrow-.4*\pgfinnerlinewidth}%
  \fi%
  \advance\pgfutil@tempdima by.3\pgfutil@tempdimb%
  \pgfarrowsleftextend{+-1\pgfutil@tempdima}
  \pgfarrowsrightextend{+9\pgfutil@tempdima}
}
{
  \pgfutil@tempdima=0.28pt%
  \pgfutil@tempdimb=\pgflinewidth@arrow%
  \ifdim\pgfinnerlinewidth>0pt%
    \pgfmathsetlength\pgfutil@tempdimb{.6\pgflinewidth@arrow-.4*\pgfinnerlinewidth}%
  \fi%
  \advance\pgfutil@tempdima by.3\pgfutil@tempdimb%
  \pgfpathmoveto{\pgfqpoint{9\pgfutil@tempdima}{0pt}}
  \pgfpathcurveto
  {\pgfqpoint{6.3333\pgfutil@tempdima}{.5\pgfutil@tempdima}}
  {\pgfqpoint{2\pgfutil@tempdima}{2\pgfutil@tempdima}}
  {\pgfqpoint{-1\pgfutil@tempdima}{3.75\pgfutil@tempdima}}
  \pgfpathlineto{\pgfqpoint{-1\pgfutil@tempdima}{-3.75\pgfutil@tempdima}}
  \pgfpathcurveto
  {\pgfqpoint{2\pgfutil@tempdima}{-2\pgfutil@tempdima}}
  {\pgfqpoint{6.3333\pgfutil@tempdima}{-.5\pgfutil@tempdima}}
  {\pgfqpoint{9\pgfutil@tempdima}{0pt}}
  \pgfusepathqfill
}

\tikzset{
    bigdiagramarrow/.style = {
        -_latex,
        arrow thick
    },
    arrow line width/.code={
        \pgfmathsetlength\pgflinewidth@arrow{#1}
    },
    arrow line width/.initial=\pgflinewidth,
    arrow ultra thin/.style={arrow line width=0.1pt},
    arrow very thin/.style={arrow line width=0.2pt},
    arrow thin/.style={arrow line width=0.4pt},
    arrow semithick/.style={arrow line width=0.6pt},
    arrow thick/.style={arrow line width=0.8pt},
    arrow very thick/.style={arrow line width=1.2pt},
    arrow ultra thick/.style={arrow line width=1.6pt},
}
\makeatother
\begin{document}
    \begin{tikzpicture}
        \node [draw] (A) at (0, 0) {$A$};
        \node [draw] (B) at (0, 1) {$B$};
        \node [draw] (C) at (2, 1) {$C$};
        \draw [bigdiagramarrow] (A) to (B);
        \draw [out = 0, in = 180][bigdiagramarrow] (A) to (C);
    \end{tikzpicture}
\end{document}

Output

enter image description here

more appropriate:

Code

\documentclass[tikz,border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\makeatletter
\tikzset{nomorepostaction/.code = \let\tikz@postactions\pgfutil@empty}
\def\pgf@arrowset#1#2{%
  \pgfutil@ifundefined{pgf@arrow@code@#2}
  {\PackageError{pgf}{Arrow #1 type ``#2'' unknown}{}}
  {%
    \edef\pgf@arrow@temp{#2}%
    \ifx\pgf@arrow@temp\pgfutil@empty% ah. clear!
      \expandafter\let\csname pgf@#1arrow\endcsname=\pgfutil@empty%
      \expandafter\let\csname pgf@shorten@#1\endcsname=\pgfutil@empty%
    \else%
      %\pgf@arrow@prepare{#2}%
      \expandafter\def\csname pgf@#1arrow\endcsname{\multiply\pgflinewidth by \pgflinewidth@arrow\relax\pgf@arrow@call{#2}}%
      \expandafter\edef\csname pgf@shorten@#1\endcsname{\multiply\pgflinewidth by \noexpand\pgflinewidth@arrow\relax\expandafter\noexpand\csname pgf@arrow@right@#2\endcsname}%
    \fi%
  }%
}
\tikzset{
    bigdiagramarrow/.style = {
        -latex,
        arrow thick
    },
    arrow line width/.code={
        \pgfmathsetmacro\pgflinewidth@arrow{#1}
    },
    arrow line width=1,
    arrow ultra thin/.style={arrow line width=0.25},
    arrow very thin/.style={arrow line width=0.5},
    arrow thin/.style={arrow line width=1},
    arrow semithick/.style={arrow line width=1.5},
    arrow thick/.style={arrow line width=2},
    arrow very thick/.style={arrow line width=3},
    arrow ultra thick/.style={arrow line width=4},
}
\makeatother
\begin{document}
    \begin{tikzpicture}
        \node [draw] (A) at (0, 0) {$A$};
        \node [draw] (B) at (0, 1) {$B$};
        \node [draw] (C) at (2, 1) {$C$};
        \draw [bigdiagramarrow] (A) to (B);
        \draw [out = 0, in = 180][bigdiagramarrow] (A) to (C);
    \end{tikzpicture}
\end{document}

Output

enter image description here

share|improve this answer
    
Thank you very much. Your approach of creating a new arrow style proves to be a much more effective way of doing this. With the decorations approach, I was finding that the end of the curve would enter the arrow head askew, which is quite ugly. I am grateful for the effort you appear to have put into this. –  Hammerite Jan 4 '13 at 5:20
    
@Hammerite I have updated my answer with a solution I found more fitting, as it doesn’t rely on new arrow heads. (One could even combine both solutions.) –  Qrrbrbirlbel Jan 4 '13 at 6:17
    
Your second and preferred method doesn't compile for me. It says ! Undefined control sequence. \pgf@shorten@end ...ewidth by \pgflinewidth@arrow <linebreak> \relax \pgf@arrow@right@ti... –  Hammerite Jan 4 '13 at 21:29
    
Wait a minute, if I just copy and paste your code into a file it does compile. but if I put it in the preamble of the document I'm working on I get that error. It must be interfering with something else in the document. –  Hammerite Jan 4 '13 at 21:41
    
I worked out what the problem is. If you attempt to use arrow styling without specifying the arrow size, it gets confused. –  Hammerite Jan 4 '13 at 23:10
show 3 more comments

Why to adapt a simple way when there are complex methods?

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
        \node [draw] (A) at (0, 0) {$A$};
        \node [draw] (B) at (0, 1) {$B$};
        \node [draw] (C) at (2, 1) {$C$};
        \draw [-latex] (A) -- (B);
        \draw [out = 0, in = 180, -latex] (A) to (C);
    \end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.