5

I want to achieve the following (this is a mockup drawing in Inkscape): Curve in Inkscape

I want to draw a smooth curve through three coordinates and I want the control points of the second coordinate (labeled "P" in the image above) to lie on the tangent of Point P, so that I can stretch them out to either side to control the smoothness of the curve at that point. Further, the curve should leave the first point (which is the one on the bottom left) at 5 degrees and enter the last point (upper right) at -90 degress. This is not depicted in the image above.

Unfortunately, I do not know how to achieve this. I tried the following:

\documentclass[border=5pt,tikz]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc,intersections,through}
\tikzset{point/.style={circle,inner sep=0pt,minimum size=3pt,fill=red}}

\begin{document}
\begin{tikzpicture}

\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=above:$B$] (B) at (11,6);
\coordinate [label=right:$C$] (C) at (16,14);
\coordinate [label=above:$D$] (D) at (16,28);

\draw[thick] (A) .. controls +(5:3)  and ([turn]1:1) .. (B) .. controls ([turn]1:1) and +(-90:3) .. (C);
\draw[thick] (C) -- (D);

\node[point] at (A) {};
\node[point] at (B) {};
\node[point] at (C) {};
\node[point] at (D) {};

\end{tikzpicture}
\end{document}

But that does not give the desired result, as you can see here: Curve in Tikz

Can anybody please give me a hint how to align control points to the tangent of a curve point? Any help is greatly appreciated.

4 Answers 4

3

Your approach is quit good, unfortunately it is not consistent used. First, your curve is larger that A4 paper , so you need to reduce it. For example as I do in the code below:

    \documentclass[border=5pt,tikz]{standalone}  
    \usetikzlibrary{arrows}
    \tikzset{point/.style={circle,inner sep=0pt,minimum size=3pt,fill=red}}

         \begin{document}
    \begin{tikzpicture}
    \coordinate [label=left: $A$] (A) at (0,0);
    \coordinate [label=above:$B$] (B) at (5,2.5);
    \coordinate [label=above:$C$] (C) at (8,10);

    \draw[thick] (A) .. controls +(05:2) and +(225:1) .. (B) 
                     .. controls +(45:1) and +(-90:5) .. (C);
    % only for show of tangents
    \draw[red,dashed,-*] (A) -- + (  5:2);
    \draw[red,dashed,-*] (B) -- + (225:2);
    \draw[red,dashed,-*] (B) -- + ( 45:2);
    \draw[red,dashed,-*] (C) -- + (270:2);
    %
    \node[point] at (A) {};
    \node[point] at (B) {};
    \node[point] at (C) {};
    \end{tikzpicture}
        \end{document}

It gives:

enter image description here

In it the tangent of start point and end point determined +(05:2) and +(225:1), where +(05:2) determine "departure" angle at start of curve and +(225:2) departure angle at end of curve. With + is indicated, that this ponts are relative to start and end of curve.

2
  • How do you determine what lengths to use for the controls (I see 1, 2 and 5.) May 14, 2016 at 13:25
  • You catch me :-). So far I follow to my experiences/fillings ... which I correct in trial/error process.
    – Zarko
    May 14, 2016 at 13:43
3

If you use the hobby library to draw the curve, then the curve is smooth and you can adapt its use of TikZ code to show the path's construction, which appears as show curve controls in the manual.

For example:

\documentclass[tikz, border=5pt, multi]{standalone}
\usetikzlibrary{hobby,decorations.pathreplacing,arrows.meta}
\tikzset{% adapted from hobby_doc.tex
  show curve controls/.style={
    decoration={
      show path construction,
      curveto code={
        \draw [blue, -{Circle[black,open]}] (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) ;
        \draw [blue, {Circle[black,open]}-] (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast) ;
      }
    },decorate
  },
}
\begin{document}
\begin{tikzpicture}
  \coordinate [label=left:$A$] (A) at (0,0);
  \coordinate [label=above:$B$] (B) at (5.5,3);
  \coordinate [label=right:$C$] (C) at (8,7);
  \draw [thick, use Hobby shortcut, postaction=show curve controls] ([out angle=5, in angle=-90]A)  .. (B) .. (C);
  \foreach \i in {A,B,C}
  {
    \draw [fill, red] (\i) circle (2.5pt);
    \draw [fill, green] ([xshift=-1pt,yshift=-1pt]\i) rectangle ([xshift=1pt,yshift=1pt]\i);
  }
\end{tikzpicture}
\end{document}

show curve controls, adapted

Obviously, you could use the TikZ code for showing path construction without using the hobby library. You'd just draw the curve in your preferred way and use the postaction on the path, modifying as desired.

1

I was wondering if there was a more rigorous solution. First I tried using single controls at the intersections of the tangents (too ugly). Then I tried using two controls a fixed ratio of the distance to the intersection (0.5, .67, .75). Just for fun I settled for the (inverse) golden ratio.

\documentclass[border=5pt,tikz]{standalone}  
    \usetikzlibrary{calc,intersections}
    \tikzset{point/.style={circle,inner sep=0pt,minimum size=3pt,fill=red}}

         \begin{document}
    \begin{tikzpicture}[scale=0.5]
    \coordinate [label=left: $A$] (A) at (0,0);
    \coordinate [label=above:$B$] (B) at (5,2.5);
    \coordinate [label=above:$C$] (C) at (8,10);

    \path[name path=Atan] (A) -- +(5:5);
    \path[name path=Btan] ($(B) + (225:5)$) -- ($(B) + (45:5)$);
    \path[name path=Ctan] (C) -- +(-90:5);
    \path[name intersections={of=Atan and Btan, by={AB}}] node[point] at (AB) {};
    \path[name intersections={of=Btan and Ctan, by={BC}}] node[point] at (BC) {};
    \def\factor{0.61803399}
    \draw[thick] (A) .. controls ($(A)!\factor!(AB)$) and ($(B)!\factor!(AB)$) .. (B) 
                     .. controls ($(B)!\factor!(BC)$) and ($(C)!\factor!(BC)$) .. (C);
    %
    \node[point] at (A) {};
    \node[point] at (B) {};
    \node[point] at (C) {};
    \end{tikzpicture}
        \end{document}

demo

0

if the connecting curve has no clear function, I like to use to[out = angle, angle=in] which specifies the angle of entry and exit point

\documentclass[border=5pt,tikz]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc,intersections,through}
\tikzset{point/.style={circle,inner sep=0pt,minimum size=3pt,fill=red}}

\begin{document}
\begin{tikzpicture}

\coordinate [label=left:$A$] (A) at (0,0);
\coordinate [label=above:$B$] (B) at (11,6);
\coordinate [label=right:$C$] (C) at (16,14);
\coordinate [label=above:$D$] (D) at (16,28);

\draw[thick,smooth] (A) to[out =0, in=-135] (B) to[out =45, in=-90](C);
\draw[thick] (C) -- (D);

\node[point] at (A) {};
\node[point] at (B) {};
\node[point] at (C) {};
\node[point] at (D) {};

\end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

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