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'm having an annoying problem bending an arrow with xypic. I read the part 2.8 of the manual (http://www-bcf.usc.edu/~cautis/tools/xypic.pdf‎) about bending arrows, but could not understand it. Here's the best I could do (UPDATE: the first version is what I had before; the output mysteriously looks different on different runs of LaTeX. The second version is based on a suggestion from a comment below. It's still ugly, but perhaps that's the best I can do?):

\documentclass{article}
\usepackage[all]{xy}

\begin{document}
$$\xymatrix{
A \ar `/40pt[d] `[ddd] [ddd] \\ LongEntry \\ LongEntry \\ LongEntry
} \quad \xymatrix{
A \ar `/40pt[ddd] `/10pt[ddd] [ddd] \\ LongEntry \\ LongEntry \\ LongEntry
}$$
\end{document}

The output looks as follows:

AARGH!

How do I make the ending of the arrow sane? For bonus points, how does one bend arrows in general?

(I'm more interested in an xypic answer, since this is part of a large diagram, but a tikz-cd answer would be nice too if it's particularly clear. The misadventure with this diagram is encouraging me to switch).

share|improve this question
    
Could you add a few properties of this arrow so that one can re-create it most accurate in TikZ? A minimal working example (MWE) would be highly appreciated, too. –  Qrrbrbirlbel Jul 6 '13 at 21:42
    
\ar `/40pt[ddd] `/15pt[ddd] [ddd] seems to do a pretty good job. –  Qrrbrbirlbel Jul 6 '13 at 22:11
    
@Qrrbrbirlbel: Thank you! With your suggestion, I get almost what I want, but the arrow points in the wrong direction. I will post a MWE in a second. –  user21952-is-a-great-name Jul 9 '13 at 0:23

2 Answers 2

up vote 3 down vote accepted

Here are two xy-pic solution.

\documentclass{article}
\usepackage[all]{xy}
\begin{document}
\[\xymatrix{
A \ar `r [r]`[ddd][ddd]&\\ LongEntry \\ LongEntry \\ LongEntry
}
\qquad
\xymatrix{
A \ar `r []+<5em,0cm>`[ddd][ddd]\\ LongEntry \\ LongEntry \\ LongEntry
}\]
\end{document}

The first one is the easier to understand, but you need to add one extra column. Here it is how it works : \ar `r [r]`[ddd][ddd]means that the arrow begin in the rdirection, then goes to [r] (relative coordinate) — hence the need for one extra column — and makes a quarter of turn, then goes to `[ddd] position (relative coordinates) and do another quarter of turn, and finally ends on [ddd] ("absolute" position, i.e. relative to the beginning of the arrow).

The second example avoid to use one extra column and work sensibly the same. The only difference is the use of []_<5em,0em> instead of [r]. But that means : the actual coordinate ([]) plus <5em,0em>.

Finally — for the bonus point and to be complete — the general syntax is

\ar `d1[p1]`d2[p2] ... `dn[pn] [f]

which means : start from here in direction d1 and go to [p1], then take the direction d2 and go to [p2] (relatively from p1), etc, and finally end in [f], where [f] is the position off the end node, relatively from your start node. Usually, d2 to dn are not necessary (and produces ugly results). You can control the direction off the turn with ^d[p]`` or_d[p]. You can also control the radius as in ```d/16pt[p].

N.B. You can also change the tip of arrows with (for example) \usepackage[all,cmtip]{xy} For more explanations you can consult the xy-pic user's guide. If you want more example of diagram in xy-pic with bended arrows, you can look for example at here and here (if I may cite myself).

The results :

Tada

share|improve this answer
    
Thank you! This is exactly what I was looking for. –  user21952-is-a-great-name Jul 15 '13 at 23:46

With a special to path

You can do this with a special to path. I am assuming that this will only be used on nodes (which is true for tikz-cd).

I have included two implementations: One with the calc library (called rl), one without it with plain PGF macros (slightly faster).

The approach is the same. I extract the x and y value of the most right point of the path (the east anchor), then I check which of both x values is greater (more to the right) and add the passed length. This will be the x value of the vertical line part.

The nodes are placed (only) on this vertical part (whereas with the rl path operator below you could nodes along the whole path).

Code

\documentclass[tikz,convert=false]{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\makeatletter
\tikzset{
  RL/.style={% without calc
    rounded corners={#1-.1pt},
    to path={% we asume that you use this path only on nodes (otherwise it will get tricky)
      \pgfextra
        \pgf@process{\pgfpointanchor{\tikztostart}{east}}%
        \pgf@xa\pgf@x\pgf@ya\pgf@y
        \pgf@process{\pgfpointanchor{\tikztotarget}{east}}%
        \pgf@xb\pgf@x\pgf@yb\pgf@y
        \ifdim\pgf@xb>\pgf@xa
          \pgf@xa\pgf@xb
        \fi
        \pgfmathsetlength\pgf@xc{#1}%
        \advance\pgf@xa\pgf@xc
      \endpgfextra
      -- (+\pgf@xa,+\pgf@ya) -- (+\pgf@xa,+\pgf@yb) \tikztonodes -- (\tikztotarget)
    }
  },
  RL/.default=.5cm}
\makeatother
\tikzset{
  rl/.style={% with calc
    rounded corners={#1-.1pt},
    to path={% we asume that you use this path only on nodes (otherwise it will get tricky)
        let \p{@aux1}=(\tikztostart.east),
            \p{@aux2}=(\tikztotarget.east),
            \n{@aux@x}={#1+max(\x{@aux1},\x{@aux2})}
        in
      -- (+\n{@aux@x},+\y{@aux1}) -- (+\n{@aux@x},+\y{@aux2}) \tikztonodes -- (\tikztotarget)
    }
  },
  rl/.default=.5cm,
}
\begin{document}
\begin{tikzcd}
A \arrow[RL]{ddd}\\
LongEntry \\
LongEntry \\
LongEntry
\end{tikzcd}
\begin{tikzcd}
A \arrow[rl]{ddd}\\
LongEntry \\
LongEntry \\
LongEntry
\end{tikzcd}
\end{document}

Path Operator rl

With my paths.ortho (→ another answer) library you can do this very easily.

The path operator rl means that both start and target of a line is connected by a combination of a horizontal, a vertical and a horizontal line. In this case (rl instead of lr) means that the vertical line is to the right of both nodes (or coordinates). I.e first to the right, then down or up, then to the left. The given distance is measured from the node/coordinate that is furthest to the right.

As the paths.ortho already installs a rl style that uses the rl path operator, I’ll ad another RL style that sets an appropriate amount for the rounded corners radius and the rl distance. The -.1pt was necessary so that the arrow tip is placed correctly.

This does not take other nodes in account. So if you have another very long node between start and target you will need to make manual adjustments either way.

Code

\documentclass[tikz,convert=false]{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{paths.ortho}
\tikzset{
  RL/.style={
    rounded corners={#1-.1pt},
    rl distance={#1},
    rl
  },
  RL/.default=.5cm
}
\usepackage[all]{xy}
\begin{document}
\begin{tikzcd}
A \arrow[RL]{ddd}\\
LongEntry \\
LongEntry \\
LongEntry
\end{tikzcd}
\end{document}

Outputs

enter image description here

share|improve this answer
    
Thank you for your answer! Do you know if this would be hard to implement in pure tikz-cd? As nice as your library is, I'm not sure I want to drag around an extra file with my paper... –  user21952-is-a-great-name Jul 9 '13 at 0:20
    
@user21952-is-a-great-name I have added both a PGF and a calc solution. Both of them can easily be adjusted to work for all other directions, too. If you also want to avoid overlapping with nodes between start and target, more work is involved. Will this be needed? –  Qrrbrbirlbel Jul 11 '13 at 0:36
    
Thank you! I appreciate all the different recipes; they will be very useful if I need to make a sufficiently weird arrow in tikz. –  user21952-is-a-great-name Jul 15 '13 at 23:45

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.