I have three points in 2D and I want to draw a quadratic Bézier curve passing through them. How do I calculate the middle control point (x1
and y1
I have used Nemos answer in my JavaFX apllication, but my goal was to draw the curve, so that the visual turning point of the curve always fits with the choosen fixed one (CP).
CP = ControlPoint
SP = StartPoint
EP = EndPoint
BP(t) = variable Point on BeziérCurve where t is between 0 and 1
To achieve this i made a variable t (not fix 0.5). If the choosen Point CP is no longer in the middle between SP and EP, you have to vary t up or down a little bit. As a first step you need to know if CP is closer to SP or EP: Let distanceSP be the distance between CP and SP and distanceEP the distance between CP and EP then i define ratio as:
ratio = (distanceSP - distanceEP) / (distanceSP + distanceEP);
Now we are going to use this to vary t up and down:
ratio = 0.5 - (1/3) * ratio;
note: This is still an approximation and 1/3 is choosen by try and error.
Here is my Java-Function: (Point2D is a class of JavaFX)
private Point2D adjustControlPoint(Point2D start, Point2D end, Point2D visualControlPoint) {
// CP = ControlPoint, SP = StartPoint, EP = EndPoint, BP(t) = variable Point on BeziérCurve where t is between 0 and 1
// BP(t) = SP*t^2 + CP*2*t*(1-t) + EP*(1-t)^2
// CP = (BP(t) - SP*t^2 - EP*(1-t)^2) / ( 2*t*(1-t) )
// but we are missing t the goal is to approximate t
double distanceStart = visualControlPoint.distance(start);
double distanceEnd = visualControlPoint.distance(end);
double ratio = (distanceStart - distanceEnd) / (distanceStart + distanceEnd);
// now approximate ratio to be t
ratio = 0.5 - (1.0 / 3) * ratio;
double ratioInv = 1 - ratio;
Point2D term2 = start.multiply( ratio * ratio );
Point2D term3 = end.multiply( ratioInv * ratioInv );
double term4 = 2 * ratio * ratioInv;
return visualControlPoint.subtract(term2).subtract(term3).multiply( 1 / term4);
}
I hope this helps.