ПРИМЕР ПРОГРАММЫ ГЕНЕРАЦИИ КРИВЫХ БЕЗЬЕ

В приведенной ниже программе реализован расчет стыковочных функций Безье и генерация двухмерного кубического сплайна Безье. На плоскости ху определены четыре контрольные точки, и на кривой отмечено 1000 положений пикселей, причем ширина пикселя равна 4. Значения биномиальных коэффициентов вычисляются в процедуре binoraialCoef f s, а положения точек на кривой вычисляются в процедуре computeBezPt. Данные значения передаются процедуре bezier, и пиксели отмечаются на кривой с использованием процедур OpenGL вывода точек на экран. Кроме того, траекторию кривой можно аппроксимировать прямыми отрезками, используя при этом меньшее число точек. Более эффективные методы генерации точек вдоль сплайновой кривой рассматриваются в разделе 8.17. В приведенном примере наложены условия внешней системы координат, поэтому отображаются только точки кривой, находящиеся в окне просмотра (рис. 8.34). Если дополнительно требуется изобразить положения контрольных точек, контрольный граф или выпуклую оболочку, отсекающее окно нужно расширить во внешней системе координат.

Кривая Безье, изображенная программой-примером

Рис. 8.34. Кривая Безье, изображенная программой-примером

♦include <GL/glut.h>

♦include <stdlib.h>

♦include <math.h>

/* Задается исходный размер окна на экране дисплея. */ GLsizei winWidth = 600, winHeight * 600;

/* Задается размер отсекающего окна во внешних

* координатах.

*/

GLfloat xwcMin = -50.0, xwcMax = 50.0;

GLfloat ywcMin = -50.0, ywcMax = 50.0;

class wcPt3D { public:

GLfloat x, y, z;

};

void init (void)

{

/* Цвет окна выбирается белым. */ glClearColor (1.0, 1.0, 1.0, 0.0);

}

void plotPoint (wcPt3D bezCurvePt)

{

glBegin (GL_POINTS);

glVertex2f (bezCurvePt.x, bezCurvePt.y); glEnd ( );

}

/* Вычисляются биномиальные коэффициенты С для данного

* значения п.

*/

void binomialCoeffs (GLint п, GLint * С) {

GLint k, j;

for (k = 0; k <= n; k++) {

/* Вычисляется n!/(k!(n - k)!). */

С [k] = 1;

for (j = n; j >= k + 1; j-)

С [k] *= j; for (j = n - k; j >= 2; j -)

С [k] /= j;

}

}

void computeBezPt (GLfloat u, wcPt3D * bezPt, GLint nCtrlPts,

wcPt3D * ctrlPts, GLint * C)

{

GLint k, n = nCtrlPts - 1;

GLfloat bezBlendFcn;

bezPt->x = bezPt->y = bezPt->z = 0.0;

/* Вычисляются стыковочные функции и контрольные

* точки соединений.

*/

for (к = 0; к < nCtrlPts; к++) {

bezBlendFcn = С [к] * pow (и, к) * pow (1 - и, п - к);

bezPt->x += ctrlPts [к].х * bezBlendFcn;

bezPt->y += ctrlPts [к].у * bezBlendFcn;

bezPt->z += ctrlPts [k].z * bezBlendFcn;

}

}

void bezier (wcPt3D * ctrlPts, GLint nCtrlPts,

GLint nBezCurvePts)

{

wcPt3D bezCurvePt;

GLfloat u;

GLint *C, k;

/* Распределяется память для биномиальных коэффициентов.*/ С = new GLint [nCtrlPts];


⇐ вернуться назад | | далее ⇒