Реализация Bspline не работает должным образом

Я сделал эту реализацию кривой BSPLINE. Я следовал обычному определению, представленному в http://en.wikipedia.org/wiki/B-spline

t - вектор узла.

#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;
}

Проблема в том, что когда я рисую вычисленные точки, я вижу неожиданное поведение в начале и конце кривой. Например: введите здесь описание изображения

Не могу понять почему так происходит, попробуй изменить значения t, но похоже что то не то.


person Rafael Castro    schedule 17.05.2015    source источник


Ответы (2)


Существует две реализации bspline: универсальная и стандартная. В униформе первая и последняя контрольные точки не интерполируются, а в стандартной последовательности узлов интерполируются обе. В униформе вы можете иметь однородные узлы, обычно 1,2,3,... Для стандартной последовательности узлов, если у вас порядок k (степень k-1), вы должны иметь k нулей, k единиц и заполнить середину 1/( m-k+2), где m — количество контрольных точек. Например, имея 5 контрольных точек и порядок 3, последовательности узлов будут 0, 0, 0, 0,25, 0,5, 0,75, 1, 1, 1.

Кроме того, используя дельта-функции, вы можете получить гораздо лучшую реализацию, чем вычисление N-функции. Дельта-функция выигрывает от локальной поддержки bspline. Я предлагаю вам ознакомиться с конспектами курсов, которые я преподаю в Университете Калгари: http://pages.cpsc.ucalgary.ca/~amahdavi/pmwiki-2.2.8/uploads/Site/notes1..pdf

См. стр. 40 алгоритм 3.3.

Надеюсь, это полезно.

person Good Luck    schedule 18.05.2015

В общем случае: если у вас есть n контрольных точек и вы строите кривую b-сплайна степени k, ваш вектор узлов имеет n+k+1 узлов. Область кривой (т.е. где сумма базисных функций равна 1) задается в интервале [t_k, ... t_n] (насколько мои данные верны).

В цикле ваши значения параметров находятся в диапазоне от 0,0 до 5,0. Это должно быть от t[k] = t[2] = 1,0 до t[n] = t[6] = 4,0.

Вики-примеры делают это по-другому, поскольку приведенные там векторы узлов имеют несколько значений (т. е. k-раз) в начале и в конце. Таким образом, показанная кривая сплайна начинается/заканчивается в первой/последней контрольной точке. Ваша конструкция не дает этого свойства.

person Christian    schedule 18.05.2015