Search code examples
cmathsplinebspline

Bspline implementation not working as expected


I made this implementation of the BSPLINE curve. I Followed the usual definition presented in http://en.wikipedia.org/wiki/B-spline

t is the knot vector.

#include <stdio.h>

double N(int i, int k, double u, double t[])
{
    if(k == 1)
    {
        if(u >= t[i] && u < t[i+1])
            return 1.0e0;
        else {
            return 0.0e0;
        }
    }
    return ((u - t[i])*N(i, k -1, u, t))/(t[i+k-1] - t[i]) + ((t[i+k] - u)*N(i+1, k-1, u, t))/(t[i+k] - t[i+1]);
}

double pu(double u, double x[], int n, int k, double t[])
{
    int i;

    double r = 0.0e0;
    for(i = 0; i < n; i++)
    {
        r += x[i]*N(i, k, u, t);
    }
    return r;
}


int main()
{
    double t[] = {0.0, 0.5, 1, 2, 3, 4, 4.5, 5}; //knot vector
    double x[] = {-30.0, 25.0, 9.0, 20.0, 25.0, 31.0}, y[] = {-5.0, -10.0, 3.0, -10.0, -5.0, 25.0}; //the points
    double u;

    for(u = 0.0e0; u < 5.0; u+=0.01e0)
    {
        printf("%lf %lf\n", pu(u, x, 6, 2, t), pu(u, y, 6, 2, t));
    }
    return 0;
}

The problem is that when I plot the computed points I see that there is an unexpected behavior at the beginning and end of the curve. For instance: enter image description here

I can not understand why this happens, try changing the values of t, but it seems that is not it.


Solution

  • There are two implementations of bspline: uniform and standard. In uniform the first and the last control points are not interpolated and in the standard knot sequence both are interpolated. In uniform, you can have uniform knots usually 1,2,3,... For standard knot sequence if you have order k (degree k-1) you should have k zeros, k ones and fill in the middle with 1/(m-k+2) where m is the number of control points. For example, having 5 control points and order 3, knot sequences are 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1.

    In addition, using delta functions you can have a much better implementation rather than computing N function. Delta function benefits from the local support of bspline. I suggest you take a look at the course notes that I teach at the University of Calgary: http://pages.cpsc.ucalgary.ca/~amahdavi/pmwiki-2.2.8/uploads/Site/notes1.pdf

    Check page 40 algorithm 3.3.

    Hopefully it's helpful.