箭头和多部分矩形的奇怪行为

箭头和多部分矩形的奇怪行为

我最近发布了一个问题使用 TikZ 绘制 DNA 序列的显示问题。我描述的问题大部分都已解决,但仍有一个问题。我设法简化了我的示例,以更清楚地显示该问题。请考虑以下代码。

在此代码中,两个多部分矩形之间绘制的线两侧都有箭头。我没想到左边会有箭头。请注意,左边的箭头指向向上。删除two north会使左箭头消失。

现在,如果添加了选项shorten >=1cm,那么我们只会看到一个向上的箭头尖漂浮在空间中,与右侧的缩短箭头处于同一水平。如果我们改为这样做shorten <=1cm, shorten >=1cm,那么两端的线条正确终止处都会有箭头,左侧箭头像以前一样指向上方。

在所有这些情况下,普通矩形的行为都是符合预期的。

有人能解释这种行为吗?

\documentclass[preview]{standalone}
\usepackage{tikz}
\usepackage[skip=2pt]{caption}
\usetikzlibrary{shapes, arrows}
\settowidth{\textwidth}{Multipart rectangles with no line shortening}
\begin{document}
\centering
\begin{tikzpicture}
\tikzstyle{line} = [draw, -latex']

% Multipart rectangle nodes

\tikzstyle{seq}=[rectangle split, rectangle split horizontal, rectangle split parts=#1, draw]

\node [seq=3] (leftrow1) at (0cm, 4cm){};
\node [seq=3] (tripletoprow)  at (4cm, 4cm){};

% Add arrows on the top

%\path [line, shorten >=1cm] (leftrow1.two north) edge[out=90, in=90] node {}(tripletoprow);
%\path [line, shorten <=1cm, shorten >=1cm] (leftrow1.two north) edge[out=90, in=90] node {}(tripletoprow);
%\path [line, shorten <=1cm] (leftrow1.two north) edge[out=90, in=90] node {}(tripletoprow);
\path [line] (leftrow1.two north) edge[out=90, in=90] node {}(tripletoprow);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Regular rectangle nodes

%\tikzstyle{seq}=[rectangle, draw]

% Regular rectangle nodes
%\node [seq] (leftrow1) at (0cm, 4cm){};
%\node [seq] (tripletoprow)  at (4cm, 4cm){};

% Add arrows on the top
%\path [line, shorten >=1cm] (leftrow1) edge[out=90, in=90] node {}(tripletoprow);
%\path [line, shorten <=1cm, shorten >=1cm] (leftrow1) edge[out=90, in=90] node {}(tripletoprow);
%\path [line, shorten <=1cm] (leftrow1) edge[out=90, in=90] node {}(tripletoprow);
%\path [line] (leftrow1) edge[out=90, in=90] node {}(tripletoprow);

\end{tikzpicture}
\captionof{figure}{Multipart rectangles with no line shortening}
\end{document}

在此处输入图片描述

答案注释:感谢 percusse 回答了这个问题。我在这里添加了一些关于答案的注释。在这种情况下,阅读文档会很有帮助。:-) PGF/TikZ 手册edge在第 16.12 节(从第 197 页开始)记录了该操作。在本节(第 197 页)的开头,手册说:

边操作的工作方式类似于在绘制主路径后添加的 to 操作,就像在绘制主路径后添加节点一样。这允许您让每条边具有不同的外观。

重点是“在主路径绘制后添加”这一点。让我们看看我示例中的路径,即

\path [line] (leftrow1.two north) edge[out=90, in=90] node {}(tripletoprow);

我的想法是绘制一条从节点leftrow1到节点以箭头终止的路径tripletoprow

事实上,两条路径被绘制了。我不知道 TikZ 是如何解析这段代码的,但既然命令edge是在“主路径绘制之后”添加的,那么“主路径”是什么?嗯,它必须在边缘之前,所以必须是

\path [line] (leftrow1.two north) node {};

如果您仅绘制此图形,您将看到只生成了一个箭头,从多部分矩形指向北方leftrow1。如果删除,则不会出现此箭头node {}。我不确定为什么。无论如何,关键是这是一条长度为零的路径。它开始和终止于(leftrow1.two north)并表现为箭头。所以,这是第一条路径。绘制的第二条路径是边缘,它也是一条以箭头为终点的路径,因为(第 198 页)

可以看出,边缘操作的路径继承了主路径的选项,但您可以在本地否决它们。

因此,两侧带有箭头的奇怪路径实际上是两条路径,一条长度为零,一条长度不为零,但两条路径都以箭头结尾。使用缩短不会改变任何东西。它只是将所有内容向上移动了一点。

那么,应该如何解决这个问题?最简单的方法就是不要使用edge。在这里使用它并不是正确的选择。只需使用

\path [line] (leftrow1.two north) to[out=90, in=90] node {}(tripletoprow);

意味着只会绘制一条路径 - 不绘制零长度路径。或者,可以抑制零长度路径的绘制并保留边缘操作,例如

\path [] (leftrow1.two north) edge[out=90, in=90, line] node {}(tripletoprow);

但这无疑是两种选择中不太自然的一种。

最后一件事 - 我写了

在所有这些情况下,普通矩形的行为都是符合预期的。

事实并非如此。在我发布的普通(非多形状)矩形示例中没有看到这种行为的原因是north那里没有使用锚点。因此,例如,如果我们替换

\path [line] (leftrow1) edge[out=90, in=90] node {}(tripletoprow);

\path [line] (leftrow1.north) edge[out=90, in=90] node {}(tripletoprow);

我们看到了同样的行为。

答案1

好吧,这个有点奇怪,但我想我知道发生了什么。让我稍微绕个弯:考虑以下结构

\draw (0,0) -- (1,1) node (a) {A};.

我们希望这段代码在创建主路径后放置一个节点。请注意,节点不知道路径的性质。即使我们使用[pos=0.xx]它,也只是寻找最后一条可用路径,因此节点放置和路径创建之间没有有机联系。

事实证明,这edge是一个to以类似方式添加的操作,与之前构建的主路径没有任何关系。另一个示例(放大)

\begin{tikzpicture}
\path[->,
     draw,
     line width=1mm % To make the arrowhead bigger
     ] (0,0);
\end{tikzpicture}

在此处输入图片描述

因此,箭头的路径长度为零。如果我们剖析其中一条路径,边缘也会发生同样的情况

\path [line] (leftrow1.two north) % This is the main path as the example above 
     edge[out=90, in=90] node {}(tripletoprow); % This is added afterwards without the 
                                                % line option in place creating the
                                                % illusion that the path is having 
                                                % a disconnected arrowhead

line因此缩短会使情况变得更糟,因为它会缩短零长度路径,使箭头更远。一旦我们解决了问题,那么通过将选项转移到edge;来轻松解决问题就很容易了

\documentclass[preview,tikz,border=3mm]{standalone}
\usetikzlibrary{shapes, arrows}
\tikzset{line/.style={draw, latex'-},
     seq/.style={rectangle split, rectangle split horizontal, rectangle split parts=#1, draw}
}
\begin{document}
\begin{tikzpicture}
\node [seq=3] (leftrow1) at (0cm, 4cm){};
\node [seq=3] (tripletoprow)  at (4cm, 4cm){};
\path (leftrow1.two north) edge[out=90, in=90,line] (tripletoprow);
\end{tikzpicture}
\end{document}

在此处输入图片描述

另请参阅手册进行操作,以避免目标点之前的\tikztonodes多余部分。node{}

答案2

这其实不是问题,但这是一个非常好的功能。要获取主路径,您只需删除edge[options] (a,b)

例子 :

  1. 主路径为\draw[blue,->] (0,0) edge[red] (3,0)(0,0)
  2. \draw[blue,->] (0,0) edge[red] (3,0) to (1,1);主路径中(0,0) to (1,1)
  3. \draw (0,0) edge [out=60,in=60,red,->] (4,0) edge [blue,-o] (2,3);主路径 (0,0)
  4. \draw[blue,->] (0,0) to (1,0) edge [red,dashed] (2,1) to (3,0) edge [red,dashed] (4,1) to (5,0);主路径(0,0) to (1,0) to (3,0) to (5,0)

结论: 中的选项\draw应用于主路径,edge就像绘制命令后将节点添加到主路径一样。

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{arrows}

\begin{document}

 \tikz \draw(0,0) edge [out=60,in=60,red,->] (4,0) edge [blue,-o] (2,3);
 \tikz \draw[blue,->] (0,0) to (1,0) edge [red,dashed] (2,1) 
                             to (3,0) edge [red,dashed] (4,1) 
                             to (5,0);
 \tikz \draw[blue,->] (0,0) edge[red] (3,0) to (1,1);                      

\end{document}

在此处输入图片描述

相关内容