2017-02-21 35 views
0

Я пытаюсь нарисовать B-Spline с учетом 11 контрольных точек. Я использую freeglut и C++. Я смог легко отобразить контрольные точки. Затем я написал базисные функции следующим образом:Присоединение сегментов B-Spline в OpenGL/C++

float B0(float u){ 
    return float(pow(u - 1, 3)/6.0); 
} 

float B1(float u){ 
    return float((3 * pow(u, 3) - 6 * pow(u, 2) + 4)/6.0); 
} 

float B2(float u){ 
    return float((-3 * pow(u, 3) + 3 * pow(u, 2) + 3 * u + 1)/6.0); 
} 

float B3(float u){ 
    return float(pow(u, 3)/6.0); 
} 

Вот мой алгоритм, который вычисляет 100 точек для каждого сегмента и сохраняет вычисленные точки в массиве, который будет отображаться, обратите внимание, что MAX_POINTS является глобальным и точками является массивом из структур с поплавками х, у, и для каждого г:

void computeBSpline(){ 
int MAX_STEPS = 100; 
int count = 0; 
for (int i = 0; i < NUM_OF_POINTS - 3; i++) 
{ 
    cout << "Computing for P" << i << " P " << i + 1 << " P " << i + 2 << " P " << i + 3 << endl; 
    for (int j = 0; j <= MAX_STEPS; j++) 
    { 

     float u = float(j)/float(MAX_STEPS); 

     float Qx = B0(u) * points[i].x + B1(u) * points[i + 1].x + B2(u) * points[i + 2].x + B3(u) * points[i + 3].x; 
     float Qy = B0(u) * points[i].y + B1(u) * points[i + 1].y + B2(u) * points[i + 2].y + B3(u) * points[i + 3].y; 

     pointsBSpline[count].x = Qx; 
     pointsBSpline[count].y = Qy; 

     //cout << count << '(' << Qx << ", " << Qy << ")\n"; 
     count++; 
    } 
} 
cout << "Computed " << count << " points!\n"; 
} 

позже я называю это DrawBSpline(), который будет цикл через массив и отображение всех точек:

void DrawBSpline(){ 
glPointSize(1.5); 
glColor3d(0.0, 0.0, 0.0); 
int i = 0; 
glBegin(GL_POINTS); 
for (; i < NUM_OF_BSPLINE_POINTS; i++){ 
    glVertex2d(pointsBSpline[i].x, pointsBSpline[i].y); 
} 
glEnd(); 
} 

Это выход моей программы: B-Spline output

Я просто не уверен, как присоединиться к сегментам и произвести одну плавную кривую. Любая помощь будет оценена по достоинству.

+0

Ну, один из способов присоединиться к сегментам - использовать средневзвешенное значение слева и справа. (Я предполагаю, что вы не просто ищете 'GL_LINE_STRIP' вместо' GL_POINTS') –

+0

Да, я ищу способ сделать его гладкой кривой, некоторые из вычисленных точек не должны отображаться, поскольку они не будут падать Кривая. Я знаю об использовании «GL_LINE_STRIP», но это просто соединить их, однако я не уверен, как делать то, что вы описали. – user3502486

+0

Подумайте о (так называемой линейной, но фактически ** аффинной **) интерполяции из таблицы, где ближайшими точками являются (x1, y1) и (x2, y2): 'yi (x) = (y1 * (x2 - x) + y2 * (x - x1))/(x2 - x1) '. Теперь используйте его для плавной интерполяции между двумя кривыми вместо двух констант: h (x) = (f (x) * (x2 - x) + g (x) * (x - x1))/(x2 - x1) ' Поскольку ваши кривые параметризованы, вы можете использовать 'u' для управления смесью. –

ответ

0

Оказывается, я написал float(pow(u-1, 3)/6.0); вместо float(pow(1-u, 3)/6.0);

Стыдно, проблема исправлена.

+0

Такая вещь определенно сделает это - у вас будет одна базовая функция, триангуляция до -1/6, а ее соседка достигнет +1/6 –