14

In the figure below, I would like both segments to have the upward arrow that's currently in the left-hand segment, but I would also like both segments to have the nice round shape that's currently in the right-hand segment.

enter image description here

MWE code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
    \tikzstyle{smallnode}=[circle, inner sep=0mm, outer sep=0mm, minimum size=2mm, draw=black, fill=black];

    \node[smallnode, label={$i$}] (i)   at (0,0) {};
    \node[smallnode, label=below:{$j$}] (j)     at (1.5,-1) {};
    \node[smallnode, label={$k$}] (k)       at (1.5,0) {};
    \node[smallnode, label=below:{$l$}] (l)     at (0,-1) {};

    \draw (i) to[out=180, in=180, edge node={node [sloped,below] {$\leftarrow$}}] (l);
    \draw (k) .. controls ($ (k) +(2,1)$) and ($ (j) +(2,-1)$) .. (j);
\end{tikzpicture}

\end{document}

My problem is that using out/in angles, as in the left segment, doesn't allow flexibility in how "rounded" the curve appears, though it does make it very easy to add the arrow. On the other hand, using Bezier curves, as in the left segment, doesn't seem to allow edge nodes (or does it? -- I tried

\draw (k) to[out=180, in=180, edge node={node [sloped,below] {$\leftarrow$}}] 
          .. controls ($ (k) +(2,1)$) and ($ (j) +(2,-1)$) .. (j);

and a few other syntaxes but couldn't get it).

By the way, I'm a pretty new TikZ user, so if I'm doing anything else silly in this code, please let me know!

  • You can start reading a bit about the tension key if my memory serves me well. – percusse Oct 27 '14 at 15:31
  • 1
    Also looseness. – Manuel Oct 27 '14 at 15:35
  • Thanks. tension seems to apply only to plots. But looseness did the trick. @Manuel, please post as an answer; I'll accept it and post my final code. – LarrySnyder610 Oct 27 '14 at 15:45
  • I didn't even read the question (and I think I don't know the answer), answer it yourself, or wait for someone else. – Manuel Oct 27 '14 at 16:13
18

My final code, based on @Manuel's suggestion:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
    \tikzstyle{smallnode}=[circle, inner sep=0mm, outer sep=0mm, minimum size=2mm, draw=black, fill=black];

    \node[smallnode, label={$i$}] (i)   at (0,0) {};
    \node[smallnode, label=below:{$j$}] (j)     at (1.5,-1) {};
    \node[smallnode, label={$k$}] (k)       at (1.5,0) {};
    \node[smallnode, label=below:{$l$}] (l)     at (0,-1) {};

    \draw (i) to[out=150, in=210, looseness=4, edge node={node [sloped,below] {$\leftarrow$}}] (l);
    \draw (k) to[out=30, in=-30, looseness=4, edge node={node [sloped,above] {$\leftarrow$}}] (j);
\end{tikzpicture}

\end{document}

Result:

enter image description here

7

You can always place a node over the path and attach some label to it:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
    \tikzstyle{smallnode}=[circle, inner sep=0mm, outer sep=0mm, minimum size=2mm, draw=black, fill=black];

    \node[smallnode, label={$i$}] (i)   at (0,0) {};
    \node[smallnode, label=below:{$j$}] (j)     at (1.5,-1) {};
    \node[smallnode, label={$k$}] (k)       at (1.5,0) {};
    \node[smallnode, label=below:{$l$}] (l)     at (0,-1) {};

    \draw (i) to[out=180, in=180, edge node={node [sloped,below] {$\leftarrow$}}] (l);
    \draw (k) .. controls ($ (k) +(2,1)$) and ($ (j) +(2,-1)$) .. (j) node[pos=0.5, inner sep=-1pt, label=right:{$\uparrow$}] {};
\end{tikzpicture}

\end{document}

enter image description here

  • Thanks -- this is a good trick too, but I think looseness is a simpler way to go. – LarrySnyder610 Oct 27 '14 at 16:50
6

Here's a Metapost version for comparison. I've defined the two curves as path variables, so that I can then use the point x of y notation to place a label at a suitable point along the path.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

u = 1/2cm;
z1 = -z2 = (-3/2u,+u);
z3 = -z4 = (+3/2u,+u);

path h[];
h1 = z2 {dir -30} .. {dir 210} z3;
h2 = z4 {dir 210} .. {dir -30} z1;

draw h1; 
draw h2; 

label.rt (btex $\uparrow$ etex, point 0.5 of h1);
label.lft(btex $\uparrow$ etex, point 0.5 of h2);

dotlabel.top(btex $i$ etex, z1);
dotlabel.bot(btex $j$ etex, z2);
dotlabel.top(btex $k$ etex, z3);
dotlabel.bot(btex $l$ etex, z4);

endfig;
end.

However you can make rather sexier arrows by using subpath to draw an arbitrary part of the part shifted sideways a bit, like this:

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(2);
u = 1/2cm;

z1 = -z2 = (-3/2u,+u);
z3 = -z4 = (+3/2u,+u);

path h[];
h1 = z2 {dir -30} .. {dir 210} z3;
h2 = z4 {dir 210} .. {dir -30} z1;

draw h1; 
draw h2; 

drawarrow subpath (0.4,0.6) of h1 shifted 5 right;
drawarrow subpath (0.4,0.6) of h2 shifted 5 left;

dotlabel.top(btex $i$ etex, z1);
dotlabel.bot(btex $j$ etex, z2);
dotlabel.top(btex $k$ etex, z3);
dotlabel.bot(btex $l$ etex, z4);

endfig;
end.
  • Ooh, I like the sexy arrows. I don't use MetaPost but will see whether I can find a way to convert this to TikZ. – LarrySnyder610 Oct 27 '14 at 20:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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