如何将!.5!
运算符与-|
运算符结合起来?
我想要一个节点,其 x 坐标等于节点 A 和 B 的 x 坐标的平均值,并且 y 坐标等于节点 C 和 D 的 y 坐标的平均值。
答案1
我认为您不能直接混合使用($...!...!...$)
and|-
语法。相反,我建议使用\path ... node
构造来获得所需的结果:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\node (A) at (0,1) {A};
\node (B) at (1,1.5) {B};
\node (C) at (2,0) {C};
\node (D) at (2.5,-2) {D};
\path ($(A)!0.5!(B)$) |- node[red] {X} ($(C)!0.5!(D)$);
\end{tikzpicture}
\end{document}
答案2
看看代码,杰克说得对精神但事实并非如此。它是可能的混合计算东西(即$...$
计算)路口东西(即(... |- ...)
事物),但做的方式涉及一些技巧,我会警惕这种变化,所以我不推荐这个方法。
要了解其工作原理,我们必须了解 TikZ 如何解析坐标。很多指定 TikZ 必须知道的坐标的方式!所以它会寻找线索。第一个线索之一是坐标(在左括号后)是否有美元符号。如果有,它会将其交给库calc
(假设库已加载)。如果没有,它会继续进行其他测试。这些其他测试之一会查找字符串|-
或-|
。如果找到这两个中的一个,那么它就知道它在看一个交集。此时,它假设语法类似于(coordinate |- coordinate)
。这两个coordinate
s 可能非常通用(节点、长度、所有这类东西),因此它非常明智地将它们发送回解析器进行重新处理。 这是一个新实例因此从理论上讲,这些可能涉及calc
表达式。困难在于,如果第一个涉及calc
表达式,那么它以美元开头,但这正是解析器一开始寻找的!
因此,我们的任务(如果我们选择接受它)是找出一种方法来指定表单的坐标(calc-coord |- calc-coord)
,以便初始解析器能够不是看到第一个坐标的开头美元,但当它重新插入解析器时,它就会暴露出来。事实证明,这是这是可能的,因为在某个时候,一些分组是未分组的。所以我们可以将坐标包装成组,以在第一次迭代中隐藏它们,在第二次迭代中显示它们。我们只需正确设置组数即可。另一个问题是,由于calc
表达式通常涉及括号,我们希望在初始解析器中隐藏这些括号,这样它就不会对坐标的结尾位置感到困惑。
最后,通过一些实验,我们发现二第一个坐标有 10 个组,第二个坐标只有一个组。因此:
\node at ({{$(A)!0.5!(B)$}} -| {$(C)!.5!(D)$}) {X};
它在锡上说了什么。
我实在不推荐这样做的原因是,如果实施情况发生变化,分组的数量可能会发生变化;甚至可能不再起作用。
因此,我还为您提供了一个使用纯calc
语法的解决方案。我们可以这样做,因为calc
库有自己的投影语法。此方法避免创建任何额外的坐标,并且意味着它都是单个坐标表达式的一部分(这意味着它比 Jake 的方法更强大一些,因为不涉及任何路径,因此在更复杂的路径中更安全)。但是,我仍然不太推荐这个解决方案,因为它很复杂,我宁愿选择更简单的解决方案,使用一些额外的坐标,因为这样在六个月后重新阅读代码时更容易弄清楚发生了什么。但为了挑战,这里是:
\node at ($($(A)!0.5!(B)$)!($(C)!0.5!(D)$)!($(A)!.5!(B)+(0,2)$)$) {Y};
简而言之,我们将 处的坐标正交投影到从到 的($(C)!0.5!(D)$)
线上。($(A)!0.5!(B)$)
($(A)!0.5!(B)+(0,2)$)
以下是包含上述两种代码的示例代码。我将一个放在下方,将一个放在上方,以分别显示它们。矩形是为了显示它们位于正确的位置。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\node (A) at (0,0) {A};
\node (B) at (2,2) {B};
\node (C) at (4,4) {C};
\node (D) at (6,6) {D};
\draw[blue] ($(A)!.5!(B)$) |- ($(C)!.5!(D)$) |- ($(A)!.5!(B)$);
\node[red] at ({{$(A)!0.5!(B)$}} -| {$(C)!.5!(D)$}) {X};
\node[red] at ($($(A)!0.5!(B)$)!($(C)!0.5!(D)$)!($(A)!.5!(B)+(0,2)$)$) {Y};
\end{tikzpicture}
\end{document}
结果:
(我为这个 hack 取的文件名是tikzcomplicatedcalc
。我想你也许想知道。)
答案3
我把它分成几部分:
\coordinate (AB) at ($(A)!.5!(B)$);
\coordinate (CD) at ($(C)!.5!(D)$);
\coordinate (X) at (AB |- CD);
答案4
我可能迟到了,但还有其他的可能性可以达到那个特别的点。
第一个使用let … in
定义两个点的语法\p1
,并\p2
使用$calc$
语法并使用\x1
(的x值\p1
)和\y2
(的y值\p2
)进行节点声明。
另一个解决方案已定义|-
/ -|
styles/codes (?),它接受两个参数,即两个点,以确保正确。代码段将一个点的 x 值保存到 ,\tempx
将另一个点的 y 值保存到\tempy
。
这些解决方案的优点是您可以在相同的路径中重复使用计算的值(let … in
)或者直到它们被重新定义(|-
/ -|
)。
人们可以编写额外的样式/代码/宏来定义额外的宏来代替\tempx
,\tempy
以便在计算另一组值后可以重新使用它们。
代码
\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\def\getxy#1#2{%
\tikz@scan@one@point\pgfutil@firstofone(#1)\relax%
\xdef\tempx{\the\pgf@x}%
\tikz@scan@one@point\pgfutil@firstofone(#2)\relax%
\xdef\tempy{\the\pgf@y}%
}
\makeatother
\tikzset{
|-/.code 2 args={\getxy{#1}{#2}},
-|/.code 2 args={\getxy{#2}{#1}}
}
\begin{document}
\begin{tikzpicture}
\node (A) at (2*rand,2*rand) {A};
\node (B) at (2*rand,2*rand) {B};
\node (C) at (2*rand,2*rand) {C};
\node (D) at (2*rand,2*rand) {D};
\path let \p1=($(A)!0.5!(B)$),
\p2=($(C)!0.5!(D)$) in node[blue] at (\x1,\y2) {X};
\node[green, |-={$(A)!0.5!(B)$}{$(C)!0.5!(D)$}] at (\tempx,\tempy) {Y};
\node[yellow,-|={$(C)!0.5!(D)$}{$(A)!0.5!(B)$}] at (\tempx,\tempy) {Z};
\end{tikzpicture}
\end{document}