Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
1  
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
add comment

4 Answers 4

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.

two intersecting parabolas w/ variation in line style afforded by path clipping

\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}
share|improve this answer
2  
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
add comment

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:

enter image description here

\documentclass{article}
\usepackage{pstricks}% http://www.tug.org/PSTricks/main.cgi
\usepackage{pstricks-add}% http://ctan.org/pkg/pstricks-add
\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}
share|improve this answer
1  
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
add comment

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.

share|improve this answer
add comment

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}  

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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