你能破解我的箭头非缩短代码吗?

你能破解我的箭头非缩短代码吗?

我知道我们不喜欢代码审查,所以我试图把重点放在结果而不是方法上。

我正在尝试解决的问题: 我的spath3提供在定义 TikZ 路径后保存该路径的功能。目标是保存的路径应该与绘制的路径相同,因此任何改变路径实际形状的样式都应在保存之前应用。然后,当使用路径时,只应应用影响其渲染的样式。困难在于箭头:箭头本身是样式,所以在保存路径时不应该应用,但箭头的位置会改变路径,所以应该应用。理想情况下,我需要将渲染箭头从其放置。不幸的是,处理路径缩短的代码在 PGF 核心中埋藏得很深,很难访问。

我有一些代码可以解决这个问题。它的工作原理是调整箭头所涉及的各种长度,有效地删除控制路径缩短的长度(由于哪个存储箭头定义的长度)。但我需要一个测试套件,所以这才是我在这里真正要求的。

下面是一些可供参考的代码:

\documentclass{article}
%\url{}
\usepackage{tikz}
\usetikzlibrary{
  spath3,
  arrows.meta
}

\makeatletter

\let\spath@orig@pgf@arrow@compute@shortening=\pgf@arrow@compute@shortening

% After \pgf@arrow@compute@shortening then \pgf@xa is the amount to
% shorten the line by, so we will be setting that to 0pt; while
% \pgf@xb is the length of the arrow head so is used to position the
% arrow and so before zeroing \pgf@xa we subtract it from \pgf@xb so
% that the arrow is placed so that its back point is at the current
% position.
\def\spath@arrow@compute@shortening#1{%
  \spath@orig@pgf@arrow@compute@shortening{#1}%
  \advance\pgf@xb by -\pgf@xa%
  \pgf@xa0pt%
}

\tikzset{
  spath/disable arrow shortening/.code={%
    \let\pgf@arrow@compute@shortening=\spath@arrow@compute@shortening
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}[>=Latex, line width=5pt]
% Just a simple line
\draw (0,1) -- +(5,0);
% Same line but with arrows, also save the path
\draw[->.>, spath/save=arrow] (0,0) -- +(5,0);
% Let's redraw that path without the arrows - it's short!
\draw[spath/use={arrow,transform={yshift=-1cm}}];
% So if we redraw it with arrows it gets doubly shortened
\draw[->.>,spath/use={arrow,transform={yshift=-2cm}}];
% If we disable the shortening, the arrows end up in the right place
\draw[->.>,spath/use={arrow,transform={yshift=-3cm}}, spath/disable arrow shortening];
\end{tikzpicture}

\begin{tikzpicture}[>=Latex, line width=5pt]
% Just a simple line
\draw (0,1) to[bend left] +(5,0);
% Same line but with arrows, also save the path
\draw[->.>, spath/save=arrow] (0,0) to[bend left] +(5,0);
% Let's redraw that path without the arrows - it's short! But also distorted
\draw[spath/use={arrow,transform={yshift=-1cm}}];
% So if we redraw it with arrows it gets doubly shortened
\draw[->.>,spath/use={arrow,transform={yshift=-2cm}}];
% If we disable the shortening, the arrows end up in the right place
\draw[->.>,spath/use={arrow,transform={yshift=-3cm}}, spath/disable arrow shortening];
\end{tikzpicture}


\end{document}

得出的结果为:

带箭头的路径,既有缩短的,也有不缩短的

我要求的是一组路径的示例,其中第二条和最后一条路径(带箭头的路径)是不是相同。

答案1

对于非常短的路径,即路径本身比箭头尖短,代码将会中断。箭头尖将转向另一个方向:

\documentclass[border=10pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{
  spath3,
  arrows.meta
}

\makeatletter

\let\spath@orig@pgf@arrow@compute@shortening=\pgf@arrow@compute@shortening

% After \pgf@arrow@compute@shortening then \pgf@xa is the amount to
% shorten the line by, so we will be setting that to 0pt; while
% \pgf@xb is the length of the arrow head so is used to position the
% arrow and so before zeroing \pgf@xa we subtract it from \pgf@xb so
% that the arrow is placed so that its back point is at the current
% position.
\def\spath@arrow@compute@shortening#1{%
  \spath@orig@pgf@arrow@compute@shortening{#1}%
  \advance\pgf@xb by -\pgf@xa%
  \pgf@xa0pt%
}

\tikzset{
  spath/disable arrow shortening/.code={%
    \let\pgf@arrow@compute@shortening=\spath@arrow@compute@shortening
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}[>=Latex, line width=5pt]
% Just a simple line
\draw (0,1) -- ++(1,0);
% Same line but with arrows, also save the path
\draw[->.>, spath/save=arrow] (0,0) -- +(1,0);
% Let's redraw that path without the arrows - it's short! But also distorted
\draw[spath/use={arrow,transform={yshift=-1cm}}];
% So if we redraw it with arrows it gets doubly shortened
\draw[->.>,spath/use={arrow,transform={yshift=-2cm}}];
% If we disable the shortening, the arrows end up in the right place
\draw[->.>,spath/use={arrow,transform={yshift=-3cm}}, spath/disable arrow shortening];
\end{tikzpicture}

\end{document}

在此处输入图片描述

这也适用于由最后一段非常短的段组成的路径,通常情况如下plot

\documentclass[border=10pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{
  spath3,
  arrows.meta
}

\makeatletter

\let\spath@orig@pgf@arrow@compute@shortening=\pgf@arrow@compute@shortening

% After \pgf@arrow@compute@shortening then \pgf@xa is the amount to
% shorten the line by, so we will be setting that to 0pt; while
% \pgf@xb is the length of the arrow head so is used to position the
% arrow and so before zeroing \pgf@xa we subtract it from \pgf@xb so
% that the arrow is placed so that its back point is at the current
% position.
\def\spath@arrow@compute@shortening#1{%
  \spath@orig@pgf@arrow@compute@shortening{#1}%
  \advance\pgf@xb by -\pgf@xa%
  \pgf@xa0pt%
}

\tikzset{
  spath/disable arrow shortening/.code={%
    \let\pgf@arrow@compute@shortening=\spath@arrow@compute@shortening
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}[>=Latex, line width=5pt]
% Just a simple line
\draw (0,1) plot (\x,1);
% Same line but with arrows, also save the path
\draw[->.>, spath/save=arrow] (0,0) plot (\x,0);
% Let's redraw that path without the arrows - it's short! But also distorted
\draw[spath/use={arrow,transform={yshift=-1cm}}];
% So if we redraw it with arrows it gets doubly shortened
\draw[->.>,spath/use={arrow,transform={yshift=-2cm}}];
% If we disable the shortening, the arrows end up in the right place
\draw[->.>,spath/use={arrow,transform={yshift=-3cm}}, spath/disable arrow shortening];
\end{tikzpicture}

\end{document}

在此处输入图片描述

另一个可能也适合这里的变体:

\documentclass[border=10pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{
  spath3,
  arrows.meta
}

\makeatletter

\let\spath@orig@pgf@arrow@compute@shortening=\pgf@arrow@compute@shortening

% After \pgf@arrow@compute@shortening then \pgf@xa is the amount to
% shorten the line by, so we will be setting that to 0pt; while
% \pgf@xb is the length of the arrow head so is used to position the
% arrow and so before zeroing \pgf@xa we subtract it from \pgf@xb so
% that the arrow is placed so that its back point is at the current
% position.
\def\spath@arrow@compute@shortening#1{%
  \spath@orig@pgf@arrow@compute@shortening{#1}%
  \advance\pgf@xb by -\pgf@xa%
  \pgf@xa0pt%
}

\tikzset{
  spath/disable arrow shortening/.code={%
    \let\pgf@arrow@compute@shortening=\spath@arrow@compute@shortening
  }
}
\makeatother

\begin{document}

\begin{tikzpicture}[>=Latex, line width=5pt]
% Just a simple line
\draw (0,1) arc[start angle=270, end angle=300, radius=8];
% Same line but with arrows, also save the path
\draw[->.>, spath/save=arrow] (0,0) arc[start angle=270, end angle=300, radius=8];
% Let's redraw that path without the arrows - it's short! But also distorted
\draw[spath/use={arrow,transform={yshift=-1cm}}];
% So if we redraw it with arrows it gets doubly shortened
\draw[->.>,spath/use={arrow,transform={yshift=-2cm}}];
% If we disable the shortening, the arrows end up in the right place
\draw[->.>,spath/use={arrow,transform={yshift=-3cm}}, spath/disable arrow shortening];
\end{tikzpicture}

\end{document}

在此处输入图片描述

我不确定为什么这里也会出现这个问题,因为路径似乎足够长。但第三条路径末端的扭曲暗示了路径段太短的类似问题。(使用更大的值radius或通过加载bending库,结果再次正确。)

相关内容