# Is there a TikZ dashed line decorator or some other way to make part of a path dashed?

## The problem

I would like to draw a parabolic path in TikZ that changes (abruptly) from a continuous line to a dashed line. The obvious way to change the appearance of a path over the course of its length is using the decoration library however no dashed line decorator exists. Is there an easy way to do this that doesn't involve drawing multiple concatenated parabolas?

Werner's suggestion (which has now converted into an answer) works pretty well! But is there an easier way?

-
If you know the changeover location, you could draw two parabolas (one with a solid line, the other with a dashed line) and clip each using some mutually exclusive clipping path that touch at the changeover location. – Werner Nov 5 '11 at 3:05
@Werner - I don't know why I didn't think of that. I was thinking that I would have to draw several unique parabola segments. Took me a few minutes of stuffing around to get the clipping rectangles in the right places but it does the job. Thanks :) – Richard Terrett Nov 5 '11 at 3:28

A solution with decoration. the problem is to calculate the length in each cases and other problem the length depends of the scaling coefficient. Interesting would be to create a macro to calculate the length of path between two nodes.

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{decorations}
\usetikzlibrary{intersections}
\begin{document}

\begin{tikzpicture}[scale=3.14159]

\tikzset{
solid part/.style={%
postaction={solid, decorate, draw,
decoration={moveto,
pre=curveto,
post=curveto,
pre length=#1,
post length=0}}
}
}
\draw[name path=curve 1,<->,color=red,dashed,solid part=3.5cm] (0,0) parabola[parabola height=-0.5cm] (1,0);

\draw[name path=curve 2,<->,dashed,solid part=1.7cm] (0.5,.125) parabola[parabola height=-0.5cm] (1.5,0.125);

\fill [name intersections={of=curve 1 and curve 2, by={a}}]
(a) circle (.5pt);
\fill (0.81,-0.305) circle (0.5pt);
\node[above]  at (a) {a};
\fill (0.5,-0.5) circle (0.5pt);
\node (c) at (0.5,-0.4) {c};
\fill (1,-0.375) circle (0.5pt);
\node (e) at (1,-0.275) {e};
\end{tikzpicture}

\end{document}


-

For what it's worth, here is a similar graphic produced using pstricks. The code should be self-explanatory for those familiar with pstricks, or even tikz/pgf:

\documentclass{article}
\usepackage{pstricks}% http://www.tug.org/PSTricks/main.cgi
\begin{document}

\begin{pspicture*}(-6.2,-6.2)(6.2,6.2)
\psset{unit=5mm,plotpoints=200,algebraic=true,arrows=<->,linewidth=1pt}%
\psclip{\psframe[linestyle=none,linewidth=0pt](-5.5,-1)(3.2045,10)}%
\psplot[linecolor=red,linestyle=solid]{-5.5}{5.5}{0.2*x^2}
\endpsclip

\psclip{\psframe[linestyle=none,linewidth=0pt](3.2045,-1)(5.5,10)}%
\psplot[linecolor=red,linestyle=dashed]{-5.5}{5.5}{0.2*x^2}
\endpsclip

\psclip{\psframe[linestyle=none,linewidth=0pt](3.2045,-1)(15,10)}%
\rput(5.5,1){%
\psplot[linecolor=black,linestyle=solid]{-5.5}{5.5}{0.2*x^2}}
\endpsclip

\psclip{\psframe[linestyle=none,linewidth=0pt](-5.5,-1)(3.2045,10)}%
\rput(5.5,1){%
\psplot[linecolor=black,linestyle=dashed]{-5.5}{5.5}{0.2*x^2}}
\endpsclip

\psdot(0,0) \uput{10pt}[u]{0}(0,0){c}%
\psdot(5.5,1) \uput{10pt}[u]{0}(5.5,1){a}%
\psdot(3.2045,2.0538) \uput{10pt}[u]{0}(3.2045,2.0538){e}%
\end{pspicture*}

\end{document}

-
Nice answer. You could put \psset{unit=5mm,plotpoints=200,algebraic=true,arrows=<->,linewidth=1pt} where you have \psset{unit=5mm} and then delete these options from the 4 plots, it would help global changes later on, and code readability :) It's only the linecolor and the linestyle that changes. – cmhughes Nov 5 '11 at 16:11
@cmhughes: Thanks - much better. – Werner Nov 5 '11 at 16:19

You can use the decoration library as you suggested. There is in fact a decoration that can be made to look like a dashed line, the border decoration from the pathreplacing family. A very simple example looks like this:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}
\begin{tikzpicture}[decoration={border, segment length=4pt,amplitude=2pt, angle=0}]
\draw [help lines] grid (3,2);
\draw [decorate] (0,0) -- (3,2);
\end{tikzpicture}
\end{document}


From your apparent familiarity with modifying decorations I presume that you will be able to apply this to your problem.

-

On Werner's advice, here is the implementation of the suggested method (draw each parabola, use path clipping) and a MWE. I stripped out the chartcruft of the original.

\documentclass{minimal}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}[scale=3.14159]
\begin{scope}
\clip (0.8,0) rectangle (1.5,-0.5);
\draw[<->,color=red,dashed] (0,0) parabola[parabola height=-0.5cm] (1,0);
\end{scope}

\begin{scope}
\clip (-0.1,0) rectangle (0.8,-0.5);
\draw[<->,color=red] (0,0) parabola[parabola height=-0.5cm] (1,0);
\end{scope}

\begin{scope}
\clip (-0.1,0.2) rectangle (0.8,-0.5);
\draw[<->,dashed] (0.5,.125) parabola[parabola height=-0.5cm] (1.5,0.125);
\end{scope}

\begin{scope}
\clip (0.8,0.2) rectangle (1.6,-0.5);
\draw[<->] (0.5,.125) parabola[parabola height=-0.5cm] (1.5,0.125);
\end{scope}
\fill (0.81,-0.305) circle (0.5pt);
\node (oh) at (0.81,-0.205) {a};
\fill (0.5,-0.5) circle (0.5pt);
\node (c) at (0.5,-0.4) {c};
\fill (1,-0.375) circle (0.5pt);
\node (e) at (1,-0.275) {e};
\end{tikzpicture}

\end{document}

-
As a little extra, you could use the intersections library to find the intersection point so that you know where to clip to (then some fancy stuff using the current bounding box or the current page to make the clip as big as it needs to be without having to specify any coordinates at all). – Loop Space Nov 5 '11 at 17:46