3

Considering TikZ code:

    \begin{tikzpicture}
        \draw <a square>;
        \draw <an elephant>;
        \draw <a toaster>;
    \end{tikzpicture}

I'd like to access the coordinates of a bounding box that surrounds the elephant and toaster but that ignores the square, which must be drawn before the elephant and toaster since certain coordinates in the elephant and toaster rely on current bounding box, and this bounding box must include the square.

The problem is that the elephant and toaster are actually complex procedures that draw and fill many TikZ paths, create many nodes, etc., and these procedures are (generally speaking) unable to report back their topmost, leftmost, etc. coordinates. Hence what is needed is a facility:

    \begin{tikzpicture}
        \draw <a square>;
        <do something here to mark start of scope>
        \draw <an elephant>;
        \draw <a toaster>;
        <do something here to mark end of scope>
        \draw[red] ($(scoped bounding box.south west) - (2mm,2mm)$)
            rectangle ($(scoped bounding box.north east) + (2mm,2mm)$);
    \end{tikzpicture}

to draw a red box around the elephant and toaster (with a 2mm inner margin) where scoped bounding box works exactly like current bounding box except that it only considers the objects drawn by code between the designated start and end of scope.

I don't require this specific syntax, setup, or command order. Anything that yields the coordinates for the "partial" bounding box in a format that can be used in TikZ point arithmetic will suffice, with the lone caveat being that whatever code is injected must not alter the coordinate frames or style options of commands in the subroutines to render the elephant and toaster. Also, it would be greatly preferred if the none of the code in the elephant and toaster subroutines needed to be altered, although I understand this may be necessary.

4

There is a syntax dedicated to this, it is the local bounding box. See section 106.4 Special Nodes of the TikZ manual.

screenshot

\documentclass[tikz,border=5mm]{standalone}
%\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}
       \draw (0,0)rectangle (2,2);
        \begin{scope}[local bounding box=redbox]
        \draw (4,0)circle(1cm);
        \draw (4,-3)circle(1cm and 2cm);       
        \end{scope}
        \draw[red] ($(redbox.south west) - (2mm,2mm)$)
            rectangle ($(redbox.north east) + (2mm,2mm)$);

\end{tikzpicture}

\end{document}
| improve this answer | |
  • Brilliant. Exactly what I wanted. Those TikZ guys think of everything. :) – COTO Oct 28 at 2:39
3

I didn't understand everything, but it seems to me that a solution is to encapsulate your elephant and toaster procedures in two nodes and then to use the fit library. It is not advisable to encapsulate tikz figures in nodes but it is sometimes practical.

\documentclass{article}
\usepackage{geometry,graphicx}
\usepackage{tikz,amsmath,ppnmacro}

\usetikzlibrary{fit}

\begin{document}


\begin{tikzpicture}

\node[draw,minimum size=1.5cm] (A) at (0,0) {square};

\node(elephant) at (5,3) {
\begin{tikzpicture}
\draw (0,0) -- (2,1) -- (5,-2) -- (0,-1)-- cycle;
\draw[blue] (2,1) coordinate(aa) circle (2cm);
\node at (aa){elephant};
\end{tikzpicture}
};


\node(toaster) at (3,-2) {
\begin{tikzpicture}
\draw[red] (2,1) coordinate(aa) circle (1cm);
\node[rectangle,draw,fill=purple] at (aa){toaster};
\end{tikzpicture}
};

\node[fit=(toaster) (elephant),draw, red,thick]{};

\end{tikzpicture}


\end{document}

enter image description here

| improve this answer | |
  • A good alternative if Andre's solution doesn't work in some context. – COTO Oct 28 at 2:39
  • This solution gives unwanted affect sometimes. Do not nest tikzpicture! – Black Mild Oct 28 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.