Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
De Casteljau's algorithm
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Method to evaluate polynomials in Bernstein form}} In the [[mathematics|mathematical]] field of [[numerical analysis]], '''De Casteljau's algorithm''' is a [[Recursion|recursive]] method to evaluate polynomials in [[Bernstein form]] or [[Bézier curve]]s, named after its inventor [[Paul de Casteljau]]. De Casteljau's algorithm can also be used to split a single Bézier curve into two Bézier curves at an arbitrary parameter value. The algorithm is [[numerically stable]]<ref>{{Cite journal |last1=Delgado |first1=J. |last2=Mainar |first2=E. |last3=Peña |first3=J. M. |date=2023-10-01 |title=On the accuracy of de Casteljau-type algorithms and Bernstein representations |url=https://www.sciencedirect.com/science/article/pii/S0167839623000754 |journal=Computer Aided Geometric Design |volume=106 |pages=102243 |doi=10.1016/j.cagd.2023.102243 |issn=0167-8396|doi-access=free }}</ref> when compared to direct evaluation of polynomials. The computational complexity of this algorithm is <math>O(d n^2)</math>, where d is the number of dimensions, and n is the number of control points. There exist faster alternatives.<ref>{{Cite journal |last1=Woźny |first1=Paweł |last2=Chudy |first2=Filip |date=2020-01-01 |title=Linear-time geometric algorithm for evaluating Bézier curves |url=https://www.sciencedirect.com/science/article/abs/pii/S0010448518301234 |journal=Computer-Aided Design |volume=118 |pages=102760 |doi=10.1016/j.cad.2019.102760 |issn=0010-4485|arxiv=1803.06843 }}</ref><ref>{{Cite journal |last1=Fuda |first1=Chiara |last2=Ramanantoanina |first2=Andriamahenina |last3=Hormann |first3=Kai |date=2024 |title=A comprehensive comparison of algorithms for evaluating rational Bézier curves |url=https://drna.padovauniversitypress.it/2024/3/9 |journal=Dolomites Research Notes on Approximation |volume=17 |issue=9/2024 |pages=56–78 |doi=10.14658/PUPJ-DRNA-2024-3-9 |issn=2035-6803}}</ref> == Definition == A Bézier curve <math>B</math> (of degree <math>n</math>, with control points <math>\beta_0, \ldots, \beta_n</math>) can be written in Bernstein form as follows <math display="block">B(t) = \sum_{i=0}^{n}\beta_{i}b_{i,n}(t),</math> where <math>b</math> is a [[Bernstein polynomial|Bernstein basis polynomial]] <math display="block">b_{i,n}(t) = {n \choose i}(1-t)^{n-i}t^i.</math> The curve at point <math>t_0</math> can be evaluated with the [[recurrence relation]] <math display="block">\begin{align} \beta_i^{(0)} &:= \beta_i, && i=0,\ldots,n \\ \beta_i^{(j)} &:= \beta_i^{(j-1)} (1-t_0) + \beta_{i+1}^{(j-1)} t_0, && i = 0,\ldots,n-j,\ \ j= 1,\ldots,n \end{align}</math> Then, the evaluation of <math>B</math> at point <math>t_0</math> can be evaluated in <math display="inline">\binom{n}{2}</math> operations. The result <math>B(t_0)</math> is given by <math display="block">B(t_0) = \beta_0^{(n)}.</math> Moreover, the Bézier curve <math>B</math> can be split at point <math>t_0</math> into two curves with respective control points: <math display="block">\begin{align} &\beta_0^{(0)},\beta_0^{(1)},\ldots,\beta_0^{(n)} \\[1ex] &\beta_0^{(n)},\beta_1^{(n-1)},\ldots,\beta_n^{(0)} \end{align}</math> === Geometric interpretation === The geometric interpretation of De Casteljau's algorithm is straightforward. *Consider a Bézier curve with control points <math>P_0, \dots, P_n</math>. Connecting the consecutive points we create the control polygon of the curve. *Subdivide now each line segment of this polygon with the ratio <math>t : (1-t)</math> and connect the points you get. This way you arrive at the new polygon having one fewer segment. *Repeat the process until you arrive at the single point – this is the point of the curve corresponding to the parameter <math>t</math>. The following picture shows this process for a cubic Bézier curve: [[Image:DeCasteljau1.svg]] Note that the intermediate points that were constructed are in fact the control points for two new Bézier curves, both exactly coincident with the old one. This algorithm not only evaluates the curve at <math>t</math>, but splits the curve into two pieces at <math>t</math>, and provides the equations of the two sub-curves in Bézier form. The interpretation given above is valid for a nonrational Bézier curve. To evaluate a rational Bézier curve in <math>\mathbf{R}^n</math>, we may project the point into <math>\mathbf{R}^{n+1}</math>; for example, a curve in three dimensions may have its control points <math>\{(x_i, y_i, z_i)\}</math> and weights <math>\{w_i\}</math> projected to the weighted control points <math>\{(w_ix_i, w_iy_i, w_iz_i, w_i)\}</math>. The algorithm then proceeds as usual, interpolating in <math>\mathbf{R}^4</math>. The resulting four-dimensional points may be projected back into three-space with a [[perspective divide]]. In general, operations on a rational curve (or surface) are equivalent to operations on a nonrational curve in a [[projective space]]. This representation as the "weighted control points" and weights is often convenient when evaluating rational curves. === Notation === When doing the calculation by hand it is useful to write down the coefficients in a triangle scheme as <math display="block"> \begin{matrix} \beta_0 & = \beta_0^{(0)} & & & \\ & & \beta_0^{(1)} & & \\ \beta_1 & = \beta_1^{(0)} & & & \\ & & & \ddots & \\ \vdots & & \vdots & & \beta_0^{(n)} \\ & & & & \\ \beta_{n-1} & = \beta_{n-1}^{(0)} & & & \\ & & \beta_{n-1}^{(1)} & & \\ \beta_n & = \beta_n^{(0)} & & & \\ \end{matrix} </math> When choosing a point ''t''<sub>0</sub> to evaluate a Bernstein polynomial we can use the two diagonals of the triangle scheme to construct a division of the polynomial <math display="block">B(t) = \sum_{i=0}^n \beta_i^{(0)} b_{i,n}(t), \quad t \in [0,1]</math> into <math display="block">B_1(t) = \sum_{i=0}^n \beta_0^{(i)} b_{i,n}\left(\frac{t}{t_0}\right)\!, \quad t \in [0,t_0]</math> and <math display="block">B_2(t) = \sum_{i=0}^n \beta_i^{(n-i)} b_{i,n}\left(\frac{t-t_0}{1-t_0}\right)\!, \quad t \in [t_0,1].</math> == Bézier curve == [[File:Bézier 2 big.gif|thumb|right|A second order Bézier curve.]] [[File:Bezier cubic anim.gif|thumb|right|A third order Bézier curve.]] [[File:Bezier forth anim.gif|thumb|right|A fourth order Bézier curve.]] When evaluating a Bézier curve of degree ''n'' in 3-dimensional space with ''n'' + 1 control points '''P'''<sub>''i''</sub> <math display="block">\mathbf{B}(t) = \sum_{i=0}^{n} \mathbf{P}_i b_{i,n}(t),\ t \in [0,1]</math> with <math display="block">\mathbf{P}_i := \begin{pmatrix} x_i \\ y_i \\ z_i \end{pmatrix},</math> we split the Bézier curve into three separate equations <math display="block">\begin{align} B_1(t) &= \sum_{i=0}^{n} x_i b_{i,n}(t), & t \in [0,1] \\[1ex] B_2(t) &= \sum_{i=0}^{n} y_i b_{i,n}(t), & t \in [0,1] \\[1ex] B_3(t) &= \sum_{i=0}^{n} z_i b_{i,n}(t), & t \in [0,1] \end{align}</math> which we evaluate individually using De Casteljau's algorithm. == Example == We want to evaluate the Bernstein polynomial of degree 2 with the Bernstein coefficients <math display="block">\begin{align} \beta_0^{(0)} &= \beta_0 \\[1ex] \beta_1^{(0)} &= \beta_1 \\[1ex] \beta_2^{(0)} &= \beta_2 \end{align}</math> at the point ''t''<sub>0</sub>. We start the recursion with <math display="block">\begin{align} \beta_0^{(1)} &&=&& \beta_0^{(0)} (1-t_0) + \beta_1^{(0)}t_0 &&=&& \beta_0(1-t_0) + \beta_1 t_0 \\[1ex] \beta_1^{(1)} &&=&& \beta_1^{(0)} (1-t_0) + \beta_2^{(0)}t_0 &&=&& \beta_1(1-t_0) + \beta_2 t_0 \end{align}</math> and with the second iteration the recursion stops with <math display="block"> \begin{align} \beta_0^{(2)} & = \beta_0^{(1)} (1-t_0) + \beta_1^{(1)} t_0 \\ \ & = \beta_0(1-t_0) (1-t_0) + \beta_1 t_0 (1-t_0) + \beta_1(1-t_0)t_0 + \beta_2 t_0 t_0 \\ \ & = \beta_0 (1-t_0)^2 + \beta_1 2t_0(1-t_0) + \beta_2 t_0^2 \end{align}</math> which is the expected Bernstein polynomial of degree ''2''. == Implementations{{anchor|Example implementation}} == Here are example implementations of De Casteljau's algorithm in various programming languages. === [[Haskell (programming language)|Haskell]] === <syntaxhighlight lang="haskell" line> deCasteljau :: Double -> [(Double, Double)] -> (Double, Double) deCasteljau t [b] = b deCasteljau t coefs = deCasteljau t reduced where reduced = zipWith (lerpP t) coefs (tail coefs) lerpP t (x0, y0) (x1, y1) = (lerp t x0 x1, lerp t y0 y1) lerp t a b = t * b + (1 - t) * a </syntaxhighlight> === [[Python (programming language)|Python]] === <syntaxhighlight lang="python" line> def de_casteljau(t: float, coefs: list[float]) -> float: """De Casteljau's algorithm.""" beta = coefs.copy() # values in this list are overridden n = len(beta) for j in range(1, n): for k in range(n - j): beta[k] = beta[k] * (1 - t) + beta[k + 1] * t return beta[0] </syntaxhighlight> === [[Java (programming language)|Java]] === <syntaxhighlight lang="java" line=""> public double deCasteljau(double t, double[] coefficients) { double[] beta = coefficients; int n = beta.length; for (int i = 1; i < n; i++) { for (int j = 0; j < (n - i); j++) { beta[j] = beta[j] * (1 - t) + beta[j + 1] * t; } } return beta[0]; } </syntaxhighlight> === Code Example in JavaScript === The following JavaScript function applies De Casteljau's algorithm to an array of control points or [https://www.sciencedirect.com/science/article/pii/S0167839624000128 poles] as originally named by De Casteljau to reduce them one by one until reaching a point in the curve for a given t between 0 for the first point of the curve and 1 for the last one <syntaxhighlight lang="javascript" line> function crlPtReduceDeCasteljau(points, t) { let retArr = [ points.slice () ]; while (points.length > 1) { let midpoints = []; for (let i = 0; i+1 < points.length; ++i) { let ax = points[i][0]; let ay = points[i][1]; let bx = points[i+1][0]; let by = points[i+1][1]; // a * (1-t) + b * t = a + (b - a) * t midpoints.push([ ax + (bx - ax) * t, ay + (by - ay) * t, ]); } retArr.push (midpoints) points = midpoints; } return retArr; } </syntaxhighlight> For example, var poles = [ [0, 128], [128, 0], [256, 0], [384, 128] ] crlPtReduceDeCasteljau (poles, .5) returns the array [ [ [0, 128], [128, 0], [256, 0], [384, 128 ] ], [ [64, 64], [192, 0], [320, 64] ], [ [128, 32], [256, 32]], [ [192, 32]], ] which yields the points and segments plotted below: [[File:Recursive Linear Interpolation.svg|center|Intermediate line segments obtained by recursively applying linear interpolation to adjacent points.]] == See also == *[[Bézier curves]] *[[De Boor's algorithm]] *[[Horner scheme]] to evaluate polynomials in [[monomial form]] *[[Clenshaw algorithm]] to evaluate polynomials in [[Chebyshev form]] ==References== {{Reflist}} *{{ cite book | last1 = Farin | first1 = Gerald E. | last2 = Hansford | first2 = Dianne | author2-link = Dianne Hansford | title = The Essentials of CAGD |date = 2000 | publisher = A.K. Peters | isbn = 978-1-56881-123-9 | location = Natick, MA }} ==External links== * [http://hcklbrrfnn.wordpress.com/2012/08/20/piecewise-linear-approximation-of-bezier-curves/ Piecewise linear approximation of Bézier curves] – description of De Casteljau's algorithm, including a criterion to determine when to stop the recursion * [http://jeremykun.com/2013/05/11/bezier-curves-and-picasso/ Bézier Curves and Picasso ] — Description and illustration of De Casteljau's algorithm applied to cubic Bézier curves. * [https://pomax.github.io/bezierinfo/#decasteljau de Casteljau's algorithm] - Implementation help and interactive demonstration of the algorithm. [[Category:Splines (mathematics)]] [[Category:Numerical analysis]] [[Category:Articles with example Haskell code]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Anchor
(
edit
)
Template:Cite book
(
edit
)
Template:Cite journal
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)