Why is my version of the bezier curve biased?

I want to display Bezier curves in C ++, so I started implementing it myself. This shouldn't be very effective at this point. My code somehow gives a close result, but these curves are imprecise. ( dvec2

is a vector of two double values.)

list<dvec2> bezier(list<dvec2> const &points, int resolution)
{
    list<dvec2> samples;
    double step = 1.0 / resolution;
    for (double time = 0.0; time <= 1.0; time += step) {
        list<dvec2> sliders = points;
        while (sliders.size() > 1)
            sliders = slide(sliders, time);
        samples.push_back(sliders.front());
    }
    return samples;
}

list<dvec2> slide(list<dvec2> const &points, double time)
{
    list<dvec2> result;
    auto current = points.begin();
    dvec2 last = *current;
    for (++current; current != points.end(); ++current)
        result.push_back(last * time + *current * (1.0 - time));
    return result;
}

      

I am currently creating n-1 points from a curve by interpolating the first with the second, the second with the third, etc. depending on the time t. Then I shrink this new set of points again using the same algorithm until I am left with one point that I can draw. I think this approach should work.

In the rendered image, you can see the result of the algorithm on several rendered curves.

rendering looks similar to bezier curves

For example, in the lower left corner of the image, the two opposite curves should be symmetrical, I think. Mines are displaced in direction. Moreover, those completely closed curves should at least draw a point in the center at t = 0.5. What caused this?

+3


source to share


1 answer


Your approach should work. You did a little bit of work: internally slide()

you are not updating last

in your loop.

Try:

for (++current; current != points.end(); ++current) {
    result.push_back(last * time + *current * (1.0 - time));
    last = *current; // <--
}

      




Note that another interpretation of Bezier curves can be specified by taking the sum of these products:

(Source: wikipedia )

Some terminology is associated with these parametric curves. We have

\ mathbf {B} (t) = \ sum_ {i = 0} ^ n b_ {i, n} (t) \ mathbf {P} _i, \ quad t \ in [0, 1]

where are the polynomials

b_ {i, n} (t) = {n \ choose i} t ^ i (1 - t) ^ {n - i}, \ quad i = 0, \ ldots, n

are known as Bernstein base polynomials of degree n.

Here you need the (pre-computed) binomial coefficients, and with the function std::pow

you get one loop instead of two nested ones (given that n is limited to a constant in practice to make pre-compilation possible).

+4


source







All Articles