我应该指出,我已经熟悉 TikZ,并且正在寻找技术答案,好像 TikZ 还不够技术性。
这个问题归结为以下问题,这些东西之间有什么区别:
\def\pointA{\pgfpoint{0cm}{0cm}}
\coordinate (A) at (current page.north east);
\coordinate (A) at (1,1);
(current page.north east)
\node [anchor=east] {}
<-- 一个锚点?:-p(仅展示术语重叠)\pgfpointanchor
<-- 但这一定是一个锚点,或者是一个点?:-p
我认为我的理解还不够,而且这干扰了我下面的尝试。
在数学中
A观点定义为:
点是平面上的一个精确位置或地点。重要的是要理解点不是一个事物,而是一个地方。
A协调定义为:
坐标是定义点位置的一组有序的数字。
锚点是:
我想用实际例子来澄清这一点。
让我们定义一个坐标:
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
有很多隐式坐标(应该称之为坐标、点、锚点还是别的什么?)比如:
- (当前页面.西北)
- (当前页面.北)
- (当前页面.东北)
- (当前页面.东)
- (当前页面.东南)
- (当前页面.南)
- (当前页面.西南)
- (当前页面.中心)
假设我想计算两件事物之间的垂直距离(我故意选择“事物”这个词)并将此变量存储在当前范围之外以供使用。
例如,这两个事物是 (当前页面.东北) 和 (右中)
为了进行算术运算,我知道以下选项(是全部吗?):
我可以用来
\pgfmathparse
评估算术我可以使用
\path let \p1=
语法。
使用选项 1,我可以将 设置\pgfxa
为\pgfya
并\pgfx
进行\pgfy
计算并使用 获得结果\pgfmathresult
。
然后我可以定义一个唯一的长度(全局),例如\setlength{\mylength}{2cm}
。然后我可以使用\mylength
来检索它。这将不允许我将所有内容都写入一个独立的宏中,因为\setlength
只能定义一次。另一种方法是使用\global\let\mylength{2cm}
,在我看来,这更适合这项工作(如果我错了,请纠正我。这对值+单位/维度有影响吗)?
综合起来
- 是否可以使用一个 TikZ 节点的宽度来计算另一个节点的宽度?
- 如何将坐标转换为 pgfpoint,反之亦然?
- 坐标 A、B:计算 |BA| 以及 +x 与 (BA) 之间的角度
- 返回节点的 pgf 宏
这是一个实验无法编译根据以下几个答案:
\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
% A4 Paper
\pdfpagewidth=210mm \pdfpageheight=297mm % for PDF output
\paperwidth=210mm \paperheight=297mm % for TikZ
\newcommand{\getdistance}[3]{
\makeatletter
% Syntax: <length variable/macro> <coordinate1> <coordinate2>
\pgfpointdiff{\pgfpointanchor{#2}{center}} % https://tex.stackexchange.com/a/39325/13552
{\pgfpointanchor{#3}{center}} % https://tex.stackexchange.com/a/39325/13552
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)}
\global\let#1\pgfmathresult % <-- I want the pgfmathresult to be a dimension like 510 pt
\makeatother
}
\begin{document}
\begin{tikzpicture}[overlay]
\coordinate (rightmidtest) at ($ (current page.north east) + (0,-10cm) $); % use tikz calc library
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\end{tikzpicture}
\getdistance{\globalresult}{rightmidtest}{rightmid}
\getdistance{\globalresult}{current page.north east}{rightmid}
\getdistance % <-- Should expand to last distance measured
\end{document}
更新代码 2016-02-25在职的
经过对 percusse 的回答的分析和新的理解后,我想到了一些其他的东西。
记住:
(current page)
是隐含的- 锚点 .center 在 TikZ 中是隐式的,但在 PGF 中不是
\pgfpointanchor{<ref>}{<anchor e.g. center>}
我使用xparse
宏的语法,因为它更容易阅读。
\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{xparse}
\makeatletter
\NewDocumentCommand{\getdistance}{ m m O{center} m O{center} }{%
%Syntax: {\<macro>} {<ref1>} [<anchor>] {<ref2>} [<anchor>]
\pgfpointdiff{\pgfpointanchor{#2}{#3}}% https://tex.stackexchange.com/a/39325/13552
{\pgfpointanchor{#4}{#5}}% https://tex.stackexchange.com/a/39325/13552
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)} % result as number (floating point)
%\pgfmathveclen{\pgf@xa}{\pgf@ya} % alternate syntax to pgfmathparse: result as number (floating point)
%\global\let#1\pgfmathresult pt % does not recognize pt.
\global\edef#1{\pgfmathresult\ pt}
%\pgfmathprintnumber{\pgfmathresult}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
% (current page) is implicit
% .center is implicit in TikZ but not in PGF \pgfpointanchor{<ref>}{<anchor e.g. center>}
\coordinate (referral1) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\node [minimum height=2cm] (referral2) {};
\end{tikzpicture}
\begin{tikzpicture}[remember picture,overlay]
\getdistance{\globalresultA}{current page}{referral1}
\getdistance{\globalresultB}{current page}[north east]{referral1}
\getdistance{\globalresultC}{current page}[north east]{referral2}[north]
\getdistance{\globalresultD}{current page}[north east]{referral2}[south]
\end{tikzpicture}
\globalresultA
\globalresultB
\globalresultC
\globalresultD
\end{document}
答案1
我认为混淆的原因是 TikZ 使用的是引用而不是对象。当a
提到某个节点名称时。它通常假设用户可能指的是它的中心坐标。或者在两个东西之间绘制东西的情况下,如果其中一个是节点,那么它会神奇地计算出其边界上的点,这样用户就不会注意到。
但所有这些都是在内部完成的。与节点无关。节点有一个可以引用的名称和预定义的节点可理解的位置。
这些都不存储。它们只是检查是否存在或只是执行。换句话说,如果你写shape=duck
,那么它不会检查所有可能的形状名称,它只是进行这种存在性检查(我对实际的宏使用了无意义的名称)
\pgfutil@ifdefined\pgf@Shape@#1@...{<if it exists use>}{<if not err>}
锚点也是一样的,如果你说,它会通过一些等等来anchor=heel
询问这个名字。\pgf@sh@#1@anchor@#2
那么这些是从哪里来的呢?它们是通过形状声明来定义的,\savedanchor
等等\anchor
。
所以它们就在那里,精心排列,这样当你引用它们时,从文本框的宽度高度到形状路径的所有内容都是痛苦的手工编码。这就是为什么定义新形状是一项非常繁琐的工作。当你引用它们时,它们的排列方式是将锚点位置(全局!)写入长度寄存器内\pgf@<x,y>
长话短说,当您引用节点锚点时,实际上有一个相当复杂的过程才能从中获取坐标。
此外,坐标\pgf@<x,y>
和坐标类型节点之间是有区别的\coordinate
。
最后,当您引用一个节点时,TikZ 会尝试通过假设您指的是它的中心锚点来帮助您,这样您就可以节省一些击键,但有时您需要进行更精细的操作,例如距离测量。
您不能使用引用名称。您需要实际坐标(再次强调不是\coordinate
s)。正如 Mark Wibrow 所评论的那样,您必须以某种方式理解上下文,而这可以通过\pgf@process
回答以下问题来实现:它是文字坐标吗(1,1)
?它是节点名称吗?它是节点锚点吗?等等。然后,您可以使用生成的\pgf@<x,y>
寄存器。
然后,您就可以对它们做任何您想做的事情。您的示例let
语法也很好地简化了这一点,但它仍然在做您所描述的事情。实际上,您的问题基本上是为什么 TikZ 存在于 PGF 之上。它是一个设计精良的前端,具有非常冗长但功能强大的 PGF 语法。
答案2
\def\pointA{\pgfpoint{0cm}{0cm}}
仅当您熟悉 PGF(Ti 的基础)时才使用此功能钾Z)。无论如何,TeX 中做什么并不重要\pgfpoint
;这个命令从来都不是单独存在的。通常它是语法的一部分,例如
\coordinate (A) at (current page.north east);
给点命名。实际的 x 和 y 坐标是什么并不重要。我们知道它(A)
在哪里,这就是我们需要知道的一切。
\coordinate (A) at (1,1);
与上一个类似。通常我们命名点是为了 (A) 减少代码长度/复杂性和 (B) 提高可读性。例如
(current page.north east)
带括号时,它会发出搬去动作。这很像你拿着笔,将手移到下一个想要画的地方。例如
此代码使 Ti钾Z 将笔移动到画布周围并声明节点/坐标。
\node [anchor=east] {}
将节点放置在钢笔当前位置的“附近”。我说的“附近”是指您给出的锚应与钢笔的位置一致。这很像您在船上可以将锚抛到您想要的地方,然后锚会固定住船。
实践部分
- 你需要
\makeatletter
。 - 您可能想要
\pgfmathsetlength
而不是\pgfmathsetmacros
或\pgfmathparse
。- 但请记住,所有尺寸必须在使用前声明。
- 使用节点时要小心
(current page)
。通常你需要[overlay]
。 - 您需要处于
tikzpicture
环境内部才能检索您在tikzpicture
环境中制作的任何内容。- 如果您不是在同一个环境中工作
tikzpicture
,您需要[remember picture]
。
- 如果您不是在同一个环境中工作
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\newcommand{\getdistance}[3]{
% Syntax: <length variable/macro> <coordinate1> <coordinate2>
\pgfpointdiff{\pgfpointanchor{#2}{center}} % http://tex.stackexchange.com/a/39325/13552
{\pgfpointanchor{#3}{center}} % http://tex.stackexchange.com/a/39325/13552
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfmathparse{veclen(\pgf@xa,\pgf@ya)}
\global\let#1\pgfmathresult % <-- I want the pgfmathresult to be a dimension like 510 pt
}
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
\coordinate (rightmidtest) at ($ (current page.north east) + (0,-10cm) $); % use tikz calc library
\coordinate (rightmid) at ($ (current page.north east) + (0,-18cm) $); % use tikz calc library
\end{tikzpicture}
\tikz[remember picture,overlay]{
\getdistance{\globalresulta}{rightmidtest}{rightmid}
\getdistance{\globalresultb}{current page}{rightmid}
}
\globalresulta
\globalresultb
\end{document}
答案3
\def\pointA{\pgfpoint{0cm}{0cm}}
这基本上与
\coordinate (A) at (0,0);
\coordinate (A) at (current page.north east);
这里您只是将页面的右上角命名为
A
。从位置已经命名的角度来看,这毫无意义,但不必输入所有内容而只需输入 会很有帮助A
。\coordinate (A) at (1,1);
TikZ 中的坐标基本上是具有
coordinate
形状的节点,它们不需要标题,而且,特别重要的是,它们没有sep
。所以这是一个要点。尽管如此,写\node[coordinate] (a) at (0,0) {};
等于\coordinate (a) at (0,0);
(current page.north east)
这表示当前“页面”的右上角。通常,这是一张 A4 纸,但可以是任意尺寸。在这种情况下,页面不一定是通常的纸张,但可以是任何指定区域。
\node [anchor=east] {}
<-- 一个锚?不,这不是锚点。这是一个节点,其定位是通过在坐标处放置设计的锚点来确定的。因此将放置具有与坐标重合的锚点
\node [anchor=east] at (4,0) {};
的节点。east
(4,0)
答案4
我不知道如何编辑我的旧答案。我只会写一个新的。
钛钾Z 有很多方法可以指定点
给出数字坐标。
例如(1,2)
,(3mm,4in,5pt)
,(6:7)
,(axis cs:x=8)
。给出预定义的节点名称和锚点名称。
例如(current page.south east)
,(current bounding box.north west)
。给出预定义的节点名称。
例如(current page)
。这相当于(current page.center)
给出预定义的
coordinate
。
例如\coordinate(X)at(1,2);\path(X);
。Acoordinate
实际上是一个节点,其中锚点“消失”:(X)
、(X.center)
、(X.south)
和(X.34)
均给出相同的结果。
他们的 PGF 对应物是
\pgfpointxy
,\pgfpointxyz
,\pgfpointpolar
, 等等\pgfpointanchor{#1}{#2}
\pgfpointanchor{#1}{center}
\pgfpointanchor{#1}{center}
现在你看到,在 的定义中\getdistance
,只能填写一个节点名称,并且锚点center
是强制选择的。因此
\getdistance{\globalresultb}{current page.north east}{rightmid}
无法编译,因为current page.north east
不再是节点。但是
\coordinate (A) at (current page.north east);
\getdistance{\globalresultb}{A}{rightmid}
确实编译,因为(A)
是节点的名称。
哪种输入可以处理取决于你\getdistance
。例如在 Ti钾Z,\tikz@parse@node
可以处理(X)
和(Y.Z)
。但不能(1,2)
。更一般地\tikz@@scan@@no@calculator
,和可以处理(X)
、(Y.Z)
和(1,2)
。更一般地,\tikz@@@scan@@absolute
可以处理($ (current page.north east) + (0,-10cm) $)
。您需要选择一个。