How do I implement a Bézier curve in C++?

前端 未结 5 1310
有刺的猬
有刺的猬 2020-11-30 18:53

I\'d like to implement a Bézier curve. I\'ve done this in C# before, but I\'m totally unfamiliar with the C++ libraries. How should I go about creating a quadratic curve?

相关标签:
5条回答
  • 2020-11-30 19:08

    Here is a general implementation for a curve with any number of points.

    vec2 getBezierPoint( vec2* points, int numPoints, float t ) {
        vec2* tmp = new vec2[numPoints];
        memcpy(tmp, points, numPoints * sizeof(vec2));
        int i = numPoints - 1;
        while (i > 0) {
            for (int k = 0; k < i; k++)
                tmp[k] = tmp[k] + t * ( tmp[k+1] - tmp[k] );
            i--;
        }
        vec2 answer = tmp[0];
        delete[] tmp;
        return answer;
    }
    

    Note that it uses heap memory for a temporary array which is not all that efficient. If you only need to deal with a fixed number of points you could hard-code the numPoints value and use stack memory instead.

    Of course, the above assumes you have a vec2 structure and operators for it like this:

    struct vec2 {
        float x, y;
        vec2(float x, float y) : x(x), y(y) {}
    };
    
    vec2 operator + (vec2 a, vec2 b) {
        return vec2(a.x + b.x, a.y + b.y);
    }
    
    vec2 operator - (vec2 a, vec2 b) {
        return vec2(a.x - b.x, a.y - b.y);
    }
    
    vec2 operator * (float s, vec2 a) {
        return vec2(s * a.x, s * a.y);
    }
    
    0 讨论(0)
  • 2020-11-30 19:15

    You have a choice between de Casteljau's method, which is to recursively split the control path until you arrive at the point using a linear interpolation, as explained above, or Bezier's method which is to blend the control points.

    Bezier's method is

     p = (1-t)^3 *P0 + 3*t*(1-t)^2*P1 + 3*t^2*(1-t)*P2 + t^3*P3 
    

    for cubics and

     p = (1-t)^2 *P0 + 2*(1-t)*t*P1 + t*t*P2
    

    for quadratics.

    t is usually on 0-1 but that's not an essential - in fact the curves extend to infinity. P0, P1, etc are the control points. The curve goes through the two end points but not usually through the other points.

    0 讨论(0)
  • 2020-11-30 19:20

    Recently I ran across the same question and wanted to implemented it on my own. This image from Wikipedia helped me:

    http://upload.wikimedia.org/wikipedia/commons/3/35/Bezier_quadratic_anim.gif

    The following code is written in C++ and shows how to compute a quadratic bezier.

    int getPt( int n1 , int n2 , float perc )
    {
        int diff = n2 - n1;
    
        return n1 + ( diff * perc );
    }    
    
    for( float i = 0 ; i < 1 ; i += 0.01 )
    {
        // The Green Line
        xa = getPt( x1 , x2 , i );
        ya = getPt( y1 , y2 , i );
        xb = getPt( x2 , x3 , i );
        yb = getPt( y2 , y3 , i );
    
        // The Black Dot
        x = getPt( xa , xb , i );
        y = getPt( ya , yb , i );
    
        drawPixel( x , y , COLOR_RED );
    }
    

    With (x1|y1), (x2|y2) and (x3|y3) being P0, P1 and P2 in the image. Just for showing the basic idea...

    For the ones who ask for the cubic bezier, it just works analogue (also from Wikipedia):

    http://upload.wikimedia.org/wikipedia/commons/a/a3/Bezier_cubic_anim.gif

    This answer provides Code for it.

    0 讨论(0)
  • 2020-11-30 19:25

    Did you use a C# library earlier?

    In C++, no standard library function for Bezier curves is available (yet). You can of course roll your own (CodeProject sample) or look for a math library.

    This blogpost explains the idea nicely but in Actionscript. Translation should not be much of a problem.

    0 讨论(0)
  • 2020-11-30 19:30
    • If you just want to display a Bezier curve, you can use something like PolyBezier for Windows.

    • If you want to implement the routine yourself, you can find linear interpolation code all over the Intarnetz.

    • I believe the Boost libraries have support for this. Linear interpolation, not Beziers specifically. Don't quote me on this, however.

    0 讨论(0)
提交回复
热议问题