# Tikz \draw with controls with limited range

How can I limit the drawing of a curve defined with \draw .. controls .. to a specific range?

Example: \draw is defined up till x=9, but I would like to stop the \draw for x>=8

 \draw[->]
(3,1) .. controls (3.75,1.4) and (4.25,1.4) ..
(5,1) .. controls (5.75,0.6) and (6.25,0.6) ..
(7,1) .. controls (7.75,1.4) and (8.25,1.4) ..
(9,1);

• Welcome to TeX.SX! Please help us help you and add a minimal working example (MWE) that illustrates your problem. Reproducing the problem and finding out what the issue is will be much easier when we see compilable code, starting with \documentclass{...} and ending with \end{document}. Sep 13, 2022 at 9:03
• You'd probably need to clip it. Unlike metapost I don't think you can get sub paths out of a tikz path. Sep 13, 2022 at 9:28
• Besides clipping, you could shorten the curve or even use a decoration for that. (There's also \pgfpathcurvebetweentime on the lower level.) But I think the easiest following your instruction (x≥8) would be the \clip. Sep 13, 2022 at 10:23
• Your drawing looks like a sine curve. There might be a better option drawing this with sin and cos path operations. Sep 13, 2022 at 11:01
• Thx @Qrrbrbirlbel . Indeed very similar to sin and cos, and only minor difference. Will yield simpler solution. Thanks for showing the "shorten" feature. New to me. Sep 13, 2022 at 12:26

In your simple case – because you want to stop the curve exactly at half the length and time – you could use the PGF level command \pgfpathcurvebetweentime which has no proper TikZ path operation.

(7,1) .. controls (7.75,1.4) and (8.25,1.4) .. (9,1)


you need to write

(7,1) to[shorten controls={0 .. (7.75,1.4) and (8.25,1.4) .. .5}] (9,1)


where the curve is only drawn between times 0 and 1 - .5. (If both are 0 everything of the curve will be drawn.)

You can't place nodes along that path (but I believe that can be implemented pretty easily).

For more complex situation, I think the best would be to use the spath3 library.

I've also added a very similar curve with sin and cos which doesn't give the exact same curve but might be good enough in your case.

## Code

\documentclass[tikz]{standalone}
\makeatletter
\tikzset{
shorten controls/.code args={#1..#2..#3}{
\pgfutil@in@{and}{#2}%
\ifpgfutil@in@\expandafter\pgfutil@firstoftwo
\else\expandafter\pgfutil@secondoftwo\fi
{\pgfkeysvalueof{/tikz/@shorten controls/.@cmd}#1..#2..#3\pgfeov}
{\pgfkeysvalueof{/tikz/@shorten controls/.@cmd}#1..#2and#2..#3\pgfeov}%
},
@shorten controls/.style args={#1..#2and#3..#4}{
to path={
\pgfextra
\pgfpathcurvebetweentime{#1}{1-(#4)}
{\tikz@scan@one@point\pgfutil@firstofone(\tikztostart)}
{\tikz@scan@one@point\pgfutil@firstofone#2}
{\tikz@scan@one@point\pgfutil@firstofone#3}
{\tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)}%
\endpgfextra
}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[dashed]
\draw[->, red, dash phase=3pt]
(3,1) .. controls (3.75,1.4) and (4.25,1.4) ..
(5,1) .. controls (5.75,0.6) and (6.25,0.6) ..
(7,1) to[shorten controls={0 .. (7.75,1.4) and (8.25,1.4) .. .5}]
(9,1);
\draw[->, blue]
(3,1) sin ++(1,.3) cos ++(1,-.3) sin ++(1,-.3) cos ++(1,.3) sin ++(1,.3);
\end{tikzpicture}

\tikz\draw[->]
(3,1) .. controls (3.75,1.4) and (4.25,1.4) ..
(5,1) .. controls (5.75,0.6) and (6.25,0.6) ..
(7,1) to[shorten controls={0 .. (7.75,1.4) and (8.25,1.4) .. .5}]
(9,1);
\tikz\draw[->]
(3,1) sin ++(1,.3) cos ++(1,-.3) sin ++(1,-.3) cos ++(1,.3) sin ++(1,.3);
\end{document}


## Output

• There's also \tikz\draw[->] plot[smooth, domain=0:10] (\x/2+3, 1+.3*sin(\x*45); but that's a bit too much. Sep 13, 2022 at 11:42
• @Qrrbrbirblbel thx. Really like your last solution. Small correction. Should be \draw[->] plot[smooth, domain=0:10] ({\x/2+3}, {1+0.4*sin(\x*45)}) Sep 13, 2022 at 18:33