7

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.

enter image description here

2
  • 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 '15 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 '15 at 0:36
10

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}

enter image description here

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}

enter image description here

3
  • ,@MarkWibrow (+1) Awesome ... I wonder if this could be added to the libraries of TikZ, for example \usetikzlibrary{aligned-dashed} would be really helpful?
    – AboAmmar
    Nov 27 '15 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.
    – user89685
    Nov 30 '15 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 '15 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.