16

I am still learning to use TikZ and now I find myself in a tight spot.

I want to draw three processes on the lhs and one on the rhs. These processes are represented by a circle. I then want three arrows comming from the lhs to merge in the space between and go to the process on the rhs.

Further more I would like the arrow from the bottom one to be dotted at the midway.

I have the following to create the four processes and join them with arrows, but how do I merge them in between

\begin{tikzpicture}
  \tikzstyle{every node}=[draw,shape=circle]; 
  \node (P0) at (0,  0.0) {$P_0$};
  \node (P1) at (0, -1.0) {$P_1$};
  \node (Pn) at (0, -2.5) {$P_n$};

  \node (Q) at (2, -1) {$Q$};

  \draw [dotted] (P1) -- (Pn);
  \draw [->] (P0) -- (Q);
  \draw [->] (P1) -- (Q);
  \draw [->] (Pn) -- (Q);
\end{tikzpicture}

My very bad hand drawing from Google Drawing can be seen below

enter image description here

4 Answers 4

15

Changing the line type along a path is not so easy, so I guess it's not worth to implement it if this is the only place to apply. A quick fix can be applied by the following:

\begin{tikzpicture}[every node/.style={draw,circle}]
\draw[style=help lines] (-1cm,0cm) grid[step=1cm] (5cm,5cm);% remove later
  \node (P0) at (0, 4cm) {$P_0$};
  \node (P1) at (0, 2.5cm) {$P_1$};
  \node (Pn) at (0, 1cm) {$P_n$};

    \node (Q) at (3.5cm, 2.5cm) {$Q$};
    \coordinate (Qf) at ([xshift=-0.5cm]Q.west); % we collect the edges in front of Q

\draw (P0) .. controls (2,4) and (1,2.5) .. (Qf) -- (Q); % (Q) is for a better line join
\draw (P1) -- (Qf);
\draw[->] (Qf) -- (Q); % the arrow
\draw  (Qf) arc (90:150:1cm) coordinate (temp1); %We stop and change line type
\draw[dashed] (temp1) arc (-45:-80:2cm and 3.5cm) coordinate (temp2); % Again
\draw (temp2) -- (Pn);

\end{tikzpicture}

enter image description here

Now I see that there is a space between Pn and the rest, but that can be fixed by changing the arc specs.

1
  • Thanks! I have posted what I ended up doing in a post below Commented Mar 19, 2012 at 20:18
13

The lines in percusse's answer look slightly skewed because the upper one uses bezier splines and the lower one uses circle segments. In an attempt to fix that, I modified his code to use the same operation for both paths for symmetry.

Edit: By inverting the clip path it is possible to draw the dashed and the solid parts separately without overlap. Thanks to percusse for pointing this out. I also replaced the clipping rectangles with circles to achieve nicer transitions.

Resulting image

Here's the not-so-Minimal Working Example that that yields the above image.

\documentclass{article}
\usepackage{tikz}

% See tex.stackexchange.com/questions/12010/
\tikzstyle{reverseclip}=[insert path={
    (current page.north east) rectangle (current page.south west)
}]

\begin{document}
\begin{tikzpicture}[
        remember picture, % Needed for inverted clip path. Be careful!
        every node/.style={draw,circle}
    ]
    \node (P0) at (0, 4) {$P_0$};
    \node (P1) at (0, 2.5) {$P_1$};
    \node (Pn) at (0, 0) {$P_n$};

    \node (Q) at (3.5cm, 2.5cm) {$Q$};
    \coordinate (Qf) at ([xshift=-0.5cm]Q.west);

    % Draw solid lines
    \draw[->] (P1) -- (Q);
    \draw[in=180,out=0] (P0) to (Qf);

    \newcommand\clippath{% Just for convenience
        (Pn) circle (1.1)   (Qf) circle (1.1)
    }

    % Draw dashed part of the line
    \begin{scope}
        % To make sure our clipping path does not mess up
        % the placement of the picture.
        \begin{pgfinterruptboundingbox}
            \clip \clippath [reverseclip];
            % Note: it is possible to save the scope and put
            % the draw command here.  But _only_ if you know
            % that it will not stick out of the bounding box.
        \end{pgfinterruptboundingbox}

        \draw[dashed,in=180,out=0] (Pn) to (Qf);
    \end{scope}

    % Draw solid part of the line
    \begin{scope}
        \clip \clippath;
        \draw[in=180,out=0] (Pn) to (Qf);
    \end{scope}
    % Draw more unclipped stuff here
\end{tikzpicture}
\end{document}

By replacing \clip with \clip[draw] you can see how this effect is achieved:

Result with clip path shown

0
6

Another answer

\begin{tikzpicture}[every node/.style={draw,circle}]
  \draw[style=help lines] (-1cm,0cm) grid[step=1cm] (5cm,5cm);% remove later
  \node (P0) at (0, 4cm) {$P_0$};
  \node (P1) at (0, 2.5cm) {$P_1$};
  \node (Pn) at (0, 1cm) {$P_n$};

  \node (Q) at (3.5cm, 2.5cm) {$Q$};
  \coordinate (Qf) at ([xshift=-0.5cm]Q.west); % we collect the edges in front of Q

  \draw (P0) to [out=0,in=180] (Qf); % (Q) is for a better line join
  \draw[-latex] (P1) -- (Q);
  \path (Pn) to [out=0,in=180] coordinate[pos=0.3](aa) coordinate[pos=0.7](bb)(Qf);
  \draw (Pn) to[out=0,in=-135](aa);
  \draw[dashed](aa) to [out=45,in=-135] (bb);
  \draw(bb) to[out=45,in=180] (Qf);
\end{tikzpicture}

enter image description here

2

After some fiddling around I ended up using percusse's idea:

\begin{tikzpicture}[every node/.style={draw,circle}]
  \node (P1) at (0,  0.0) {$P_1$};
  \node (P2) at (0, -1.0) {$P_2$};
  \node (Pn) at (0, -2.5) {$P_n$};

  \node (Q) at (2.5, -1)  {$Q$};

  \draw [dotted, shorten >=2pt, shorten <=2pt] (P2) -- (Pn);

  % Straight line from P2 to Q
  \draw [->] (P2) -- (Q);

  % Downwards smooth line from P1 to Q
  \draw [shorten <=2pt] (P1) to [out=0,in=90] (0.75, -0.5);
  \draw (0.75, -0.5) to [out=270,in=180] (1.5, -1);

  % Upwards smooth line from Pn to Q, with dotted middle
  \draw [shorten <=2pt] (Pn) to [out=0,in=270] (0.75, -2);
  \draw [dotted] (0.75, -2) to (0.75, -1.5);
  \draw (0.75, -1.5) to [out=90,in=180] (1.5, -1); 
\end{tikzpicture}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .