6

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.

7
  • 3
    TikZ, as PDF and Postscript, uses cubic Bézier curves.... May 18, 2018 at 14:33
  • 1
    @PaulGaborit How is the statement \draw (A) .. controls (B) .. (C); interpreted by TikZ?
    – caverac
    May 18, 2018 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). May 18, 2018 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, 2018 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, 2018 at 15:17

2 Answers 2

8

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
2

The QUADRATIC Bezier curve with 3 control points P0, P1, P2 is a special case of the CUBIC Bezier curve with 4 control points P0, (1/3 P0+2/3 P1), (2/3 P1+1/3 P2), P2. For example, if you want to draw the downwards arc of a parabola (quadratic Bezier) with control points (0,6), (3,6), (6,0), use the cubic control points (0,6), (2,6), (4,4), (6,0), as in \draw (0,6) .. controls (2,6) and (4,4) .. (6,0); The formula is obtained by comparing the coefficients for the two Bezier curves as in https://en.wikipedia.org/wiki/B%C3%A9zier_curve

You must log in to answer this question.

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