[Tex/LaTex] How are quadratic Bezier curves drawn by TikZ

beziertikz-pgf

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.

Best Answer

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