TikZ:获取节点锚点之间的(无量纲)距离

TikZ:获取节点锚点之间的(无量纲)距离

在下图中,我希望节点 C 的宽度与图中所示的(A.north east)和之间的距离一样宽;我尝试用定义一个新的节点 D ,并尝试使用存储此长度以供以后使用,但出现了错误。在第一种情况下,我得到了;在第二种情况下,我得到了,以及其他错误(例如缺少)。这是我的 MWE:(B.south west)\n1minimum width\pgfmathsetmacroUndefined control sequence\n1Use of \tikz@cc@stop@let doesn't match its definition. \pgfmathsetmacro}

\documentclass[tikz]{standalone}

\usepackage[T1]{fontenc}

\usetikzlibrary{
    calc,
    positioning
}

\begin{document}

\begin{tikzpicture}[font = {\fontsize{40}{42}\selectfont}]
    \node[draw, blue] (A) at (0,0) {NODE A};
    \node[draw, red, anchor = north] (B) at (A.mid west) {NODE B};
    \draw (A.north east) -- node[midway, sloped, anchor = south, inner sep = 0, fill = gray, opacity = 0.6] {\normalsize\bfseries This length} (B.south west);
    \node[draw, anchor = north east] (C) at (B.south west) {NODE C};
    \coordinate[above = 2.7pt of C.north west] (uno) {};
    \coordinate[above = 2.7pt of C.north east] (dos) {};
    \draw[densely dashed] (uno)  -- (dos) node [midway, solid] {\normalsize This length};
    \draw let \p1 = ($ (B.south west) - (A.north east) $), \n1 = {veclen(\x1,\y1)}
    %\pgfmathsetmacro{\len}{\n1} 
    in circle [at = (C.center), radius =\n1];
    %\node[minimum width = \n1] (D) {NODE D};
\end{tikzpicture}

\end{document}

我如何存储值\n1以供以后使用?此外,我想稍后将此长度用作比例因子,因此我认为\pgfmathscalar在那里会很有用,但首先我需要记录长度。我认为需要注意的是,我想使用从以上述方式构建的节点获得的长度:将一个节点放在另一个节点的锚点上。我还想在不重复绘制圆圈的情况下获得长度;有没有办法在不进行操作的情况下做到这一点let?我想人们必须获得锚点的坐标,就像这个答案一样,但我不知道如果不使用该怎么做let,这就是重点。

谢谢!!!

使用 <code>let</code> 获取长度。

答案1

在这种情况下,您可以使用路径来绘制您使用的所有对象。为了转换\n1为无量纲数字\mylen\mylen cm=\n1您可以使用

\pgfextra{\pgfmathsetmacro{\mylen}{\n1/1cm}}

在这个例子中,这不是必需的,即您可以使用\n1所有的长度,但这里有一个例子。

\documentclass[tikz]{standalone}

\usepackage[T1]{fontenc}

\usetikzlibrary{
    calc,
    positioning
}

\begin{document}

\begin{tikzpicture}[font = {\fontsize{40}{42}\selectfont}]
    \node[draw, blue] (A) at (0,0) {NODE A};
    \node[draw, red, anchor = north] (B) at (A.mid west) {NODE B};
    \draw (A.north east) -- node[midway, sloped, anchor = south, inner sep = 0, fill = gray, opacity = 0.6] {\normalsize\bfseries This length} (B.south west);
    \node[draw, anchor = north east] (C) at (B.south west) {NODE C};
    \coordinate[above = 2.7pt of C.north west] (uno) {};
    \coordinate[above = 2.7pt of C.north east] (dos) {};
    \draw[densely dashed] (uno)  -- (dos) 
    node [midway, solid] {\normalsize This length};
    \draw let \p1 = ($ (B.south west) - (A.north east) $), \n1 = {veclen(\x1,\y1)}
    in \pgfextra{\pgfmathsetmacro{\mylen}{\n1/1cm}}
    node[minimum width =\n1, draw, purple, fill = gray!10,
     opacity = 0.5] (D) at (C.center) {NODE D}
    (C.north east) circle [radius =\mylen]
    (D.west) circle [radius=\mylen];
    \draw[red,dashed,thick] let \p1 = ($ (B.south west) - (A.north east) $), \n1 = {veclen(\x1,\y1)}
    in \pgfextra{\pgfmathsetmacro{\mylen}{\n1/1cm}}
    (C.north east) circle [radius =\n1]
    (D.west) circle [radius=\n1];
\end{tikzpicture}

\end{document}

在此处输入图片描述

如您所见,圆圈匹配,即半径为的红色虚线圆圈\n1位于半径为的圆圈之上\mylen。不过,这有点意外,因为原则上 TiZ 区分半径(即有量纲量)和无量纲半径因子,参见这里进行精彩的讨论。在本例中,单位向量的长度为1cm,这就是结果匹配的原因。也就是说,无量纲半径被解释为(radius factor) * (length of unit vector)。这特别意味着,如果 x 和 y 单位向量的长度不同,您将得到一个具有无量纲半径的椭圆。

附录:以下是一些关于走私的评论,即关于在不将其设为全局的情况下将宏从组中广播出去的问题。这与路径和foreach例如,这与路径和 for 循环有关。已经讨论了走私这里。Henri Menke 还补充道这个答案,它将在下一个版本的 pgf 中完全发挥作用(现在必须使用一个小修复)。这些技巧尚未得到应有的重视也就是说,如果您使用 3.1.6 或更高版本,则不需要修复。核心级宏\pgfutil@pushmacro\pgfutil@popmacro可以内置在 pgf 函数中,允许我们走私。这是一个例子。

\documentclass[tikz]{standalone}
\usetikzlibrary{calc,positioning}
\makeatletter
% using https://tex.stackexchange.com/a/491246/194703
% won't be needed in future versions of tikz/pgf 
% see fix https://github.com/pgf-tikz/pgf/commit/0034290cb0295bafbb45f27a12a71a67797fcdbb
\def\pgfutil@pushmacro#1{%
    \xdef\pgfutil@pushmacro@string{\string#1}%
    \ifcsname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\else
        % \newcount is \outer in Plain
        \csname newcount\expandafter\endcsname\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname
    \fi
    \global\advance\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname 1\relax
    \global\expandafter\let\csname\the\csname pgfutil@pushedmacro@\pgfutil@pushmacro@string\endcsname\pgfutil@pushmacro@string\endcsname#1%
}
\tikzset{push/.code={\expandafter\edef\csname#1\endcsname{\csname#1\endcsname}%
\expandafter\pgfutil@pushmacro\csname#1\endcsname}}
\pgfmathdeclarefunction{pop}{1}{\begingroup
\expandafter\pgfutil@popmacro\csname#1\endcsname%
\expandafter\pgfmathparse\expandafter{\csname#1\endcsname}%
\pgfmathsmuggle\pgfmathresult
\endgroup}
\makeatother
\begin{document}
\begin{tikzpicture}
    \node[draw, blue] (A) at (0,0) {NODE A};
    \node[draw, red, anchor = north] (B) at (A.mid west) {NODE B};
    \draw let \p1 = ($ (B.south west) - (A.north east) $), \n1 = {veclen(\x1,\y1)}
    in \pgfextra{\pgfmathsetmacro{\mylen}{\n1/1cm}}
    [push={mylen}];
    \path (A)
    node[above=1ex]{length in cm is $\pgfmathparse{pop("mylen")}\pgfmathprintnumber\pgfmathresult$};
    \foreach \X [count=\Y] in {A,...,F}
    {\edef\mycount{\Y}
    \tikzset{push=mycount}}
    \pgfmathparse{pop("mycount")}
    \typeout{\pgfmathresult}
\end{tikzpicture}
\end{document}

在此处输入图片描述

如您所见,您现在可以使用

 \tikzset{push=mycount}}

推送宏\mycount,然后使用 pgf 函数pop("mycount")在组外检索其值。pop("mycount")可用于由 Ti 解析的任何表达式中Z,包括坐标。类似的技巧允许键入foreach类型remember outside。也就是说,\foreach循环的最大缺点之一可以通过以下方式克服亨利的回答

答案2

我想我已经明白了,尽管也许还有其他解决方案,希望更有效;它需要库math

\documentclass[
    tikz
]{standalone}

\usepackage[T1]{fontenc}

\usetikzlibrary{
    calc,
    positioning,
    math
}

\begin{document}

\begin{tikzpicture}[font = {\fontsize{40}{42}\selectfont}]
    \node[draw, blue] (A) at (0,0) {NODE A};
    \node[draw, red, anchor = north] (B) at (A.mid west) {NODE B};
    \draw (A.north east) -- node[midway, sloped, anchor = south, inner sep = 0, fill = gray, opacity = 0.6] {\normalsize\bfseries This length} (B.south west);
    \node[draw, anchor = north east] (C) at (B.south west) {NODE C};
    \coordinate[above = 2.7pt of C.north west] (uno) {};
    \coordinate[above = 2.7pt of C.north east] (dos) {};
    \draw[densely dashed] (uno)  -- (dos) node [midway, solid] {\normalsize This length};
%   \draw let \p1 = ($ (B.south west) - (A.north east) $), \n1 = {veclen(\x1,\y1)}
%   in circle [at = (C.center), radius =\n1];
    \tikzmath{
        coordinate \p;
        \p = (B.south west) - (A.north east);
        \len = veclen(\p);  
        \lencm = 0.035*\len;
    }
    \node[minimum width = {\lencm cm}, draw, purple, fill = gray!10, opacity = 0.5] (D) at (C.center) {NODE D};
    \draw (C.north east) circle (\len pt);
    \draw (D.west) circle (\lencm);
    \node[circle, inner sep = 1pt, fill] at (D.west) {};
\end{tikzpicture}

\end{document}

我还定义了相同的长度(以厘米为单位)并乘以适当的因子;但是我注意到,我必须键入minimum length = {\lencm cm}才能获得适当大小的矩形;否则我会得到一个与 C 大小完全相同的节点;不过,绘制圆时不需要指定单位。有人知道为什么吗?

在此处输入图片描述

相关内容