有人知道如何使用 TikZ-PGF 创建角对齐虚线矩形吗?我正在寻找 Adobe Illustrator 中存在的类似功能(请参阅http://tv.adobe.com/watch/learn-illustrator-cs5/creating-corneraligned-dashed-lines/)我无法找到此功能或 TikZ 的解决方法。
答案1
如果您不了解装饰,可能会有点复杂,但我认为这或多或少是必需的。它仅支持单个虚线开启虚线关闭模式(没有花哨的短虚线和长虚线组合),并且虚线之间间隙的自动调整可能需要更复杂一些。
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations}
\makeatletter
\def\pgf@dec@dashon{5pt}
\def\pgf@dec@dashoff{5pt}
\pgfkeys{/pgf/decoration/.cd,
dash on/.store in=\pgf@dec@dashon,
dash off/.store in=\pgf@dec@dashoff
}
\pgfdeclaredecoration{aligned dash}{start}{
\state{start}[width=0pt, next state=pre-corner,persistent precomputation={
\pgfextract@process\pgffirstpoint{\pgfpointdecoratedinputsegmentfirst}%
\pgfextract@process\pgfsecondpoint{\pgfpointdecoratedinputsegmentlast}%
\pgfmathsetlengthmacro\pgf@dec@dashon{\pgf@dec@dashon}%
\pgfmathsetlengthmacro\pgf@dec@dashoff{\pgf@dec@dashoff}%
\pgfmathsetlengthmacro\pgf@dec@halfdash{\pgf@dec@dashon/2}%
}]{}
\state{pre-corner}[width=\pgfdecoratedinputsegmentlength, next state=post-corner, persistent precomputation={
%
\pgfmathparse{int(ceil((\pgfdecoratedinputsegmentlength-\pgf@dec@dashon-\pgf@dec@dashoff)/(\pgf@dec@dashon+\pgf@dec@dashoff)))}%
\let\pgf@n=\pgfmathresult
\pgfmathsetlengthmacro\pgf@b%
{\pgfdecoratedinputsegmentlength/(\pgf@n+1)-\pgf@dec@dashon}%
\ifdim\pgf@b<\pgf@dec@dashoff\relax%
\pgfmathparse{int(\pgf@n-1)}\let\pgf@n=\pgfmathresult%
\pgfmathsetlengthmacro\pgf@b%
{\pgfdecoratedinputsegmentlength/(\pgf@n+1)-\pgf@dec@dashon}%
\fi%
\pgfmathsetlengthmacro\pgf@b{\pgf@b+\pgf@dec@dashon}%
}]{%
\pgfmathloop
\ifnum\pgfmathcounter>\pgf@n%
\else%
\pgfpathmoveto{\pgfpoint{\pgf@b*\pgfmathcounter-\pgf@dec@halfdash}{0pt}}%
\pgfpathlineto{\pgfpoint{\pgf@b*\pgfmathcounter+\pgf@dec@halfdash}{0pt}}%
\repeatpgfmathloop%
\pgfpathmoveto%
{\pgfpoint{\pgfdecoratedinputsegmentlength-\pgf@dec@halfdash}{0pt}}%
\pgfpathlineto%
{\pgfpointdecoratedinputsegmentlast}
}
\state{post-corner}[width=0pt, next state=pre-corner]{
\pgfpathlineto{\pgfpoint{\pgf@dec@halfdash}{0pt}}%
}
\state{final}{
\pgftransformreset%
\pgfpathlineto{\pgfpointlineatdistance{\pgf@dec@halfdash}{\pgffirstpoint}{\pgfsecondpoint}}%
}
}
\tikzset{aligned dash/.style={
decoration={aligned dash, #1}, decorate
}}
\begin{document}
\begin{tikzpicture}
\foreach \c [count=\i] in {red, green, blue}
\foreach \j in {3,...,6}
\draw [draw=\c, thick, aligned dash={dash on=\i*3pt, dash off=2pt}]
[shift={(\i*3,\j*3)}]
(90:1) \foreach \k in {1,...,\j}{ -- (\k*360/\j+90:1) } -- cycle;
\end{tikzpicture}
\end{document}
装饰不要求边的长度相同:
\begin{tikzpicture}
\draw [blue, thick, aligned dash] (0,3) rectangle (3,2);
\draw [red, thick, aligned dash] (0:1)
\foreach \i in {60,120,...,300}{ -- (\i:1+rnd) } -- cycle;
\end{tikzpicture}