# Prevent shifting of shading center point when using relative coordinates

I am writing some macros that allow for the drawing of ball shapes in an arbitrary fashion in \foreach loops:

\documentclass[tikz, border=0.5in]{standalone}
\newcommand{\ball}[3][0,0]{%\ball[basepoint]{point}{diameter}
\shadedraw[ball color=blue!15!white, draw=blue!50] (#1) +(#2) circle (#3);
}

\begin{document}
\begin{tikzpicture}
\foreach \t in {10, 20, ..., 360}{
\ball{\t:6}{0.5}
}
\ball{0,0}{0.5}

\foreach \t in {10, 20, ..., 360}{
\ball[14,0]{\t:6}{0.5}
}
\ball{14,0}{0.5}
\end{tikzpicture}
\end{document}


I am using relative coordinates in order to allow the use of polar coordinates not centered at the origin, as can be seen above. Unfortunately, my shading is not working as I expect.

I hope to get a result like this, but using the relative coordinates:

\documentclass[tikz, border=0.5in]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \t in {10, 20, ..., 360}{
\shadedraw[ball color=blue!15!white, draw=blue!50] (\t:6) circle (0.5);
}
\shadedraw[ball color=blue!15!white, draw=blue!50] (0,0) circle (0.5)
\end{tikzpicture}
\end{document}


It seems that the shading algorithm is not taking in to account the center of the drawn circles being moved relative to (0,0). Is it possible to re-define the origin of the shading?

• Haha nice one, I guess it is a bug. For now use the calc library and sum the coordinates instead like ($(#1)+(#2)$) circle (#3). – percusse Feb 19 '15 at 0:26
• @percusse I did not anticipate that calc would do the rectangular and polar math so transparently! I think I will use @Paul's answer below since it doesn't require an additional library, but I will keep this solution in mind for the future. – Scott Colby Feb 19 '15 at 0:45
• @percusse It is not a bug: just a shaded path with a too large bounding box (containing the base point). – Paul Gaborit Feb 19 '15 at 1:02
• @PaulGaborit It should have not put the pen down. I would consider it as a bug as there is no path to build a bounding box yet initially Just a move to operation. – percusse Feb 19 '15 at 1:20
• @Scott pgfmanual v3.0, section 15.7, p.175: " "To solve this problem, the predefined shadings like ball or axis fill a large rectangle completely in a sensible way. Then, when the shading is used to shade a path, what actually happens is that the path is temporarily used for clipping and then the rectangular shading is drawn, scaled and shifted such that all parts of the path are filled." – Paul Gaborit Feb 19 '15 at 7:34

To limit the bounding box of your shaded path, the base point should not appear in this path.

Here are four solutions:

• \ballshift: use a shift operation on your center,
• \ballscope: use a local scope with a shifted origin,
• \ballcalc: use calc to shift your center,
• \ballnode: use a circle node with shading.

\documentclass[tikz, border=0.5in]{standalone}
\usetikzlibrary{calc}
\newcommand{\ballshift}[3][0,0]{%\ball[basepoint]{point}{diameter}
\shadedraw[ball color=blue!15!white, draw=blue!50] ([shift={(#1)}]#2) circle (#3);
}
\newcommand{\ballscope}[3][0,0]{%\ball[basepoint]{point}{diameter}
\begin{scope}[shift={(#1)}]
\shadedraw[ball color=red!15!white, draw=red!50] (#2) circle (#3);
\end{scope}
}
\newcommand{\ballcalc}[3][0,0]{%\ball[basepoint]{point}{diameter}
\shadedraw[ball color=orange!15!white, draw=orange!50] ($(#1)+(#2)$) circle (#3);
}
\newcommand{\ballnode}[3][0,0]{%\ball[basepoint]{point}{diameter}
\path (#1) ++(#2) node[inner sep=0,circle,minimum size=2cm*#3,
ball color=lime!50!white,draw=lime]{};
}

\begin{document}
\begin{tikzpicture}
\foreach \t in {10, 20, ..., 360}{
\ballshift{\t:6}{0.5}
\ballscope{\t:5}{0.4}
\ballcalc{\t:4}{0.3}
\ballnode{\t:3}{0.2}
}
\ballshift{0,0}{0.5}

\foreach \t in {10, 20, ..., 360}{
\ballshift[14,0]{\t:6}{0.5}
\ballscope[14,0]{\t:5}{0.4}
\ballcalc[14,0]{\t:4}{0.3}
\ballnode[14,0]{\t:3}{0.2}
}
\ballshift{14,0}{0.5}
\end{tikzpicture}
\end{document}