4

I'm trying to understand how exactly Bezier curves are drawn by TikZ. According to wikipedia, the parametrization of a quadratic Bezier curve is given by B(t) = (1 - t) ((1 - t) P0 + t P1) + t ((1 - t) P1 + t P2. Consider the example y = 2x^2, going through the points P0 = (0,0) and P2 = (1, 2) (blue line below) which can be parametrized as P(t) = (t, 2t^2)

It is easy to calculate

B''(t) = 2 (P2 - 2 P1 + P0) = (2, 4) - 2P1
P''(t) = (0, 4)

From this I can calculate the control point P1 = (1/2, 0) by making B''(t) = P''(t). The result is shown in red below

Clearly the curves are different, which means that the point P1 is not the control point I am supposed to use. Or that the parametrization B(t) that wikipedia uses is not the one used by TikZ. The question is then: what is the actual parametrization used by TikZ?

enter image description here

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

\usetikzlibrary{decorations.markings}

\begin{document}
\begin{tikzpicture}[%
  decoration = {markings,
    mark = at position 0.5 with {\fill[red, opacity = 0.5] circle (0.05);}
  },
  ]

  \draw [help lines] (-1, -1) grid (2, 3);

  % parabola
  \draw[blue, thick] (0, 0) parabola (1, 2) node[left]{$y=2x^2$};
  \fill[blue, opacity = 0.5] (0.5, 0.5) circle (0.05);

  % bezier
  \draw[red, thick, postaction={decorate}] (0, 0) .. controls (0.5, 0) .. (1, 2) node[midway, right]{bezier};
\end{tikzpicture}
\end{document}

I am aware of this, but I don't think it covers this question.

  • 3
    TikZ, as PDF and Postscript, uses cubic Bézier curves.... – Paul Gaborit May 18 '18 at 14:33
  • 1
    @PaulGaborit How is the statement \draw (A) .. controls (B) .. (C); interpreted by TikZ? – caverac May 18 '18 at 14:36
  • 4
    The complete syntax is .. controls (c) and (d) ... If the and (d) part is not given, d is assumed to be equal to c (cf. p.149 pfmanual, v3.0.1a). – Paul Gaborit May 18 '18 at 14:44
  • 1
    Quadratic curves are also replaced by cubic ones. The curve is not changing but the bounding box is tighter. – Kpym May 18 '18 at 15:07
  • 1
    By the way the parabola in tikz is not rally a parabola. If you want to draw x^2 over [0,1] you can use a quadratic curve with control points (0,0) (.5,0) (1,1) or a cubic curve with control points (0,0) (1/3,0) (2/3,1/3) (1,1). – Kpym May 18 '18 at 15:17
5

As Paul Gaborit said in his comments (a) .. controls (b) .. (c) is not a quadratic Bézier curve, but the cubic one (a) .. controls (b) and (b) .. (c).

If you want to draw a quadratic curve in TikZ you can define your own to path style. Here is an an example of how to do it using calc library.

\documentclass[tikz,border=7pt,convert={density=1400}]{standalone}
\usetikzlibrary{calc}
\tikzset{
  quadratic/.style={
    to path={
      (\tikztostart) .. controls
      ($#1!1/3!(\tikztostart)$) and ($#1!1/3!(\tikztotarget)$)
      .. (\tikztotarget)
    }
  }
}
\begin{document}
  \begin{tikzpicture}[nodes={scale=2,text opacity=1}]
    \draw[help lines] (0,0) grid (2,4);
    \filldraw[fill opacity=.07]
        (0,0) coordinate[label=center:.](A)
      --(1,0) coordinate[label=center:.](B)
      --(2,4) coordinate[label=center:.](C);
    \draw[blue] (A)..controls (B)..(C);
    \draw[red,very thick] (A) to[quadratic={(B)}] (C);  % <- The quadratic curve
    \draw[white,domain=0:2] plot (\x,\x^2);
  \end{tikzpicture}
\end{document}

enter image description here

And if you prefer a code that do not use calc and use the PGF command \pgfpathquadraticcurveto you can replace the style definition with :

\makeatletter
\def\pt@get#1{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax%
  \pgfpoint{\the\pgf@x}{\the\pgf@y}%
}
\tikzset{
  quadratic/.code={
    \def\tikz@to@path{}% <- TikZ do nothing
    \pgfpathquadraticcurveto{\pt@get{#1}}{\pt@get{(\tikztotarget)}}% <- PGF insert the quadratic curve
  }
}
\makeatother

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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