[Tex/LaTex] How to get consistent positioning for a node with \usebox containing a \tikzpicture

beamerboxestikz-pgf

I'm using beamer and tikz to create an animation of a photon travelling between snowflakes. I have ten Koch snowflakes (hence the \newcommand in my MWE) typeset with decorate{ decorate{ decorate{ decorate{..., and subsequently I have many slides within a frame. Since each slide takes about 20 seconds to typeset, I have decided to use \savebox and \usebox to save time (I tried externalization first, but I rely heavily on external macros, external references, pointers from one tikzpicture to another, and therefore gave up). However, I don't know how to match the coordinate systems of the tikzpicture inside the savebox and the one containing the node where I use the savebox.

This question appears related, but since my image is off in both coordinates, not only vertically, it appears my issue is a different one.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,spy,fit,positioning,backgrounds,arrows,shapes,intersections,decorations.fractals,decorations.markings,external}
\newcommand{\snowflake}[2]{
    \path[fill,draw] decorate{ decorate{ decorate{ decorate{ #1 ++(-150:.5*#2/0.866) -- ++(60:#2) -- ++(-60:#2) -- cycle }}}};
}
\newsavebox{\manyflakes}
\savebox{\manyflakes}{
\begin{tikzpicture}[decoration={Koch snowflake,amplitude=1pt,segment
length=1pt,start radius=1pt},draw=blue,fill=white,very thin]
\snowflake{(1.81, 1.42)}{0.89}
\end{tikzpicture}
}
\begin{document}
\begin{tikzpicture}
\node[anchor=south west,inner sep=0] at (0,0) {\usebox{\manyflakes}};
\filldraw[red] (1.81, 1.42) circle [radius=0.1];
\end{tikzpicture}
\end{document}

Output with photon not centred as desired

How do I match the coordinate systems of the savebox with the one of the tikzpicture, so that the circle at 1.81, 1.42 is exactly in the middle of the snowflake?

Best Answer

One thing which is wrong is that you have two spaces, one before and one after the tikzpicture, which push the savebox to the right. Note that source file line breaks are turned to spaces (except two in a row which are turned into a \par. You need to add a % after the opening { to remove that space and then one after \end{tikzpicture}.

Then you should also the outer sept to 0pt, which affects the positioning, too.

I also figured that your \showflake macro has a bug. It seems that the path starts at (0,0) and makes a moveto operation to the start position given by #1. This seems to cause the have picture to have a slightly negative X and Y component which pushes the savebox to the upper right. To fix this you can make the \path operation already start at #1. Then you need to add an empty \path which includes (0,0), otherwise TikZ will crop the image to only contain the flake, but not the origin.

The following code gives me a perfect match. I added a second circle for easy comparison.

\documentclass[border=2]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,spy,fit,positioning,backgrounds,arrows,shapes,intersections,decorations.fractals,decorations.markings,external}
\newcommand{\snowflake}[2]{%
    \path (0,0);
    \path[fill,draw] #1 decorate{ decorate{ decorate{ decorate{ #1 ++(-150:.5*#2/0.866) -- ++(60:#2) -- ++(-60:#2) -- cycle }}}};
}
\newsavebox{\manyflakes}
\savebox{\manyflakes}{%
    \begin{tikzpicture}[decoration={Koch snowflake,amplitude=1pt,segment
        length=1pt,start radius=1pt},draw=blue,fill=white,very thin]
        \snowflake{(1, 2)}{0.89}
        \filldraw[green] (1, 2) circle [radius=0.11];% For comparison
    \end{tikzpicture}%
}

\begin{document}
\begin{tikzpicture}
\node[anchor=south west,inner sep=0pt,outer sep=0pt] at (0,0) {\usebox{\manyflakes}};
\filldraw[red] (1, 2) circle [radius=0.1];
\end{tikzpicture}
\end{document}