• The 4 species of bezier curves

    From luser droog@21:1/5 to All on Sat May 16 22:41:50 2020
    According to this paper,

    https://www.cad-journal.net/files/vol_11/CAD_11(5)_2014_568-578.pdf

    there are only 4 kinds of bezier curve. All bezier curves
    can be decomposed into affine combinations of the 4 primitive
    curves.

    The math is pretty heavy tho

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Forkosh@21:1/5 to luser droog on Sun May 17 07:44:57 2020
    luser droog <luser.droog@gmail.com> wrote:
    According to this paper,
    https://www.cad-journal.net/files/vol_11/CAD_11(5)_2014_568-578.pdf
    there are only 4 kinds of bezier curve. All bezier curves
    can be decomposed into affine combinations of the 4 primitive
    curves. The math is pretty heavy tho

    Interesting. I'd thought there was only one kind, as described at, e.g.,
    https://en.wikipedia.org/wiki/Bezier_curve
    And I've just now been using all that as discussed in my question
    https://math.stackexchange.com/questions/3676231/
    (see the second paragraph where I mention that the purpose of the
    question is for a bezier curve application)

    And the application of the end result of that question is illustrated
    by the upper-right-corner animated gif on the banner of my homepage
    http://www.forkosh.com/
    where you can see the image morphing between my name and logo.
    Each pixel morphs along a random bezier curve from the initial
    to final image, but it happens too quickly (i.e., you barely see
    the initial and final images at all) if the t-parameter just
    goes linearly from 0 to 1 (and back).

    And here's the little bit of C code, based on that wikipedia
    discussion, added to my gifscroll program to facilitate its
    new morphing feature...

    /* ---
    * bezier datatypes
    * ------------------- */
    #define POINT struct point_struct
    POINT { double x, y; } ;

    /*===========================================================================
    * Function: bezier ( n, cp, t )
    * Purpose: returns x,y-coords of bezier curve
    * with n control points cp, at 0.<=t<=1.
    * --------------------------------------------------------------------------
    * Arguments: n (I) int n>=2, number of control points
    * cp (I) POINT* vector of control points, with
    * cp[0] the initial, and cp[n-1] the final
    * points of the curve, as usual.
    * t (I) double 0.<=t<=1.
    * Returns: (POINT) x,y-coords of bezier curve at t,
    * or -1.,-1. for argument error, or any error.
    * --------------------------------------------------------------------------
    * Notes: o See https://en.wikipedia.org/wiki/Bezier_curve
    * for algorithms.
    *======================================================================== */ /* --- entry point --- */
    POINT bezier ( int n, POINT *cp, double t ) {
    /* --- allocations and declarations --- */
    POINT bezt = { -1., -1. }; /* returned point, init for error */
    int k=0,binky(); /* binomial coefficient */
    /* --- check args --- */
    if ( n<2 || cp==NULL /* invalid control points */
    || t<0. || t>1. ) goto end_of_job; /* invalid parameter */
    /* --- explicit sum over control points --- */
    n--; /* sum from 0...n rather than 0...n-1 */
    bezt.x = bezt.y = 0.0; /* init sum */
    for ( k=0; k<=n; k++ ) {
    double coef=((double)binky(n,k))*pow(1.-t,(double)(n-k))*pow(t,(double)k);
    bezt.x += coef*cp[k].x;
    bezt.y += coef*cp[k].y;
    } /* --- end-of-for(k) --- */
    end_of_job:
    return ( bezt ); /* back to caller */
    } /* --- end-of-function bezier() --- */

    /*===========================================================================
    * Function: binky ( n, k )
    * Purpose: Binomial coefficient n!/k!(n-k)!
    * --------------------------------------------------------------------------
    * Arguments: n (I) int n >= 0
    * k (I) int k = 0,...,n
    * Returns: (int) Binomial coefficient n!/k!(n-k)!,
    * or -1 if the result would likely overflow,
    * or -1 if argument error.
    * --------------------------------------------------------------------------
    * Notes: o uses the recursive relation (n k) = (n-1 k-1) + (n-1 k)
    *======================================================================== */ /* --- entry point --- */
    int binky ( int n, int k ) {
    /* --- allocations and declarations --- */
    int this_binky= (-1), /* init for error */
    binky_max = INT_MAX/2; /* assert binky <= binky_max */
    /* --- check args for "convergence" --- */
    if ( n<k || k<0 ) return ( -1 ); /* argument error */
    if ( n==k /* default=1 if n == k */
    || n<1 || k<1 ) return ( 1 ); /* default=1 if n or k == 0 */
    this_binky = binky(n-1,k-1) + binky(n-1,k);
    if ( this_binky > binky_max ) this_binky = (-1);
    return ( this_binky );
    } /* --- end-of-function binky() --- */
    --
    John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)