This is about explicit/non-parametric quadratic Bézier curves. Normally you can't fit a quadratic Bézier curve to 3 points because the X-variable is also a function (Bézier = parametric function), but when the control points are equidistant, you can: it is called an explicit/non-parametric Bézier function. I want to fit a quadratic bernstein polynomial to 3 random points in a 2D plane, and the x-axis coordinates of the 3 control points have to be equidistant. Also, the (outer) control points don't have to coincide with the 2 outer data points like they normally do.
I guess this requires solving a set of equations, but which ones? And how do I do that in R given the limitations I set (curve through the 3 data points, control points same horizontal distance, and control points not necessarily on the data points?
The quadratic Bézier function is B(t)=(1-t)^2*P0+2*t*(1-t)*P1+t^2*P2,
if you run this in R, you will see what I meant:
# control points are equidistant: here the horizontal distance is 20
cpx<-c(-20,0,20)
# y-values can be random
cpy<-c(0,2,-4)
t<-seq(0,1,len=101)
# the 3 control points
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)
# the quadratic Bernstein polynomial:
B<-(1-t)^2%*%P0+2*t*(1-t)%*%P1+t^2%*%P2
par(mfrow=c(1,1))
plot(cpx,cpy,type="p",pch=20,xlab="",ylab="")
abline(v=c(min(cpx),max(cpx)),lty=3,col='red')
text(cpx[1],cpy[1],"P0",cex=.8,pos=4)
text(cpx[2],cpy[2],"P1",cex=.8,pos=1)
text(cpx[3],cpy[3],"P2",cex=.8,pos=2)
segments(cpx[1],cpy[1],cpx[2],cpy[2],lty=3);segments(cpx[2],cpy[2],cpx[3],cpy[3],lty=3)
lines(B,col="DeepSkyBlue")
# 3 random points on the curve:
pnts<-sort(sample(1:length(t),3,replace=F),decreasing=F)
point1<-pnts[1]
point2<-pnts[2]
point3<-pnts[3]
points(B[point1,1],B[point1,2],col='orange',pch=20)
points(B[point2,1],B[point2,2],col='orange',pch=20)
points(B[point3,1],B[point3,2],col='orange',pch=20)
segments(B[point1,1],B[point1,2],B[point2,1],B[point2,2],lwd=2,col='orange',lty=1)
segments(B[point2,1],B[point2,2],B[point3,1],B[point3,2],lwd=2,col='orange',lty=1)
Here's a similar but not equal topic. Here and here some nice Bézier animations.