相对于整体图片的边界框定位 TikZ 节点

相对于整体图片的边界框定位 TikZ 节点

我想在 TikZ 中绘制一些点,并将它们相对于整个图片的边界框定位。具体来说,我想明确给出它们的 y 坐标,并从图片边界框的左边缘获取它们的 x 坐标。我该怎么做?

下面是一个例子。每次我调用\myCircle或 时\mySquare,都会绘制圆形/正方形,并在左侧绘制一个小“缺口”。(缺口的目的是作为绘图辅助,以便用户可以看到形状的位置。)缺口的 y 坐标取自圆形/正方形的中心。x 坐标目前固定在0,但我更希望它是 之类的bounding box of overall picture.west

\documentclass[border=5mm]{standalone}
\usepackage{tikz}

\newcommand\myCircle[2]{%
  \fill[red] (#1,#2) circle (5);
  \draw (-2,#2) -- (0,#2);
}
\newcommand\mySquare[2]{%
  \fill[red] (#1-5,#2-5) rectangle (#1+5,#2+5);
  \draw (-2,#2) -- (0,#2);
}

\begin{document}
  \begin{tikzpicture}[x=1mm,y=1mm]
    \myCircle{7}{5}
    \mySquare{26}{0}
    \myCircle{8}{20}
  \end{tikzpicture}
\end{document}

在此处输入图片描述

答案1

一种可能性是创建标记的局部边界框,以供以后为每条路径引用。

\documentclass{article}
\usepackage{tikz}
\newcount\mycircle
\newcount\mysquare

\newcommand\myCircle[2]{%
\advance\mycircle by 1\relax
\begin{scope}[local bounding box/.expanded=c\the\mycircle]
    \draw[red] (#1,#2) circle (5);
\end{scope}
}
\newcommand\mySquare[2]{%
\advance\mysquare by 1\relax
\begin{scope}[local bounding box/.expanded=s\the\mysquare]
        \draw[red] ({#1-5},{#2-5}) rectangle ({#1+5},{#2+5});
\end{scope}
}

\tikzset{every picture/.style={
    execute at end picture={
        \ifnum\the\mycircle>0\relax%
            \foreach\myc in{1,...,\the\mycircle}{%
                \draw[overlay] (current bounding box.north west |- c\myc) -- ++(-3mm,0);%
            }%
        \fi%
        \ifnum\the\mysquare>0\relax%
            \foreach\myc in{1,...,\the\mysquare}{%
                \draw[overlay] (current bounding box.north west |- s\myc) -- ++(-3mm,0);%
            }%
        \fi%
        \mycircle=0\mysquare=0%
        }
    }
}
\begin{document}
  \begin{tikzpicture}[x=1mm,y=1mm]
    \myCircle{0}{5}
    \mySquare{26}{0}
    \myCircle{8}{20}
    \mySquare{10}{-3}
  \end{tikzpicture}

\vspace{2cm}

  \begin{tikzpicture}[x=1mm,y=1mm]
    \myCircle{-1}{5}
    \myCircle{3}{7}
  \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

我最终使用了 percusse 答案的简化版本,按照 Andrew 的建议只保留 y 坐标列表。代码如下。我只想指出两个导致我产生混乱的错误消息的“陷阱”:

  • 如果AB是节点,则可以使用A |- B来计算坐标,A其中的 x 值和B的 y 值。您可能希望能够写出对(x,y)而不是AB,但请注意以下问题:语法(A |- x,y)不是(A |- (x,y))

  • \x使用或\y作为循环的迭代变量时要小心\foreach。在下面的代码中,这样做没问题,但在早期版本中let \p1 = (oldBBox.north west),我使用了而不是|-语法,将边界框的左上角点存储在中。如果变量和已经在使用中,\x1,\y1则会出现问题。\x\y

代码

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\gdef\ys{} 

\makeatletter
\newcommand*\snoc[2]{%
  \ifx#1\@empty
    \xdef#1{#2}
  \else
    \xdef#1{#1,#2}
  \fi
}
\makeatother

\newcommand\myCircle[2]{%
  \draw[red] (#1,#2) circle (5);
  \snoc\ys{#2}
}
\newcommand\mySquare[2]{%
  \draw[red] ({#1-5},{#2-5}) rectangle ({#1+5},{#2+5});
  \snoc\ys{#2}
}

\tikzset{every picture/.style={
  execute at end picture={
    \coordinate (oldBBox) at (current bounding box.north west);
    \foreach \yvalue in \ys {%
      \draw (oldBBox |- 0,\yvalue) -- ++(-3mm,0);
    }
    \gdef\ys{}    
  }
}}

\begin{document}
  \begin{tikzpicture}[x=1mm,y=1mm]
    \myCircle{0}{5}
    \mySquare{26}{0}
    \myCircle{8}{20}
    \mySquare{10}{-3}
  \end{tikzpicture}

\vspace{2cm}

  \begin{tikzpicture}[x=1mm,y=1mm]
    \myCircle{10}{5}
    \myCircle{3}{7}
  \end{tikzpicture}
\end{document}

相关内容