Search code examples
c#wpfbezierpathgeometry

Find Control Point for QuadraticBezierSegment when given Start, End, and 1 Point lying along the bezier in C# - QuadraticBezier 3-point Interpolation


This is Similar to a previous question I asked about the Cubic Bezier. I've got a start point, an endpoint, and a point that is meant to lie along a Quadratic Bezier. Given these three points I want to be able to draw a QuadraticBezierSegment in WPF, but I need the single ControlPoint value (in the QuadraticBezierSegment it's Point1) in order to draw it.

Is there a calculation or means whereby I can determine that value and thus draw my QuadraticBezier?

Thanks!


Solution

  • The best quadratic fit is simpler than the best cubic fit. Here's some code:

    static class DrawingUtility
    {
        static void bez3pts1(double x0, double y0, double x3, double y3, double x2, double y2, out double x1, out double y1)
        {
            // find chord lengths
            double c1 = Math.Sqrt((x3 - x0) * (x3 - x0) + (y3 - y0) * (y3 - y0));
            double c2 = Math.Sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2));
            // guess "best" t
            double t = c1 / (c1 + c2);
            // quadratic Bezier is B(t) = (1-t)^2*P0 + 2*t*(1-t)*P1 + t^2*P2
            // solving gives P1 = [B(t) - (1-t)^2*P0 - t^2*P2] / [2*t*(1-t)] where P3 is B(t)
            x1 = (x3 - (1 - t) * (1 - t) * x0 - t * t * x2) / (2 * t * (1 - t));
            y1 = (y3 - (1 - t) * (1 - t) * y0 - t * t * y2) / (2 * t * (1 - t));
        }
    
        // pass in a PathFigure and it will append a QuadraticBezierSegment connecting the previous point to int1 and endPt
        static public void QuadraticBezierFromIntersection(PathFigure path, Point startPt, Point int1, Point endPt)
        {
            double x1, y1;
            bez3pts1(startPt.X, startPt.Y, int1.X, int1.Y, endPt.X, endPt.Y, out x1, out y1);
            path.Segments.Add(new QuadraticBezierSegment { Point1 = new Point(x1, y1), Point2 = endPt } );
        }
    }