0

I have a problem of writing the beizer function. I have written a simple code in c# :

public static PointF[] BeizerFunction (int interval, PointF point0, PointF point1, PointF point2) {
        //x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x;
        //y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y;
        var Points = new PointF[interval];
        var time = 1.0f / (float) interval;

        for (var i=0; i<Points.Length; i++) {
            var point = Points [i];

            point = new PointF ();
            point.X = (1 - time) * (1 - time) * point0.X
                + 2 * (1 - time) * time * point1.X
                + time * time * point2.X;
            point.Y = (1 - time) * (1 - time) * point0.Y
                + 2 * (1 - time) * time * point1.Y
                + time * time * point2.Y;

            Points [i] = point;
            time ++;
        }

        return Points;
    }

By application is listen to mouse move so I would guess the mouse pointer would be the control points for this function. The above code if correct should give me a beizer curve from three points.

In reality, there multiple curves so there would be more than 3 points. To join the beize curve together I do something like this.

Bezier(p0.5, p1, p1.5);
Bezier(p1.5, p2, p2.5);
Bezier(p2.5, p3, p3.5); 

The c# code to draw just a 3 points is this

var p0 = new PointF (50, 50);
        var p1 = new PointF (100, 100);
        var p2 = new PointF (150, 50);

        var points = QuadraticBezierFunction.BeizerFunction (100, p0, p1, p2);

        for (var i=0; points != null && i<points.Length-1; i=i+1)
            canvas.DrawLine (points[i].X, points[i].Y, points[i+1].X, points[i+1].Y, new Android.Graphics.Paint ());

When I try to draw the curve it doesn't look a curve.

LittleFunny
  • 8,155
  • 15
  • 87
  • 198
  • What are you targetting: Winforms, WPF, ASP..? __Always__ tag your question correctly! - Also: I hope you are not using __all__ those many many points you get from mousemove to build a bezier curve, as the whole point (or one main one) is that you need only __very few__ to create nice curves. – TaW May 21 '16 at 06:55
  • do not use quadratic BEZIER but cubic instead (4 control points). The quadratic BEZIER (3 control points) is really hard to join with pleasant results (you will need fitting). With cubics you do not need any of it just use the points in correct order. See http://stackoverflow.com/a/30438865/2521214 also I think this is your goal http://stackoverflow.com/a/30750626/2521214 – Spektre May 21 '16 at 07:37
  • Thanks Spektre. Do you mean with Cubics I only need to apply something like this: Cubic( p0,p1,p2,p3) then Cubic (p3, p4, p5, p6). Sorry my understanding of math is quite limited. – LittleFunny May 21 '16 at 08:32
  • TaW - I am not target to any particular platform... Before I was use java quadTo to do the job but I need to applied it on one of the library but they don't have the same function so I have to create my own bezier algorithm. Thanks for the advice. I will try the many points version first and sample the point in later version. – LittleFunny May 21 '16 at 08:40
  • 2
    The "time++;" statement in your codes does not seem to be right. – fang May 22 '16 at 01:02
  • @Simon yes almost the calling sequence is `(p0,p0,p0,p1),(p0,p0,p1,p2),(p0,p1,p2,p3),(p1,p2,p3,p4),(p2,p3,p4,p5)...` for more info see the linked **QA** ... You can also use any kind of cubic for this (my favorite for this is interpolation cubic also in that linked content). PS to acknowledge user by comment you need to add `@` before `nick` and the site will do that for you. (for example `@Spektre`) – Spektre May 22 '16 at 06:39

1 Answers1

1

As per @fang's observation, don't use time ++; because you don't want to go from 0.xyz to 1.xyz, you want to increment by small fractions. The Bezier functions only "work" (that is, as intended for the usual graphics purposes) for a time parameter between 0 and 1 (inclusive), so you want to start at time=0;, iterate a number of times with some small time += step;, and stop once time>=1+step.

(and then unless you are extraordinarily lucky you probably need to manually add a final point for time=1 so you are guaranteed the correct endpoint)

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153