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've got

\node (A) at (0,2) {$A$};
\node (B) at (0,0) {$B$}
  edge [<-] (A)
  edge [<-, bend right=90] (A); 

How do I fill this D shape? I've got to use \filldraw, obviously, but I can't figure out how to do the bending.

share|improve this question

3 Answers 3

up vote 12 down vote accepted

It's not easy to give an answer because you don't explain exactly what is the D shape. If you want to fill from A.center and B.center, the answer is not the same. Now it's important to understand why you have a problem.

All the explanations are in the pgfmanual but I will add some examples complete.

The effect of the edge operation is that after the main path the following path is added to the picture:

  \path[every edge,⟨options⟩] (\tikztostart) ⟨path⟩;

Here, ⟨path⟩ is the to path. Note that, unlike the path added by the to operation, the (\tikztostart) is added before the ⟨path⟩ (which is unnecessary for the to operation, since this coordinate is already part of the main path). The \tikztostart is the last coordinate on the path just before the edge operation, just as for the node or to operations. However, there is one exception to this rule: If the edge operation is directly preceded by a node operation, then this just-declared node is the start coordinate (and not, as would normally be the case, the coordinate where this just-declared node is placed – a small, but subtle difference). In this regard, edge differs from both node and to. If there are several edge operations in a row, the start coordinate is the same for all of them as their target coordinates are not, after all, part of the main path. The start coordinate is, thus, the coordinate preceding the first edge operation. This is similar to nodes insofar as the edge operation does not modify the current path at all. In particular, it does not change the last coordinate visited, see the following example:

   \tikzstyle{every edge}=              [draw]  

The edge operation works like a to operation that is added after the main path has been drawn, much like a node is added after the main path has been drawn. This allows each edge to have a different appearance. As the node operation, an edge temporarily suspends the construction of the current path and a new path p is constructed. This new path p will be drawn after the main path has been drawn. Note that p can be totally different from the main path with respect to its options. Also note that if there are several to and/or node operations in the main path, each creates its own path(s) and they are drawn in the order that they are encountered on the path.

 \path ... edge[⟨options⟩] ⟨nodes⟩ (⟨coordinate⟩) ...;

Your code

\node (A) at (0,2) {$A$};
\node (B) at (0,0) {$B$}
  edge [<-] (A)
  edge [<-, bend right=90] (A); 

First I think it's not a good idea to mix creation of nodes and creation of edges and filling of an area. I propose

\begin{tikzpicture}
  \node (A) at (0,2) {$A$};
  \node (B) at (0,0) {$B$};
  \path[<-] (B) edge  (A)
                edge [bend right=90] (A); 
 \end{tikzpicture} 

but more natural is

\begin{tikzpicture}
    \node (A) at (0,2) {$A$};
    \node (B) at (0,0) {$B$};
    \path[->] (A) edge  (B)
                  edge [bend left=90] (B);  
\end{tikzpicture}  

But we can remark despite the use of \path the curve is drawn and each curve have an arrow.

The effect of the edge operation is that after the main path the following path is added to the picture:

 \path[every edge,⟨options⟩] (\tikztostart) ⟨path⟩; 

and

  \tikzstyle{every edge}=              [draw]  

The edge operation creates a new path. This is why the curves are drawn. Options to draw are inherited like ->, thick etc. With \tikzstyle{every edge}= [draw,fill=red]`, you can fill all the areas defined by an edge operation.

An example to see the how works edge

\documentclass{article}  
\usepackage{tikz}  
\usetikzlibrary{backgrounds} 
\begin{document} 
 \tikzstyle{every edge}=  [draw=red]     
  \begin{tikzpicture}[out=90,in=90,relative]
  \node [circle,draw] (a) at (0,0) {a};
  \node [circle,draw] (b) at (1,1) {b};
  \node [circle,draw] (c) at (2,2) {c};
  \draw[->] (a) -- (b) 
            (a) edge (b)
                edge (c)
            (b) -- (c); 
\end{tikzpicture}  

\end{document}

enter image description here

another with fill

\documentclass{article}  
\usepackage{tikz}  
\usetikzlibrary{backgrounds} 
\begin{document} 
 \tikzstyle{every edge}=  [draw=red,fill=blue!20,opacity=.5]     
  \begin{tikzpicture}[out=90,in=90,relative]
  \node [circle,draw] (a) at (0,0) {a};
  \node [circle,draw] (b) at (1,1) {b};
  \node [circle,draw] (c) at (2,2) {c};
  \draw[->] (a) -- (b) 
            (a) edge (b)
                edge (c)
            (b) -- (c); 
\end{tikzpicture}  

\end{document} 

enter image description here

Now I you place the fill command at the beginning of the path. This command is used only for the main path but in your case the main path is not what you want. I think it's a single point. You need to add an option at the edge operation or you need to modify every edge if you want to fill the extra paths that you get with edge.

Now three examples : The first to see how works the options for the main path, the second to see it's possible to use to and the third to fill all the picture.

\documentclass{article}
\usepackage{tikz}  
\usetikzlibrary{backgrounds} 
\begin{document} 



\begin{tikzpicture}
\node (A) at (0,2) {$A$};
\node (B) at (0,0) {$B$};
\draw[->,ultra thick] (A)    edge  (B)
                             edge[ bend left=90,fill=red] (B);
\end{tikzpicture}
\begin{tikzpicture}
\node (C) at (0,2) {$A$};
\node (D) at (0,0) {$B$};
\draw[->] (C)      to  (D);
\draw[->,fill=red] (C) to [ bend left=90] (D);
\end{tikzpicture} 
\begin{tikzpicture}
\node (C) at (0,2) {$A$};
\node (D) at (0,0) {$B$};
\draw[->] (C)      to  (D);
\draw[->] (C) to [ bend left=90] (D);
\begin{scope}[on background layer]
    \path [fill=red!30] (A) to [ bend left=90] (B) -- (B.center)--(A.center)--(A.east);
\end{scope}  
\end{tikzpicture} 
\end{document} 

enter image description here

share|improve this answer

Simply use fill

\documentclass{article}
\usepackage{tikz}
\begin{document}
  \begin{tikzpicture}
\node (A) at (0,2) {$A$};
\node (B) at (0,0) {$B$}
  edge [<-] (A)
  edge [<-, bend right=90,fill=red] (A);
\end{tikzpicture}
\end{document}

enter image description here

Edit A small modification (idea from Altermundus's answer)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\begin{document}
\begin{tikzpicture}
\node[fill=white,inner sep=.5pt] (A) at (0,2) {$A$};
\node [fill=white,inner sep=.5pt] (B) at (0,0) {$B$};
\draw[->] (A)      to  (B);
\draw[->] (A) to [ bend left=90] (B);
\begin{scope}[on background layer]
    \path [fill=red!30] (A) to [ bend left=90] (B) -- (B.center)--(A.center)--(A.east);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
    
I'd like to fill the entire region up to the straight arrow edge. (Actually, I'd really like to fill the left- and right-hand regions on this diagram.) –  Mike Stay May 14 '12 at 0:27
    
Thanks! This backgrounds package looks very helpful. –  Mike Stay May 14 '12 at 18:45

What you're asking for is actually quite complicated. Here's what makes it complicated:

  1. Each edge command defines a whole new path. So the region that you want filled is described by not just physically disjoint paths, but programmatically disjoint paths.
  2. Arrows are only put at path ends, so you really want these paths disjoint when they are drawn.
  3. The region you want to fill is not precisely defined.
  4. When a path is filled, each segment of it is filled independently by joining the start and finish by a straight line.
  5. At least one of the paths is such that the user doesn't really know where it is. (In the given code, it is possible to see what anchors the curved arrow ends up at, but this might not be always true.)

So what you want to do is this: specify some paths and then use them in two different and incompatible ways. A sophisticated method of solving this would be to store the two paths and then produce a new one by "welding" them together. Then the original two paths could be used for the arrows and the welded path for the fill. Doing this is entirely possible (using my spath library), however it's a bit sledgehammer-walnut for this case (and the spath code is decidedly unstable). If you're prepared to specify the two paths again, there's a quick hack that gets what you want.

When specifying the path for filling, we use tos rather than edges. In terms of the path created, these are identical (there's a difference in how the paths are specified due to the fact that to updates the current position but edge does not). The difference is that the resulting object is a single path rather than several. Then what we do is insert a low-level hack which changes all the internal movetos to linetos. This creates a closed path for filling. Then we have to respecify it with the drawing commands.

One draw-back of this is that the nodes are drawn before the path is filled (well, in the example then the A node was always drawn before the path was filled, but now B is as well) which means that it is possible that the filled region overlaps the node text. In this case it doesn't, but if it does one could use layers to put the filled region below the nodes (see "Z-level" in TikZ for few sneaky ways to do that).

Here's the code:

\documentclass{article}
%\url{http://tex.stackexchange.com/q/55739/86}
\usepackage{tikz}

\makeatletter

\let\orig@pgfsyssoftpath@movetotoken=\pgfsyssoftpath@movetotoken
\def\new@pgfsyssoftpath@movetotoken{%
  \let\pgfsyssoftpath@movetotoken=\pgfsyssoftpath@linetotoken
  \orig@pgfsyssoftpath@movetotoken}


\tikzset{
  join with lines/.code={
    \let\pgfsyssoftpath@movetotoken=\new@pgfsyssoftpath@movetotoken
  }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node (A) at (0,2) {$A$};
\node (B) at (0,0) {$B$};
\fill[red,join with lines] (A) to (B) to[<-,bend right=90] (A);
\draw[black] (B) edge[<-] (A) edge[<-,bend right=90] (A);
\end{tikzpicture}
\end{document}

and result:

filled region partially specified

share|improve this answer
    
Thanks! Ultimately I chose his answer because it's the one I ended up using in my paper. I wish I could accept both of them. –  Mike Stay May 14 '12 at 15:31

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.