“缩短 >”命令后行尾的修饰

“缩短 >”命令后行尾的修饰

我有一种在行尾放置箭头的风格:

\makeatletter
\tikzset{nomorepostaction/.code={\let\tikz@postactions\pgfutil@empty}}
\makeatother
\tikzset{mystyle/.style={
    shorten >=0.5pt,
    postaction={
        nomorepostaction,
        decorate,
        decoration={
            markings,
            mark=at position 1 with {\arrow[semithick]{>}}
        }
    }
}}

我需要这样做,因为这正是我想要的“半粗”箭头。但如果我缩短一条线,箭头就会画在错误的位置:

\draw [mystyle, shorten >=5pt] (0,0) to (2,0);

在我看来,问题是由“在位置 1”部分引起的,它指的是行尾,但没有实施任何缩短。

所以,我的问题是:我如何定义一种样式来可靠地将装饰放在行尾(或与行尾固定偏移量),这对于因“缩短 <”和“缩短 >”而导致的行缩短或加长具有鲁棒性?

答案1

这是对实际问题的回答(我仍然认为定义一个新的箭头会更优雅)。这使用了 Caramdir 的回答使用 TikZ 标记放置箭头扩展了mark=at position,使其能够处理算术。再加上长度\pgf@shorten@end@additional(和\pgf@shorten@start@additional)中保存的缩短,这似乎可以解决问题(至少对于这个例子来说,我不知道它是否更普遍)。

顺便说一句,shorten >键不是累积的,因此装饰shorten >=0.5pt中的mystyle会被实际使用中的覆盖shorten >=5pt。我不确定你是否希望箭头被拉回额外的 0.5pt不管该行已经缩短了多少,我在下面给出了各种替代方案。希望这些内容足以让您找到最适合您实际用途的方案。

\documentclass[border=10]{standalone}
% \url{https://tex.stackexchange.com/q/25830/86}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\makeatletter
% overwrite the number parsing macro from pgflibrarydecorations.markings
\def\pgf@lib@dec@parsenum#1{%
    \gdef\pgf@lib@dec@computed@width{0 pt}%
    \tsx@pgf@lib@dec@parsenum#1+endmarker+%
    \ifdim\pgf@lib@dec@computed@width<0pt\relax%
        \pgfmathparse{\pgfdecoratedpathlength\pgf@lib@dec@computed@width}
        \edef\pgf@lib@dec@computed@width{\pgfmathresult pt}%
    \fi%
}

\def\tsx@pgf@lib@dec@parsenum@endmarker{endmarker}

% this is iterated over all numbers that are summed
\def\tsx@pgf@lib@dec@parsenum#1+{
    \def\temp{#1}%
    \ifx\temp\tsx@pgf@lib@dec@parsenum@endmarker%
    \else%
        \tsx@pgf@lib@dec@parsenum@one{#1}%
        \expandafter\tsx@pgf@lib@dec@parsenum%
    \fi%
}

% calculate the length for each number
\def\tsx@pgf@lib@dec@parsenum@one#1{%
  \pgfmathparse{#1}%
  \ifpgfmathunitsdeclared%
    \pgfmathparse{\pgf@lib@dec@computed@width + \pgfmathresult pt}%
  \else%
    \pgfmathparse{\pgf@lib@dec@computed@width + \pgfmathresult*\pgfdecoratedpathlength*1pt}%
  \fi%
  \edef\pgf@lib@dec@computed@width{\pgfmathresult pt}%
}

\tikzset{nomorepostaction/.code={\let\tikz@postactions\pgfutil@empty}}
\tikzset{mystyle 1/.style={
    shorten >=0.5pt,
    postaction={
        nomorepostaction,
        decorate,
        decoration={
            markings,
            mark=at position 1 with {\arrow[semithick]{>}}
        }
    }
  },
  mystyle 2/.style={
    postaction={
        nomorepostaction,
        decorate,
        decoration={
            markings,
            mark={at position 1 + - \pgf@shorten@end@additional with {\arrow[semithick]{>}}}
        }
    }
  },
    mystyle 3/.style={
    postaction={
        nomorepostaction,
        decorate,
        decoration={
            markings,
            mark={at position 1 + - \pgf@shorten@end@additional + -0.5pt with {\arrow[semithick]{>}}}
        }
    }
  },
  mystyle 4/.style={
    shorten >=0.5pt,
    postaction={
        nomorepostaction,
        decorate,
        decoration={
            markings,
            mark={at position 1 + - \pgf@shorten@end@additional with {\arrow[semithick]{>}}}
        }
    }
  },
}
\makeatother

\begin{document}
\begin{tikzpicture}
\foreach \st in {1,...,4} {
\begin{scope}[yshift=-\st cm]
\draw [mystyle \st,shorten >=5pt] (0,0) to (2,0);
\draw [mystyle \st] (0,-.5) to (2,-.5);
\end{scope}
}
\end{tikzpicture}
\end{document}

结果:

箭头偏移的箭头

(如果您发现这有用,请在上面的链接中为 Caramdir 的代码投票!我所做的只是剪切和粘贴。)

答案2

这是新的thick arrow。它只是从中获取的正常箭头定义pgfcorearrows.code.tex,并添加了线条\pgfsetlinewidth{...}

编辑:根据 Andrew Stacey 的建议,以下是相同的箭头,但厚度是一个选项。如果您不指定厚度的单位,则该值将乘以线条厚度以获得箭头的厚度。使用的线条厚度是绘制箭头时生效的线条厚度。

发行

\draw [thick arrow] (0,0) to (2,0);
\draw [thick arrow=2pt] (0,-1) to (2,-1);
\draw [line width=2pt,thick arrow=1,shorten >=5pt] (0,-2) to (2,-2);
\draw [line width=2pt,thick arrow=2,shorten >=5pt] (0,-3) to (2,-3);

将产生

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}


\makeatletter
\pgfarrowsdeclare{thickarrow}{thickarrow}
{
  \pgfutil@tempdima=-0.84pt%
  \advance\pgfutil@tempdima by-1.3\pgflinewidth%
  \pgfutil@tempdimb=0.21pt%
  \advance\pgfutil@tempdimb by.625\pgflinewidth%
  \pgfarrowsleftextend{+\pgfutil@tempdima}
  \pgfarrowsrightextend{+\pgfutil@tempdimb}
}
{
  \pgfmathparse{\pgfgetarrowoptions{thickarrow}}%
  \ifpgfmathunitsdeclared%
    \pgfmathparse{\pgfmathresult pt}%
  \else%  
    \pgfmathparse{\pgfmathresult*\pgflinewidth}%
  \fi%
  \let\thickness=\pgfmathresult
  \pgfsetlinewidth{\thickness pt}
  \pgfutil@tempdima=0.28pt%
  \advance\pgfutil@tempdima by.3\pgflinewidth%
  \pgfsetlinewidth{0.8\pgflinewidth}
  \pgfsetdash{}{+0pt}
  \pgfsetroundcap
  \pgfsetroundjoin
  \pgfpathmoveto{\pgfqpoint{-3\pgfutil@tempdima}{4\pgfutil@tempdima}}
  \pgfpathcurveto
  {\pgfqpoint{-2.75\pgfutil@tempdima}{2.5\pgfutil@tempdima}}
  {\pgfqpoint{0pt}{0.25\pgfutil@tempdima}}
  {\pgfqpoint{0.75\pgfutil@tempdima}{0pt}}
  \pgfpathcurveto
  {\pgfqpoint{0pt}{-0.25\pgfutil@tempdima}}
  {\pgfqpoint{-2.75\pgfutil@tempdima}{-2.5\pgfutil@tempdima}}
  {\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}}
  \pgfusepathqstroke
}
\makeatother

\tikzset{
    set thickarrow thickness/.code={
        \pgfsetarrowoptions{thickarrow}{#1}},
    thick arrow/.style={set thickarrow thickness=#1,-thickarrow},
    thick arrow/.default=0.6pt
}


\begin{document}

\begin{tikzpicture}[transform canvas={scale=3}]
\draw [thick arrow] (0,0) to (2,0);
\draw [thick arrow=2pt] (0,-1) to (2,-1);
\draw [line width=2pt,thick arrow=1,shorten >=5pt] (0,-2) to (2,-2);
\draw [line width=2pt,thick arrow=2,shorten >=5pt] (0,-3) to (2,-3);
\draw [thick arrow=2,shorten >=5pt,line width=2pt] (0,-3) to (2,-3);
\end{tikzpicture}
\end{document}

相关内容