0

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);
5
  • 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}.
    – dexteritas
    Sep 13, 2022 at 9:03
  • 1
    You'd probably need to clip it. Unlike metapost I don't think you can get sub paths out of a tikz path.
    – daleif
    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.
    – FiLou
    Sep 13, 2022 at 12:26

1 Answer 1

2

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.

Instead of

(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

enter image description here enter image description here enter image description here

2
  • 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)})
    – FiLou
    Sep 13, 2022 at 18:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .