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 want to create with TikZ a yellow arrow with black margin (border, edge). I thought I could do this by using two arrows which lie on the top of each other, e.g. with:

\documentclass[12pt,twoside, a4paper]{report}
\usepackage{tikz} 
\begin{document}
\begin{tikzpicture}[yscale=0.25]%
\draw[->,black,very thick](-1974*0.107pt,119*0.107pt) -- (-2258*0.107pt,820*0.107pt);%first layer, black arrow
\draw[->,yellow,thick](-1974*0.107pt,119*0.107pt) -- (-2258*0.107pt,820*0.107pt);%second layer, yellow arrow
\end{tikzpicture}%
\end{document}

output of the code

But I am not so satisfied with the result because the black arrow should be a bit longer. I know I could play with the end point coordinates of the black arrow so that it fits well. But if I want to change the coordinates of my black-yellow arrow, this means I have to play again with the coordinates of the black arrow, which would cost a while.

Does anyone have a better solution? I would be glad to hear any hint.:-) Thanks in advance!

share|improve this question
    
What do you think about creating a command with 2 arguments, to produce both arrow at the same time? Something like this: \darrow{(0,0)}{(2,3)}. This command automatically draw the arrows using different widths and colors and end points. –  Sigur Sep 16 '12 at 15:44
add comment

3 Answers

up vote 33 down vote accepted

Edit 1: the new version of double arrow style requires three parameters: the global width and the two colors.

Here is a solution using postaction to define the new style double arrow (I use stealth arrows because doubled default arrows are not beautiful). The postaction option allows to redraw the arrow with different parameters (like shorten > to shorten the ending) :

enter image description here

\documentclass[margin=1mm]{standalone}
\usepackage{tikz}

\tikzset{
  double arrow/.style args={#1 colored by #2 and #3}{
    -stealth,line width=#1,#2, % first arrow
    postaction={draw,-stealth,#3,line width=(#1)/3,
                shorten <=(#1)/3,shorten >=2*(#1)/3}, % second arrow
  }
}

\begin{document}
\begin{tikzpicture}
\draw[double arrow=1pt colored by blue and white]
(0,2) -- (1,1) arc(45:-360+45+90:.5) -- (1.25,2);

\draw[double arrow=3pt colored by blue!50!black and lime,rounded corners]
(1.5,2)  -| (2,0);

\draw[double arrow=7pt colored by black and yellow]
(0,-.1) arc(120:60:.5) arc(-120:-60:.5) -- ++(30:.5);
\end{tikzpicture}%
\end{document}

Edit 2: I created other styles of double arrows: double -latex, double round cap-latex, double -stealth and double round cap-stealth (original double arrow and double -stealth are the same).

Firstly a small bunch:

second example

Then the code (with the four styles of double arrows):

\documentclass[margin=2mm]{standalone}
\usepackage{tikz} 
\usetikzlibrary{arrows}

\tikzset{
  double -latex/.style args={#1 colored by #2 and #3}{    
    -latex,line width=#1,#2,
    postaction={draw,-latex,#3,line width=(#1)/3,shorten <=(#1)/4,shorten >=4.5*(#1)/3},
  },
  double round cap-latex/.style args={#1 colored by #2 and #3}{    
    round cap-latex,line width=#1,#2,
    postaction={draw,round cap-latex,#3,line width=(#1)/3,shorten <=(#1)/4,shorten >=4.5*(#1)/3},
  },
  double round cap-stealth/.style args={#1 colored by #2 and #3}{
    round cap-stealth,line width=#1,#2,
    postaction={round cap-stealth,draw,,#3,line width=(#1)/3,shorten <=(#1)/3,shorten >=2*(#1)/3},
  },
  double -stealth/.style args={#1 colored by #2 and #3}{
    -stealth,line width=#1,#2,
    postaction={-stealth,draw,,#3,line width=(#1)/3,shorten <=(#1)/3,shorten >=2*(#1)/3},
  },
}

\begin{document}
\begin{tikzpicture}
\foreach \size [
evaluate=\size as \width using \size,
evaluate=\size as \bend using (\size-7)*5,
evaluate=\size as \angle using \size*36+180,
evaluate=\angle as \angleplushalf using \angle+18,
] in {1,2,...,10}{
  \draw[double round cap-stealth=\width pt colored by green!50!black and lime]
  (0,0) ++(\angle:1.2) to[bend right=\bend] ++(\angle:3);

  \draw[double round cap-latex=\width pt colored by black and yellow]
  (0,0) ++(\angleplushalf:1.2) to[bend right=\bend] ++(\angleplushalf:3);
}

\foreach \size [
evaluate=\size as \width using \size,
evaluate=\size as \bend using (\size-7)*5,
evaluate=\size as \angle using \size*36,
evaluate=\angle as \angleplushalf using \angle+18,
] in {1,2,...,10}{
  \draw[double -stealth=\width pt colored by blue!50!black and white]
  (0,-9) ++(\angle:1.2) to[bend right=\bend] ++(\angle:3);

  \draw[double -latex=\width pt colored by red and yellow]
  (0,-9) ++(\angleplushalf:1.2) to[bend right=\bend] ++(\angleplushalf:3);
}
\end{tikzpicture}%
\end{document}
share|improve this answer
    
Much better solution than mine for the -stealth arrow type. –  Peter Grill Sep 16 '12 at 16:09
    
@PeterGrill You're right: I cheated to avoid defining a new arrow. ;-) –  Paul Gaborit Sep 16 '12 at 16:17
    
Very nice and even easy solution! Thank you sooo much! I am satisfied to 99% with this solution. I would be satisfied to 100% if the beginning of the arrow would have a black margin too (as in @Peter Grill approach). Do you know if this can be added in an easy way to your code? –  partial81 Sep 17 '12 at 5:45
    
@partial81 I edited my answer to add details... –  Paul Gaborit Sep 17 '12 at 6:06
    
That is indeed fantastic! Thank you first for adapting your solution! And thanks for the other style of double arrows (the .spaced in the 3rd line is not needed?)! They are very nice! I think/hope that a lot of other users will benefit from your solution! Thanks again so much! –  partial81 Sep 18 '12 at 6:30
show 1 more comment

One way would be to use draw=black, double=yellow, double distance=2pt, -> which draws two lines, but the result is not quite what is desired as the arrow does not get the double line:

enter image description here

The second uses the bad to style as discussed in meta arrow tips which provides better results:

enter image description here

Code:

\documentclass{article}
\usepackage{xstring} 
\usepackage{xparse} 
\usepackage{tikz} 
\usetikzlibrary{calc}

\pgfarrowsdeclare{bad to}{bad to}
{
  \pgfarrowsleftextend{-2\pgflinewidth}
  \pgfarrowsrightextend{\pgflinewidth}
}
{
  \pgfsetlinewidth{0.6\pgflinewidth}
  \pgfsetdash{}{0pt}
  \pgfsetroundcap
  \pgfsetroundjoin
  \pgfpathmoveto{\pgfpoint{-3\pgflinewidth}{4\pgflinewidth}}
  \pgfpathcurveto
  {\pgfpoint{-2.75\pgflinewidth}{2.5\pgflinewidth}}
  {\pgfpoint{0pt}{0.25\pgflinewidth}}
  {\pgfpoint{0.75\pgflinewidth}{0pt}}
  \pgfpathcurveto
  {\pgfpoint{0pt}{-0.25\pgflinewidth}}
  {\pgfpoint{-2.75\pgflinewidth}{-2.5\pgflinewidth}}
  {\pgfpoint{-3\pgflinewidth}{-4\pgflinewidth}}
  \pgfusepathqstroke
}

\newcommand*{\LineWidth}{5.0pt}%
\newcommand*{\InnerFactor}{0.60}% percentage shrinkage in line width
\newcommand*{\FudgeFactor}{0.30}% adjust shorten amounts
\NewDocumentCommand{\DoubleArrow}{%
    O{}% #1 = any parmaters to apply to outer drawing (optional)
    O{}% #2 = any parmaters to apply to inner drawing (optional)
    m  % #3 = start of arrow
    m  % #4 = end of arrow
     %  
    }{%
    \pgfmathsetmacro{\InnerLineWidth}{\InnerFactor*\LineWidth}%
    \pgfmathsetmacro{\ShortenAmount}{\FudgeFactor*(\LineWidth-\InnerLineWidth)}%
    %
    \tikzset{outer line style/.style={%
        black,  line width=\LineWidth, -to, #1}
    }%
    \tikzset{inner line style/.style={%
        yellow, line width=\InnerLineWidth, -bad to, 
        shorten >= \ShortenAmount, shorten <= \ShortenAmount, #2}
    }%
    %
    \draw [outer line style] (#3) -- (#4);% outer layer
    \draw [inner line style] (#3) -- (#4);% inner layer
}%

\begin{document}
\begin{tikzpicture}
    \draw [very thick, draw=black, double=yellow, double distance=2pt, ->] (0,1) -- (2,1);
\end{tikzpicture}%

\begin{tikzpicture}
    \DoubleArrow{0,0}{2,0}
    \DoubleArrow[blue][red]{3,0}{4,1}
\end{tikzpicture}%
\end{document}
share|improve this answer
    
That is also a nice solution, although the code was quite difficult to understand. I like it much that your arrows have a black margin at their beginning! But it is a bit complicated and time consuming that one has to type the coordinates each time for the black as for the yellow arrow. Anyway, thanks for this very good approach! –  partial81 Sep 17 '12 at 5:54
    
@partial81: Have defined a macro so that you don't have to repeat the coordinates. –  Peter Grill Sep 17 '12 at 6:51
    
Wow, thanks for defining this macro. Now your solution is very nice and easy to handle too! Thanks a lot! –  partial81 Sep 18 '12 at 6:20
add comment

It is not so beautiful but it works.

\documentclass[12pt,twoside,a4paper]{report}
\usepackage{tikz} 
\newcommand{\darrow}[2]{%
 \draw[->,black,line width=1.6pt] #1 -- #2;
 \draw[->,yellow,line width=1pt,scale=0.98] #1 -- #2;
 }
\begin{document}
\begin{tikzpicture}[yscale=0.25]%
\darrow{(0,0)}{(1,1)}
\end{tikzpicture}%
\end{document}

Or you can use your line width.

share|improve this answer
    
Can you add an image, and the complete code that generates it. I am not quite getting the desired results when I try to use this with \darrow{(0,3)}{(2,3)}. –  Peter Grill Sep 16 '12 at 16:11
    
Please, read below. There are 2 professional solutions. But I'll edit my post. –  Sigur Sep 16 '12 at 16:17
1  
+1 for the attempt... But try your proposition with an arrow between (3,3) and (0,6) for example (scaling is centered at (0,0))! –  Paul Gaborit Sep 16 '12 at 16:25
1  
Thanks for this post! It is a nice try to solve my problem too, but if I change the coordinates of your darrow, I do not always get a nice result. Anyway, thanks for trying to give a solution! –  partial81 Sep 18 '12 at 6:33
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.