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 tried to create an steady state arrow with pgfarrowsdeclare and pgfsetinnerlinewidth which seems to have no effect, when placed in the arrow declaration. So the following code shows my solution, which is not handy at all.

 \documentclass[border=5mm]{standalone}
    \usepackage{tikz}

    \begin{document}
    \newdimen\arrowsize
    \pgfarrowsdeclare{mya}{mya}{% next two lines do not work as expected. 
    %   \pgfsetinnerlinewidth{3pt} %no effect here
    %   \pgfsetlinewidth{5pt} % works but spreads over every line in the file
    \arrowsize=0.2pt \advance\arrowsize by .5\pgflinewidth %
\pgfarrowsleftextend{-4\arrowsize-.5\pgflinewidth} %
    \pgfarrowsrightextend{.5\pgflinewidth}
     }%
     {%
      \pgfsetlinewidth{1pt}
      \pgfsetdash{}{0pt} % do not dash 
      \pgfsetroundjoin % fix join 
      \pgfsetroundcap   % fix cap
  \pgfpathmoveto{\pgfpoint{-10pt}{12pt}} \pgfpatharc{180}{270}{10pt} %
  \pgfusepathqstroke%
 }

\begin{tikzpicture}
  \node  (n1) at (0,0) {Node1};
  \node(n2)at (0,2) {Node2} ;
  \node(n3)at (0,4) {Node3} ;
%The following code produces correct output
  {\pgfsetinnerlinewidth{3pt} %wont stay local
   \pgfsetlinewidth{5pt} % seems to stay local
   \draw[mya-mya] (n1)--(n2); }
   \pgfsetlinewidth{1pt}
   \draw (n2)--(n3);
\end{tikzpicture}
\end{document}

enter image description here

Is there a way to tell pgf to make an arrow double lined without setting hlinewidth and innerlinewidth manually? In the arrow declaration maybe?

PS I took a short look into the chemfig package and it seems to me that Christian uses several separated paths to construct a double arrow. Maybe that's easier so I will consider that in further approaches.

Edit: Here´s the output produced by

\documentclass[border=5mm]{standalone}

 \usepackage{tikz}


 \begin{document}
        \newdimen\arrowsize
        \pgfarrowsdeclare{mya}{mya}{% next two lines do not work as    expected. 

          \pgfsetinnerlinewidth{4pt} %does sth strange
               \pgfsetlinewidth{5pt} % works but spreads over every 
    %line in the file
            \arrowsize=0.2pt \advance\arrowsize by .5\pgflinewidth%
            \pgfarrowsleftextend{-4\arrowsize-.5\pgflinewidth} %
            \pgfarrowsrightextend{.5\pgflinewidth}
             }%
             {%
              \pgfsetlinewidth{1pt}
              \pgfsetdash{}{0pt} % do not dash 
              \pgfsetroundjoin % fix join 
              \pgfsetroundcap   % fix cap
              \pgfpathmoveto{\pgfpoint{-10pt}{12pt}}\pgfpatharc{180}{270}{10pt} %
             \pgfusepathqstroke}

    \begin{tikzpicture}
      \node  (n1) at (0,0) {Node1};
      \node(n2)at (0,2) {Node2} ;
      \node(n3)at (0,4) {Node3} ;
    %
       \draw[mya-mya] (n1)--(n2);% 
       \draw (n2)--(n3);
    %
    \end{tikzpicture}


    \end{document}

enter image description here

share|improve this question
    
When I uncomment the lines and change the values they certainly do have an effect. Also you might want to see when you draw nodes aligned horizontally. –  percusse Dec 28 '11 at 12:36
    
I´d rather say "not the expected" one. When i play around with the values in \pgfsetinnerlinewidth{Xpt} (in the pgfarrowsdeclare) the arrow get shorter or longer. That looks very curios to me. (or: i don´t understand it). The second issue is, that ` \pgfsetlinewidth{5pt}` isn´t local. –  bloodworks Dec 28 '11 at 13:00
add comment

1 Answer

up vote 5 down vote accepted
+50

You can use double to get the double line. In my opinion this should be kept separately from the arrow definition, since that is meant only to define the tip. An easy solution would be to define a style that sets up the drawing commands for the double lines and create a new arrow tip to match what you have in your example. That leads us to the following:

\documentclass{article}
\usepackage{tikz}
\newdimen\arrowsize
\newdimen\mylw
\pgfkeys{/my arrows/chemeq/.style={draw,thick,double distance=2pt,onearc-onearc}}
\pgfkeys{/my arrows/size/.code={\pgfsetarrowoptions{onearc}{#1}}}
\def\myalw{.4pt}
\pgfarrowsdeclare{onearc}{onearc}{%
  \mylw=\myalw
  \pgfarrowsleftextend{-\pgfgetarrowoptions{onearc}-.5\mylw}
  \pgfarrowsrightextend{0pt}
}{%
  \pgfsetdash{}{0pt}
  \mylw=\pgflinewidth
  \pgfsetlinewidth{\myalw}
  \advance\arrowsize by.5\pgflinewidth
  \pgfpathmoveto{\pgfpoint{-\pgfgetarrowoptions{onearc}}{-\pgfgetarrowoptions{onearc}-.5\mylw}}%
  \pgfpatharc{180}{90}{\pgfgetarrowoptions{onearc}}
  \pgfusepathqstroke
}
\begin{document}
  \begin{tikzpicture}
    \node[draw] (x) at (0,0) {x};
    \node[draw] (y) at (2,0) {y};
    \path[/my arrows/chemeq,/my arrows/size=4pt] (x) -- (y);
    \path[/my arrows/chemeq,/my arrows/size=8pt] (0,1) node[below] {Node 1} -- (0,3) node[above] {Node 2};
  \end{tikzpicture}
\end{document}

Here we use an option on the arrow to set the size of the arc drawn. The option could also be used for, for instance, line width or some minor changes in the shape. If you want to pass multiple options you would have to do some parsing of the single option command you can pass. The result looks like this:

TikZ Chemical Equation Arrows

Update: This shows how you can shorten the notation a bit and pass multiple options to the arrowtip.

\documentclass{article}
\usepackage{tikz}
\newdimen\mylw
\tikzset{chemeq/.style={draw,thick,double distance=2pt,onearc-onearc,/chemeq/size={#1}}}
\tikzset{chemeq/.default={.4pt 6pt}}
\pgfkeys{/chemeq/size/.code={\pgfsetarrowoptions{onearc}{#1}}}
\def\parseopts#1 #2{\xdef\myalw{#1}\xdef\myasize{#2}}
\pgfarrowsdeclare{onearc}{onearc}{%
  {\edef\x{\pgfgetarrowoptions{onearc}}\expandafter\parseopts\x}
  \mylw=\myalw
  \pgfarrowsleftextend{-\myasize-.5\mylw}
  \pgfarrowsrightextend{0pt}
}{%
  \pgfsetdash{}{0pt}
  {\edef\x{\pgfgetarrowoptions{onearc}}\expandafter\parseopts\x}
  \mylw=\pgflinewidth
  \pgfsetlinewidth{\myalw}
  \pgfpathmoveto{\pgfpoint{-\myasize}{-\myasize-.5\mylw}}%
  \pgfpatharc{180}{90}{\myasize}
  \pgfusepathqstroke
}
\begin{document}
  \begin{tikzpicture}
    \node[draw] (x) at (0,0) {x};
    \node[draw] (y) at (2,0) {y};
    \path[chemeq={.8pt 8pt}] (x) -- (y);
    \path[chemeq] (0,1) node[below] {Node 1} -- (0,3) node[above] {Node 2};
  \end{tikzpicture}
\end{document}

It looks pretty much the same, only thearrows on the x-y connection are slightly different. I seriously doubt that it is at all possible to not use the double (you can ofcourse use the TikZ innerlinewidth primitive, but that is doing exactly the same and you won't be able to move those commands into the arrowtip code).

share|improve this answer
    
Hi thanks that will help. I did hope, that those double definitions could go into the arrow tip, cause that would be more handy for me. –  bloodworks Jan 4 '12 at 19:16
    
@bloodworks: Why exactly? If it's just a matter of not writing as much, you can modify the style a bit to make it shorter. –  Roelof Spijker Jan 5 '12 at 8:43
    
its just about accommodativeness. So far i´m quite happy with the solution. –  bloodworks Jan 5 '12 at 12:00
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.