在 TikZ 中结合 |- 和 !.5!

在 TikZ 中结合 |- 和 !.5!

如何将!.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)。这两个coordinates 可能非常通用(节点、长度、所有这类东西),因此它非常明智地将它们发送回解析器进行重新处理。 这是一个新实例因此从理论上讲,这些可能涉及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}

输出

输出

相关内容