5
$\begingroup$

A quadratic Bézier curve is a segment of a parabola. If the $3$ control points and the quadratic Bézier curve are known, how do you calculate the equation of the parabola (which is an $y=f(x)$ function) that this Bézier curve is a part of? (algebraically)

So in the image, the red curve is known, how do you find the equation $y=ax^{2}+bx+c$ for the black curve?

enter image description here

This is accidentally a special case because the control polygon is a horizontal & a vertical segment, but a general solution can be worked out I hope.

It's actually the opposite direction of this question.

$\endgroup$
  • 1
    $\begingroup$ It's not so easy to answer your question: First you say only $P_i$ are known, then in the following that a whole curve section (red) is known. This leads to the question, how is the red curve given for you? The next problem is that $y=f(x)$ is the equation of the parabola only in a certain coordinate system. In general you can only find a representation $f(x,y) = 0$, where $f$ is a quadratic polynomial in $x,y$. Perhaps you can detail these points a little by editing your post. $\endgroup$ – Jürgen Böhm Apr 29 '15 at 15:40
  • $\begingroup$ The control points are known, so logically the red Bézier curve is known also. The coordinate system is a Cartesian grid, with constant increments of 1 on both Y & X axes. The solution has to be related to the fact that the line through P0 & P1 is tangent to the Bézier curve in P0 and P1P2 tangent to the curve in P2. So the slope of the tangent to the parabola = the slope of these 2 lines. And the point where these 2 lines cross is P1. And to get c I think you need to plug in the x values of P0 and P1 into the ax^2+bx+c equation to get their y-value after you know a & b. I think.. $\endgroup$ – MisterH Apr 29 '15 at 18:54
  • $\begingroup$ @MisterH: then you will only be able to get an quadratic equation $f(x,y)=0$ to describe the parabola. A parabola is only given by $y=ax^2+bx+c$ when its axis is vertical. $\endgroup$ – robjohn Apr 30 '15 at 0:31
  • $\begingroup$ As others have said ... there is no hope of representing your curve in the form $y=ax^2 + bx + c$. The slope of such a curve is $2ax+b$, which is always finite, but your curve has an infinite slope at its right-hand end. You'll have to use a rotated cordinate system, or accept a curve equation of the form $f(x,y)=0$. $\endgroup$ – bubba May 3 '15 at 6:13
2
$\begingroup$

If your quadratic Bezier curve is indeed a segment between $[x_1, x_3]$ of function $f(x)=ax^2+bx+c$, then there must be a relationship between the three control points as

$P_1=(x_1,y_1)=(x_1,f(x_1))$
$P_2=(x_2, y_2)=(\frac{x_1+x_3}{2}, \frac{x_3-x_1}{2}(2ax_1+b)+y_1)$
$P_3=(x_3,y_3)=(x_3,f(x_3))$.

Although all quadric Bezier curve is part of a certain parabola, not all parabola can be represented as $f(x)=ax^2+bx+c$ (for example, the black curve shown in your picture). So, the first thing you need to do is check if $x_2 =\frac{x_1+x_3}{2}$. If this check fails, then your quadratic Bezier curve is not a segment of $f(x)=ax^2+bx+c$.

Now, we can try to find the values of $a$ and $b$ from the facts that

$\frac{y_2-y_1}{x_2-x_1}=f'(x_1)=2ax_1+b$,
$\frac{y_3-y_2}{x_3-x_2}=f'(x_3)=2ax_3+b$

After some algebra, we can find

$a=\frac{y_1-2y_2+y_3}{(x_3-x_1)^2}$
$b=\frac{2}{(x_3-x_1)^2}[x_3(y_2-y_1)+x_1(y_2-y_3)]$

and you can find $c$ easily with known $a$ and $b$.

$\endgroup$
  • $\begingroup$ I don't think this works uniformly. Maybe I made some arithmetic errors, but consider the case with the three control points: (0,0), (1/2, 0), (1,1) In your answer, a=1, b = 2/1*(0-1/2)=-1 which would result in an equation of y=x^2-x, which does go through (0,0), but doesn't go through (1,1) (it goes through (1,0)) Did I make a mistake somewhere? Misunderstanding bezier curves or your math? $\endgroup$ – McKay Jun 6 '19 at 23:28
  • 1
    $\begingroup$ @McKay, I think you made an arithmetic mistake. The calculation of b should be b=2/1*( 1*0 + 0*(0-1)) = 0. So, your quadratic equation would be y=x^2. $\endgroup$ – fang Jun 7 '19 at 17:40
  • $\begingroup$ Yup. I had an off by one error in control points. $\endgroup$ – McKay Jun 8 '19 at 21:29
4
$\begingroup$

In Theorem $3.4$ of this paper, a more general algorithm for finding the the conic associated with a rational quadatic spline is derived. Specialized for non-rational quadratic splines and parabolas, we get the equation for the parabola $$ \begin{bmatrix}x&y&1\end{bmatrix}Q\begin{bmatrix}x\\y\\1\end{bmatrix}=0 $$ where $$ Q=2\left(uw^T+wu^T\right)-vv^T $$ and, using $a=p_0$, $b=p_1$, and $c=p_2$, $$ u=\begin{bmatrix}b_y-c_y\\c_x-b_x\\b_xc_y-b_yc_x\end{bmatrix}\\ v=\begin{bmatrix}c_y-a_y\\a_x-c_x\\c_xa_y-c_ya_x\end{bmatrix}\\ w=\begin{bmatrix}a_y-b_y\\b_x-a_x\\a_xb_y-c_ya_x\end{bmatrix} $$

$\endgroup$
  • $\begingroup$ thank you so much for posting that. really amazing work. Using that paper and sympy (symbolic math python) a 7-line program can solve the OP's question. $\endgroup$ – don bright Sep 12 '15 at 5:27
  • $\begingroup$ @donbright: Thanks! Your comment caused me to revisit this question and look at the accepted answer. Although the accepted answer warns that not all parabolas have axes parallels to the $y$-axis, it only handles parabolas whose axes are parallel to the $y$-axis. $\endgroup$ – robjohn Sep 12 '15 at 8:11
  • $\begingroup$ I'm having trouble understanding the answer on it's own, although it looks like what I need. The link to the paper is broken. Do you have the name of the paper so one could google it? $\endgroup$ – Adrian Leonhard Apr 2 '17 at 18:14
  • $\begingroup$ @AdrianLeonhard: I am sorry that the link is broken. Dropbox has removed its support for public folders. I need to find a new place for my public files. $\endgroup$ – robjohn Apr 3 '17 at 8:10
1
$\begingroup$

An equation of the form y=f(x) in the form of ax^2+bx+c has to be found based on known coordinates of control points (P0, P1, P2) of a quadratic Bézier.

1) try to find "a" in the equation ax^2+bx+c based on the fact that the segments between the middle and the outer control points are tangent to the parabola in the outer control points:

Define:

   cpx<-c(30,60,90)
   cpy<-c(20,30,10)
   P0<-matrix(data=c(cpx[1],cpy[1]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
   P1<-matrix(data=c(cpx[2],cpy[2]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
   P2<-matrix(data=c(cpx[3],cpy[3]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
# 

x1<-P0[1];x2<-P1[1];x3<-P2[1];y1<-P0[2];y2<-P1[2];y3<-P2[2];m1<-(y2-y1)/(x2-x1);m2<-(y3-y2)/(x3-x2)

So the slope of the tangent line to the parabola in the first (left) control point = the slope of the line connecting the first and second control points. We know the slope of a line between 2 points (x1,y1) and (x2,y2): it is (y2-y1)/(x2-x1). We also know the slope of the tangent in a point on the parabola: it is the first derivative in that point: ax^2+bx+c derived is 2*a*x1+b in point x1.

So m1 (the slope of the line P0-P1) = 2*a*x1+b and m2=2*ax2*b; we solve for b and set these equal to each other:

m1=b+2*a*x1 m2=b+2*a*x3 so (for both) m1-2*a*x1=b=m2-2*a*x3=b so m1-m2=2*a*x1-2*a*x3=b and (m1-m2)=a*2*(x1-x3) so a=(m1-m2)/(2*(x1-x3))

2) Now we move on to "b": We use the same concept again: the slope of the tangent line in the outer control points are the first derivatives of the quadratic function in that point, but now we know "a". So the slope m1=2*ax1+b and m2=2*ax3+b. Substituting a into that equation we now know b: m1-(2*a*x1)=b=m2-(2*a*x3).

3) So now we know a & b, so c is easy: for every point on a curve if you fill in the x-coordinate in the equation, it should give you the y-coordinate. What we are missing is a constant: "c", and we know both x- and y-coordinates. So we can find "c" easily:

if ax^2+bx+c=y, then ax1^2+bx1+c=y1 and ax2^2+bx2+c=y2. So c = -a*(x1^2)-(bx1)+y1 = -a(x3^2)-(b*x3)+y3.

Now all that is left to do is substitute those x1's, x2,.. for the x & y coordinates of the control points and we have a nice y=f(x) function for the parametric quadratic Bézier curve.

Here's a short numerical example (in R code):

cpx<-c(30,60,90)
cpy<-c(20,30,10)
P0<-matrix(data=c(cpx[1],cpy[1]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
P1<-matrix(data=c(cpx[2],cpy[2]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
P2<-matrix(data=c(cpx[3],cpy[3]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
# so
x1<-P0[1]
x2<-P1[1]
x3<-P2[1]
y1<-P0[2]
y2<-P1[2]
y3<-P2[2]
m1<-(y2-y1)/(x2-x1)
m2<-(y3-y2)/(x3-x2)
t<-seq(0,1,len=101)
P0<-matrix(data=c(cpx[1],cpy[1]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
P1<-matrix(data=c(cpx[2],cpy[2]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
P2<-matrix(data=c(cpx[3],cpy[3]),nrow=1,ncol=2,byrow=FALSE,dimnames=NULL)
B2<-(1-t)^2%*%P0+2*t*(1-t)%*%P1+t^2%*%P2
a<-(m1-m2)/(-2*x3+2*x1)
b<-m1-(2*a*x1)
c<-y1-(a*x1^2+b*x1)
# a<--1/120
# b<-5/6
# c<-5/2
xx<--50:150
yy<-a*xx^2+b*xx+c
plot(xx,yy,type="l")
lines(B2,col='red',lwd=3)
# so you see that the Bézier curve lies exactly on the parabola:

enter image description here

If we now substitute everything:

a<-(((P1y-P0y)/(P1x-P0x))-((P2y-P1y)/(P2x-P1x)))/(-2*P2x+2*P0x)

b<-((P1y-P0y)/(P1x-P0x))-(2*a*P0x)

c<-P0y-(aP0x^2+bP0x)

or in the same code format:

a<-(((P1[2]-P0[2])/(P1[1]-P0[1]))-((P2[2]-P1[2])/(P2[1]-P1[1])))/(-2*P2[1]+2*P0[1])
b<-((P1[2]-P0[2])/(P1[1]-P0[1]))-(2*a*P0[1])
c<-P0[2]-(a*P0[1]^2+b*P0[1])

apologies for the formatting. I think the math is sound.

$\endgroup$
  • 1
    $\begingroup$ What happens if $x1=x2$ or $x2=x3$ (as in your original picture)??? $\endgroup$ – bubba May 9 '15 at 9:25

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.