20

Is it possible to compute the length of a generic curve in TikZ?

An answer to this question would solve TikZ dashes and closed curves as follows: Let lc be the length of the curve and lp the desired length of the dash pattern. All we have to do is rescale the dash pattern to the length lc/round(lc/lp).

gTcV
  • 1,065
  • The decoration module provides some internal macros for approximating the length of the curve. But considering the application, possibly your question is answered here. – Mark Wibrow Nov 28 '14 at 15:00

1 Answers1

22

Improved version:

You can use a decoration and \pgfdecoratedpathlength:

enter image description here

The code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\makeatletter
\tikzset{%
    measureme/.style={
    decoration={
        markings,
        mark=at position 1 with {\node[below,black,anchor=west] {My length is \pgfdecoratedpathlength};},
    },
    postaction=decorate
}
}
\makeatother
\begin{document}

\begin{tikzpicture}[line width=2pt]
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) -- (B);
\begin{scope}[yshift=-1cm]
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) arc[start angle=180,end angle=0,radius=10pt];
\end{scope}
\begin{scope}[yshift=-2.5cm]
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) .. controls(0.25,2) and (0.75,-2) .. (B);
\end{scope}
\begin{scope}[yshift=-5cm]
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) .. controls(0.25,7) and (0.75,-7) .. (B);
\end{scope}
\end{tikzpicture}

\end{document}

Initial version:

Here's an option using decorations and the distance from start key:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\makeatletter
\tikzset{%
    measureme/.style={
    decoration={
        markings,
        mark=at position -.01pt with {%
            \pgfkeysgetvalue{/pgf/decoration/mark info/distance from start}\@totallength
            \global\let\@totallength\@totallength
        },
        mark=at position 0 with {\node[black] {\@totallength};},
    },
    postaction=decorate
}
}
\makeatother
\begin{document}

\begin{tikzpicture}
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) -- (B);
\begin{scope}[xshift=3cm]
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) .. controls(0.25,2) and (0.75,-2) .. (B);
\end{scope}
\begin{scope}[xshift=6cm]
\coordinate (A); 
\coordinate (B) at (20pt,0);
\draw[cyan,measureme] (A) .. controls(0.25,7) and (0.75,-7) .. (B);
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

Gonzalo Medina
  • 505,128
  • When I implement these very nice solutions sometimes I get the length and when the shape of the Bezier changes, ie different endpoint, then the length do not show!!! What happens? – the world is not flat May 31 '18 at 15:58