# Arrows from cloud cross the outer line

I'm using TikZ to draw a cloud. Also I'm drawing arrows from the cloud to some nodes. But the startpoints of the arrows are in or outside the cloud but not exactly on the outer line. I think the picture shows my problem:

As well here is an MWE:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}
\node[cloud, cloud puffs=15.7, minimum width=3cm, draw] (cloud) at (0,0) {Cloud};
\path[->] (cloud) edge (2, 2)
(cloud) edge (2, 1);
\end{tikzpicture}
\end{document}


As you may think by yourself my question is how to position the start points of the arrows on the line of the cloud.

-
It's due to the fractional numbers of puffs. –  percusse Jan 11 '13 at 13:38
I thought that as well. But is there a simple possibility to position the start points correctly? –  Dave Jan 11 '13 at 13:53

You can either use an integer number of puffs or the intersections library and find the points manually.

Notes:

• I used named coordinates for (2,1) and (2,2) to not repeat hard-coded coordinates.
• The anchor .center is neede because in the second example (the one to (2,1)) the (cloud) -- (2,1) does not intersect with the cloud’s border.

## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes,intersections}
\begin{document}
\begin{tikzpicture}
\node[
name path=cloud,
cloud, cloud puffs=15.7,
minimum width=3cm, draw,
] (cloud) at (0,0) {Cloud};
\path[name path=path22] (cloud.center) -- (2, 2) coordinate (to22);
\path[name path=path21] (cloud.center) -- (2, 1) coordinate (to21);
\draw[->,
name intersections={of=cloud and path22,name=from22},
name intersections={of=cloud and path21,name=from21}
] (from22-1) edge (to22)
(from21-1) to   (to21);
\end{tikzpicture}
\end{document}


## Output

-
Thank you very much for this simple solution. I think I will simply use an integer numer ;-) –  Dave Jan 11 '13 at 22:24

Of course Qrrbrbirlbel answer is the right one, but I cannot resist to post this cheat idea: draw the cloud shape after the rays, and use white fill. This solution is much simpler if you have lots of rays to draw.

\documentclass[tikz]{standalone}
\begin{document}
\usetikzlibrary{shapes}
\begin{tikzpicture}
\coordinate (cloud) at (0,0);
\foreach \angle in {0,15,...,360}
\draw[->] (cloud) -- (\angle:2);
\node[cloud, cloud puffs=15.7, minimum width=3cm, draw,
fill=white] (cloud) at (cloud) {Cloud};
\end{tikzpicture}
\end{document}


# Output

-
Try something like \foreach \angle in {0,1,...,360}\draw (cloud) -- (\angle:2); (cloud being the node not the coordinate!) and you will see that only the upper right part of the cloud (the asymmetric one due to the non-integer number of puffs) is the problem. The cloud puffs=15 border is clearly visible. –  Qrrbrbirlbel Jan 11 '13 at 15:14
@Qrrbrbirlbel Right! Nice demonstration indeed. –  JLDiaz Jan 11 '13 at 15:18
@JLDiaz Thanks for the solution :-) –  Dave Jan 11 '13 at 22:25

@Dave I never even thought of a non-integer number of puffs. You've stumbled on something that shouldn't work, but does. Obviously Qrrbrbirlbel provides the proper solution. But for fans of impenetrable hacking, here's something that also shouldn't work, but does:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes.symbols}
\usepgflibrary{intersections}
\begin{document}

\makeatletter

% Save the original background path definition.
\let\pgf@sh@bg@cloud@original=\pgf@sh@bg@cloud

% Redefine the cloud background path.
\def\pgf@sh@bg@cloud{%
% Draw the original path.
\pgf@sh@bg@cloud@original%
% Now save it globally.
\pgfgetpath\tmp@path%
% NB this will NOT work with early PGF versions as this
% relies on \pgf@node@name
\expandafter\global\expandafter%
\let\csname pgf@sh@bg@path@saved@\pgf@node@name\endcsname=\tmp@path%
}

% Now redefine the cloud anchor border.
% NB Outer sep is NOT taken into account.
\def\pgf@anchor@cloud@border#1{%
\pgfextract@process\externalpoint{#1}%
%
\pgfintersectionofpaths{%
% Set the transform of the current referenced node.
\pgfsettransform{\csname pgf@sh@nt@\pgfreferencednodename\endcsname}%
% Draw a line from the center of the cloud to the the external point.
\pgfpathmoveto{\centerpoint}%
}%
{%
% Install the saved cloud path.
\expandafter\pgfsetpath%
\csname pgf@sh@bg@path@saved@\pgfreferencednodename\endcsname%
}%
\ifnum\pgfintersectionsolutions>0\relax%
\pgf@process{%
% Transform the intersection appropriately.
\pgfpointintersectionsolution{1}%
\pgf@pos@transform{\pgf@x}{\pgf@y}%
}
\else%
\centerpoint%
\fi
}

\begin{tikzpicture}

\node [cloud, cloud puffs=15.7, minimum width=3cm, draw]
(cloud) at (0,0) {Cloud};

\foreach \i in {0, 10, ..., 360}
\draw [black, ->] (cloud) -- (\i:5cm and 3cm);
\end{tikzpicture}

\end{document}


Note, that it doesn't take into account the outer sep and is likely not to be particularly robust, nor will it work with early versions of PGF. It is also slow.

-
fans of impenetrable hacking that would be me :) But there was another question for asymetrical cloud puffs which might be the reason for this question because on that question the asymmetry was achieved via nonineteger puff number. –  percusse Jan 11 '13 at 20:40
@mwibrow Yes, I like hacky solutions as well :-) But for the my presentation I will use a simple one ;-) –  Dave Jan 11 '13 at 22:26