17

When a closed curve is dashed, the dash spacing at the start/end point can be very unfortunate. Is there an option to tell TikZ that it should slightly adapt the dash spacing to avoid such cases? (I could of course do this myself, but I have many such curves thus it is tedious. )

Here is an example problem:

\documentclass[tikz,border=5]{standalone}
\begin{document}
\begin{tikzpicture}
    \draw [dashed, line width=1pt]circle(0.655cm);
\end{tikzpicture}
\end{document}

enter image description here

gTcV
  • 1,065
  • Created a question aiming at a possible solution: http://tex.stackexchange.com/questions/214429/length-of-curve-in-tikz – gTcV Nov 28 '14 at 13:24

2 Answers2

14

Use dash pattern

\documentclass[border=5]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \draw [line width=.5pt,dash pattern=on 1pt off 2pt]circle(0.655cm);
\end{tikzpicture}
\end{document}

enter image description here

See also pag. 168 of the manual

d-cmst
  • 23,095
  • 2
    That's the "I could of course do it myself" solution. – gTcV Nov 28 '14 at 13:11
  • @gTcV Yeah, sorry, I actually missed that part of your question. Would you like me to delete my answer so that you get more visibility? – d-cmst Nov 28 '14 at 14:24
  • For those who do not know dash pattern, it explicitly shows the "by hand" solution. So I guess your answer does contribute something. After all, you've been upvoted, so it obviously is useful to someone. – gTcV Nov 28 '14 at 15:09
7

Here is a solution:

\documentclass[border=5]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}

\tikzset{
    cycled dash pattern/.code args={on #1 off #2}{
        % Use csname so catcode of @ doesn't have do be changed.
        \csname tikz@addoption\endcsname{%
            \pgfgetpath\currentpath%
            \csname pgf@decorate@parsesoftpath\endcsname{\currentpath}{\currentpath}%
            % Length of path
            \pgfmathparse{\csname pgf@decorate@totalpathlength\endcsname}\let\lc=\pgfmathresult%
            % Length of pattern
            \pgfmathparse{#1+#2}\let\lp=\pgfmathresult%
            % Scaling factor for pattern
            \pgfmathparse{\lc/(\lp*round(\lc/\lp))}\let\f=\pgfmathresult%
            % Actually scale the pattern
            \pgfmathparse{#1*\f}\let\on=\pgfmathresult%
            \pgfmathparse{#2*\f}\let\off=\pgfmathresult%
            % Tell PGF to dash this line
            \pgfsetdash{{\on}{\off}}{0pt}}%
    }
}

\begin{document}
\begin{tikzpicture}
    % The built-in version for comparison
    \draw [line width=1pt, dash pattern=on 4pt off 4pt] (0,0) circle(0.655);
    % Our version with automatically adapted pattern length
    \draw [line width=1pt, cycled dash pattern=on 4pt off 4pt] (2,0) circle(0.655);
\end{tikzpicture}
\end{document}

Most of the code is taken from Can TikZ dashed lines emulate PSTricks dashed lines?. I only adapted it such that the dashing starts with an on and ends with an off, in contrast to the referenced answer where the dashing starts and ends with an on).

gTcV
  • 1,065
  • I appreciate your efforts, but unfortunately, it doesn't always function as expected. For instance, when applied to a rectangle with rounded corners, it throws an error: "Package pgf Error: Unrecognised soft path token `."

    The most recent version of Mark Wibrow's code in the linked answer does function for me, but it's not designed for closed lines and it draws the starting and ending dashes connected. Any chance you could update your answer? Thanks!

    – Edoardo Serra Mar 30 '24 at 00:16