13

In TikZ, it is possible to draw a Bézier curve of degree 3 with 2 control points p0, p1, p2, and p3 as follows:

\draw(p0)..controls (p1) and (p2)..(p3);

I am wondering whether there is a way to draw a Bézier curve with 5 points where 3 of them work as control points. That would then look like:

\draw(p0)..controls (p1) and (p2) and (p3)..(p4);

It looks like it is not available.

pluton
  • 16,421

2 Answers2

11

The fact that TikZ/PGF only has capabilities for cubic beziers is a facet of the output formats that it produces: those only support cubic beziers.

So to produce anything of higher degree, you would have to produce an approximation (indeed, TikZ/PGF approximates arcs by cubic beziers since PDF does not have a native arc command (Postscript does)). There are methods that could be used for implementing one, for example using a plot command, but as it would be an approximation and not a common feature, there is not - to my knowledge - an already inbuilt implementation. If you found an algorithm for approximating higher degree curves by cubic beziers, I can think of no reason why it would not be straightforward to implement one via some sort of to path magic.

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
5

Here is some code to create a Bezier's curve with three control points. If you require more or less points to draw the curve, just modify the argument {0.05,0.1,...,1} on the "foreach" line. With the provided values the curve is drawn with 20 points. P0 and P4 are the end points, while p1, p2, and p3 are the control points.

\newcommand {\bezierq}[5]{
%\bezierq{p0}{p1}{p2}{p3}{p4};
\newdimen\pxa
\newdimen\pya
\newdimen\pxb
\newdimen\pyb
\newdimen\pxc
\newdimen\pyc
\newdimen\pxd
\newdimen\pyd
\newdimen\pxe
\newdimen\pye
\pgfextractx{\pxa}{\pgfpointanchor{#1}{center}}
\pgfextracty{\pya}{\pgfpointanchor{#1}{center}}
\pgfextractx{\pxb}{\pgfpointanchor{#2}{center}}
\pgfextracty{\pyb}{\pgfpointanchor{#2}{center}}
\pgfextractx{\pxc}{\pgfpointanchor{#3}{center}}
\pgfextracty{\pyc}{\pgfpointanchor{#3}{center}}
\pgfextractx{\pxd}{\pgfpointanchor{#4}{center}}
\pgfextracty{\pyd}{\pgfpointanchor{#4}{center}}
\pgfextractx{\pxe}{\pgfpointanchor{#5}{center}}
\pgfextracty{\pye}{\pgfpointanchor{#5}{center}}
%\def\pxi{4}
%\def\pyi{4}
\foreach \t in {0.05,0.1,...,1}{
  \pgfmathsetmacro{\pxf}{\pxa*(1-\t)^4 + \pxb*4*\t*(1-\t)^3 + \pxc*6*\t^2*(1-\t)^2 + \pxd*4*(1-\t)*\t^3 + \pxe*\t^4}
  \pgfmathsetmacro{\pyf}{\pya*(1-\t)^4 + \pyb*4*\t*(1-\t)^3 + \pyc*6*\t^2*(1-\t)^2 + \pyd*4*(1-\t)*\t^3 + \pye*\t^4}
  \pgfmathsetmacro{\q}{\t-0.05}
  \pgfmathsetmacro{\pxi}{\pxa*(1-\q)^4 + \pxb*4*\q*(1-\q)^3 + \pxc*6*\q^2*(1-\q)^2 + \pxd*4*(1-\q)*\q^3 + \pxe*\q^4}
  \pgfmathsetmacro{\pyi}{\pya*(1-\q)^4 + \pyb*4*\q*(1-\q)^3 + \pyc*6*\q^2*(1-\q)^2 + \pyd*4*(1-\q)*\q^3 + \pye*\q^4}
  \draw (\pxi pt,\pyi pt)--(\pxf pt,\pyf pt);
}
lockstep
  • 250,273
Juan
  • 51