13

I've managed to implement quadratic and cubic Bezier curves.They are pretty straightforward since we have a formula. Now I want to represent an n-th order Bezier curve using the generalization:

enter image description here

Where

enter image description here

and

enter image description here

I'm using a bitmap library to render the output, so here is my code:

// binomialCoef(n, k) = (factorial(n) / (factorial(k) * factorial(n- k)))
unsigned int binomialCoef(unsigned int n, const unsigned int k)
{
    unsigned int r = 1;

    if(k > n)
        return 0;

    for(unsigned int d = 1; d <= k; d++)
    {
        r *= n--;
        r /= d;
    }

    return r;
}

void nBezierCurve(Bitmap* obj, const Point* p, const unsigned int nbPoint, float steps, const unsigned char red, const unsigned char green, const unsigned char blue)
{
    int bx1 = p[0].x;
    int by1 = p[0].y;
    int bx2;
    int by2;

    steps = 1 / steps;

    for(float i = 0; i < 1; i += steps)
    {
        bx2 = by2 = 0;
        for(int j = 0; (unsigned int)j < nbPoint; j++)
        {
            bx2 += (int)(binomialCoef(nbPoint, j) * pow(1 - i, (float)nbPoint - j) * pow(i, j) * p[j].x);
            by2 += (int)(binomialCoef(nbPoint, j) * pow(1 - i, (float)nbPoint - j) * pow(i, j) * p[j].y);
        }

        bresenhamLine(obj, bx1, by1, bx2, by2, red, green, blue);

        bx1 = bx2;
        by1 = by2;
    }

    // curve must end on the last anchor point
    bresenhamLine(obj, bx1, by1, p[nbPoint - 1].x, p[nbPoint - 1].y, red, green, blue);
}

Here's the set of points to render:

Point ncurv[] = {
                    20, 200,
                    70, 300,
                    200, 400,
                    250, 200
                };

and here's the output:

enter image description here

The red curve is a cubic Bezier. The blue one is supposed to be the 4th order Bezier, which is the same as cubic Bezier, but in this case, they are not the same ?!

EDIT : I forgot to note that the bottom left point is (0, 0)

Community
  • 1
  • 1
Jonas
  • 1,019
  • 4
  • 20
  • 33

2 Answers2

5

The sum in your formula...

enter image description here

...runs from 0 to n, ie for an n-th order bezier you need n+1 points.

You have 4 points, so you're drawing a 3rd-order bezier.

The error in your code is here:

for(int j = 0; (unsigned int)j < nbPoint; j++)

it should be:

for(int j = 0; (unsigned int)j <= nbPoint; j++)

otherwise you're only iterating from 0 to n-1.

3rd-order bezier

EDIT:

Out of interest, the shape you were getting is the same as if the missing (5th) point was at (0,0), since that's the only point that would contribute nothing to your sum...

4th-order bezier with 5th point at origin

Richard Inglis
  • 5,888
  • 2
  • 33
  • 37
4

You are trying to construct a 4th-order Bezier curve on only four points. No wonder it's not working.

TonyK
  • 16,761
  • 4
  • 37
  • 72
  • 4
    How is this an answer? – Lo-Tan Mar 15 '15 at 19:16
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](https://stackoverflow.com/review/low-quality-posts/16357822) – Donald Duck Jun 08 '17 at 07:43
  • @DonaldDuck: This answers the question succinctly and correctly. Richard Inglis's answer is better, with all those nice pictures and everything, but if you read the first sentence of that answer you will see that it is essentially the same as mine. – TonyK Jun 08 '17 at 11:58
  • @TonyK This doesn't answer anything. You just rephrase the problem statement that the OP tries to construct a 4th order Bezier curve with four points and it doesn't work, while you introduce only two new words here: "no" and "wonder". There is no explanation why doesn't it work, or why four points are insufficient and how should it be done instead. – plasmacel Jun 08 '17 at 20:52