# Create corner-aligned dashed rectangles using TikZ

Does anyone know how to create corner-aligned dashed rectangles using TikZ-PGF? I am looking for a similar feature that exists in Adobe Illustrator (see http://tv.adobe.com/watch/learn-illustrator-cs5/creating-corneraligned-dashed-lines/) I am not able to find this feature or a workaround for TikZ.

• Set the anchors appropriately? E.g. anchor=south west and anchor=north west or anchor=north west and anchor=north east or whatever? (Note that what AI does is of absolutely no help to me.)
– cfr
Nov 26, 2015 at 20:24
• How acout only drawing three (or less) sides for all after the first? The first one would e.g. be \draw (A) -- (B) -- (C) -- (D) -- cycle; and the one right of it \draw (B) -- (E) -- (F) -- (C);. Nov 27, 2015 at 0:36

## 1 Answer

A bit involved if you don't understand decorations, but I think this is more-or-less what is required. It only supports a single dash-on dash-off pattern (no fancy short and long dash combinations), and the automatic adjustments for the gap between the dashes may need to be a bit more sophisticated.

\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}


The decoration does not require the sides to be the same length:

\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}


• ,@MarkWibrow (+1) Awesome ... I wonder if this could be added to the libraries of TikZ, for example \usetikzlibrary{aligned-dashed} would be really helpful? Nov 27, 2015 at 9:53
• @MarkWibrow Thanks! Could anyone please send me the code for a simple rectangle in the aligned-dashed style? So without rotations and an option to make one side larger than the other. Nov 30, 2015 at 13:52
• @user89685 the decoration also works with uneven length sides, for example \draw [black, thick, aligned dash] (0,0) rectangle (3,2);` Dec 2, 2015 at 14:46