在 TikZ 中有没有更好的方法用相对坐标进行相交和计算?

在 TikZ 中有没有更好的方法用相对坐标进行相交和计算?

最近我一直在做很多 TikZ 图表,时不时地我会遇到被迫coordinate在 中使用一些临时变量的情况\path。在下面的简短示例中,问题在于绘制红线:

MWE 的输出

\documentclass{article}
\usepackage{tikz}
%\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

% Angled line connecting to a straigt line. This is where my problem lies.
\draw[red] (A.140) -- ++(0,1) coordinate(temp) -- (temp -| B.50);

% Some examples of what I think would be useful in this case.
% None of these things seem to be supported in TikZ.
%\draw[red] (A.140) |- (+(0,1) -| B.50);
%\draw[red] (A.140) -- ++(1,0) -- (\currentcoordinate -| B.50);
%\draw[red] (A.140) |- ($(B.50).x, (+(0,1)).y$);
\end{tikzpicture}
\end{document}

所以我想知道是否有更好的方法来绘制红线。我说的“更好”是指更简洁,没有重复,最好没有($calculations$)。我认为可能有用的一些示例作为注释包含在代码中。

由于“更好”主要是一个品味问题,我将我的问题分解为我认为可能有助于解决问题的内容:

  1. 是否可以在交叉点语法中使用相对坐标(a -| b)
  2. 是否有某种方式(宏或其他)来访问現在座標当前路径?
  3. 是否可以在计算语法中使用相对坐标($(a) + (b)$)
  4. 除了语法之外,还有其他方法可以将x一个坐标的 -Part 与另一个坐标的 -Part 结合起来吗?它可以与相对坐标一起使用吗?y(a -| b)

答案1

在尝试回答您的问题之前,我想先澄清一下,这一切都是基于实验并试图遵循代码的运行方式。所以这只是一个猜测 - 但希望是明智的猜测。

  1. 是否可以在交叉点语法 (a -| b) 中使用相对坐标?

    不是的。TikZ 看到的是-|并假设语法是(coordinate -| coordinate)。然后它将坐标传回解析器,但它这样做了(coordinate)(因为-|语法中坐标周围没有括号)。

    但是,没有什么可以阻止您定义一个新的坐标系,该坐标系实际上是一个相对坐标系。分组时必须小心一点,因为 TikZ 通过寻找线索来解析坐标,因此执行这些线索的顺序很重要。

  2. 是否有某种方法(宏或其他)可以访问当前路径的当前坐标?

    据我所知,还没有,但定义一个非常容易。

  3. 是否可以在计算语法($(a) + (b)$)中使用相对坐标?

    不,但是一旦你有了\currentcoordinate宏,那么就可以很容易地使用它来制作相对坐标,并且一旦你有一个额外的相对坐标系,那么它也可以使用它。

  4. 除了 (a -| b) 语法之外,还有其他方法可以将一个坐标的 x 部分与另一个坐标的 y 部分结合起来吗?它可以与相对坐标一起使用吗?

    是的!(终于)可以使用let语法(PGF 手册第 14.15 节,版本 2.10)来完成此操作。

这是一个包含上述内容的示例。它没有经过压力测试,因此在更高级的情况下,可能会出现一些问题。

\documentclass{article}
%\url{http://tex.stackexchange.com/q/53734/86}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\newcommand\currentcoordinate{\the\tikz@lastxsaved,\the\tikz@lastysaved}

\tikzdeclarecoordinatesystem{+}{%
  \tikz@scan@one@point\pgfutil@firstofone+(#1)%
}

\makeatother

\begin{document}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

% Angled line connecting to a straigt line. This is where my problem lies.
\draw[red] (A.140) -- ++(0,1) coordinate(temp) -- (temp -| B.50);
\end{tikzpicture}

% Some examples of what I think would be useful in this case.
% None of these things seem to be supported in TikZ.
\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) |- ({{$(\currentcoordinate)+(0,1)$}} -| B.50);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) |- ({+ cs:0,1} -| B.50);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) |- ($(+ cs:0,1) + (2,0)$);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) -- ++(0,1) -- (\currentcoordinate -| B.50);
\end{tikzpicture}

\begin{tikzpicture}
% Some nodes. Precise coordinates are unknown.
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) let \p1=(B.50), \p2=+(0,1) in |- (\x1,\y2);
\end{tikzpicture}
\end{document}

结果:

各种相对坐标

答案2

对于像这样的高级路径命令,to paths 值得一看。它们允许您根据 和 指定两个坐标之间的路径(\tikztostart)(\tikztoend)这为您提供了极大的灵活性。

对于你的例子,可以定义to path一个

(\tikztostart)
-- ($(\tikztostart)+(0,1)$)
-- ({{$(\tikztostart)+(0,1)$}}-|\tikztotarget)

请注意,括号有点棘手,Andrew Stacey 对所需的内容进行了很好的分析在 TikZ 中结合 |- 和 !.5!

您甚至可以参数化to path表达式。以下是如何使用的示例:

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

\tikzset{
    rect connect/.style={
        to path={
            (\tikztostart)
            -- ($(\tikztostart)+(0,#1)$)
            -- (
                perpendicular cs:
                horizontal line through={($(\tikztostart)+(0,#1)$)},
                vertical line through={(\tikztotarget)}
            )
        }
    },
    rect connect/.default=1
}

\begin{tikzpicture}
\node[draw] at (1,1) (A) {Node};
\node[draw, right of=A, above right=0.5cm] (B) {Other Node};
\draw (B.50) -- ++(0,1);

\draw[red] (A.140) to [rect connect] (B.50);
\draw[blue] (A.70) to [rect connect=1.3] (B.50);

\end{tikzpicture}
\end{document}

相关内容