14576

Кривые и поверхности в OpenGL

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторная работа № 7 Кривые и поверхности в OpenGL Кривые Безье Кривая Безье задается векторной функцией одной переменной Cu = [ Xu Yu Zu] Где u изменяется в некоторой области например [0.0 1.0]. Фрагмент поверхности Безье задается векторной фу

Русский

2013-06-08

75 KB

55 чел.

Лабораторная работа № 7

Кривые и поверхности в OpenGL

Кривые Безье

Кривая Безье задается векторной функцией одной переменной

   C(u) = [ X(u), Y(u), Z(u)],

     

Где  u изменяется в некоторой области, например, [0.0, 1.0].

Фрагмент поверхности Безье задается векторной функцией двух переменных

   S(u, v) = [ X(u, v), Y(u, v), Z(u, v) ].

Для каждого значения u и v формула C( ) или S( ) вычисляет точку на кривой ( поверхности ). При использовании Безье-вычисления сначала выбирают функцию C( ) или S( ), включают ее (Безье-вычислитель), а затем используют команду glEvalCoord1( ) или glEvalCoord2( ) вместо команды glVertex*( ). В этом случае вершина кривой или поверхности может использоваться точно также, как и любая другая вершина, например, для формирования точки или линии. Кроме того, другие команды автоматически генерируют серии вершин, образующих пространство регулярной однородной сетки по оси u (или по осям u и v ).  

Если  представляет набор контрольных точек, то уравнение

   C(u) =   - представляет собой кривую Безье при изменении u от 0.0 до 1.0, где

 

- многочлен Бернштейна степени n, который задается следующим уравнением

    

В составе OpenGL имеются средства поддержки работы с кривыми и поверхностями Безье - Безье-вычислитель, которые позволяют вычислять значения полиномов Безье любого порядка. Безье вычислитель можно использовать для работы с полиномами от одной, двух, трех и четырех переменных.

Функция обработки полинома одной переменной настраивается в процессе инициализации OpenGL- программы посредством вызова функции

 glMap1f(type, u_min, u_max, stride, order, point array)

 Аргумент  type задает тип объекта, который будет представлен полиномом Безье. Можно назначить в качестве значения этого аргумента константы, задающие трех- и четырехмерные геометрические точки, цвет в формате RGBA, нормали, индексированные цвета и координаты текстур ( от одно- до четырехмерных).

Table 12-1 : Types of Control Points for glMap1*()

Parameter

Meaning

GL_MAP1_VERTEX_3

x, y, z vertex coordinates

GL_MAP1_VERTEX_4

x, y, z, w vertex coordinates

GL_MAP1_INDEX

color index

GL_MAP1_COLOR_4

R, G, B, A

GL_MAP1_NORMAL

normal coordinates

GL_MAP1_TEXTURE_COORD_1

s texture coordinates

GL_MAP1_TEXTURE_COORD_2

s, t texture coordinates

GL_MAP1_TEXTURE_COORD_3

s, t, r texture coordinates

GL_MAP1_TEXTURE_COORD_4

s, t, r, q texture coordinates

 Указатель на массив опорных точек полинома передается функции через аргумент point_array. Аргументы u_min, u_max определяют область существования параметра полинома. Аргумент stride представляет собой количество значений параметра между сегментами кривой. Значение аргумента order должно быть равно количеству опорных точек. Для формирования кубической трехмерной кривой в форме В-сплайна, определенной на интервале (0,1), функции glMap1f() следует передать такой набор аргументов:

point data[]= {…};

glMap1f(GL_MAP_VERTEX_3, 0.0, 1.0, 3, 4, data);

 После настройки функция активизируется посредством вызова:

 glEnable(type);

 Если функция расчета активизирована, то можно получить от нее значения полинома, вызвав функцию:

 glEvalCoord1f(u);

 Таким образом, обращение к glEvalCoord1f() может заменить обращение к функциям glVertex(), glColor(), glNormal(). Пусть, например, функция расчета настроена на формирование кривой Безье на интервале (0,10) по некоторому массиву опорных точек. Набор из 100 точек кривой, равноотстоящих на этом интервале можно получить с помощью такого фрагмента программы:

 glBegin(GL_LINE_STRIP)

 for(i=0; i<100; i++) glEvalCoord1f( (float)i/100.);

glEnd();  

 Если значения параметра u распределены равномерно, то для вычисления точек на кривой следует использовать функции glMapGrid1f() и glEvalMesh1(), например:

 glMapGrid1f(100, 0.0, 10.0);

glEvalMesh1(GL_LINE, 0, 100);

 После вызова glMapGrid1f() устанавливается равномерная сетка в 100 отсчетов, а после вызова функции glEvalMesh1() будет сформирована кривая.

Пример программы вычисления и рисования полинома Безье.

#include <GL/glut.h>

#include <stdlib.h>

GLfloat ctrlpoints[4][3] = {

{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},

{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};

void init(void)

{

  glClearColor(0.0, 0.0, 0.0, 0.0);

  glShadeModel(GL_FLAT);

  glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);

  glEnable(GL_MAP1_VERTEX_3);

}

void display(void)

{

  int i;

  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(1.0, 1.0, 1.0);

  glBegin(GL_LINE_STRIP);

     for (i = 0; i <= 30; i++)

        glEvalCoord1f((GLfloat) i/30.0);

  glEnd();

  /* The following code displays the control points as dots. */

  glPointSize(5.0);

  glColor3f(1.0, 1.0, 0.0);

  glBegin(GL_POINTS);

     for (i = 0; i < 4; i++)

        glVertex3fv(&ctrlpoints[i][0]);

  glEnd();

  glFlush();

}

void reshape(int w, int h)

{

  glViewport(0, 0, (GLsizei) w, (GLsizei) h);

  glMatrixMode(GL_PROJECTION);

  glLoadIdentity();

  if (w <= h)

     glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,

              5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);

  else

     glOrtho(-5.0*(GLfloat)w/(GLfloat)h,

              5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);

  glMatrixMode(GL_MODELVIEW);

  glLoadIdentity();

}

void keyboard(unsigned char key, int x, int y)

{

  switch (key) {

     case 27:

        exit(0);

        break;

  }

}

int main(int argc, char** argv)

{

  glutInit(&argc, argv);

  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

  glutInitWindowSize (500, 500);

  glutInitWindowPosition (100, 100);

  glutCreateWindow (argv[0]);

  init ();

  glutDisplayFunc(display);

  glutReshapeFunc(reshape);

  glutKeyboardFunc (keyboard);

  glutMainLoop();

  return 0;

}

Поверхности Безье

Математически  фрагмент  поверхности  Безье  задается  уравнением                                                                                                   S(u,v)=

где - представляет собой множество  контрольных точек, а функции - те же самые многочлены Бернштейна, что и для одного измерения. Значения  могут представлять вершины, нормали, цвета или текстурные координаты.

Поверхности Безье формируются в OpenGL примерно по той же методике, что и кривые, только роль функции инициализации играет не glMap1*(), а glMap2*(), а для считывания результатов следует обращаться к функции glEvalCoord2*() вместо glEvalCoord1*(). В обеих функциях нужно специфицировать данные, относящиеся к двум независимым параметрам u и v. Например, функция glMap2f() имеет такой формат вызова:

glMap2f(type, u_min, u_max, u_stride, u_order, v_min, v_max, v_stride, v_order, point_array);

 Настройка функции вычисления на работу с бикубической поверхностью Безье, определенной на области (0,1)х(0,1), выполняется таким вызовом glMap2f():

glMap2f(GL_MAP_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, data);

 Для обоих независимых переменных нужно задать порядок полинома (аргументы u_order и v_order) и количество значений параметра между сегментами (аргументы u_stride и v_stride), что обеспечивает дополнительную гибкость при формировании поверхности. Обратите внимание на то, что значение v_stride для второго параметра равно 12, поскольку в массиве опорных точек  data данные хранятся по строкам. Поэтому для перехода к следующему элементу этой же строки нужно «перешагнуть» три числа в формате float, а для перехода к следующему элементу в этом же столбце нужно «перешагнуть» через 3*4=12 чисел в формате float. Способ вызова программы расчета зависит от того, какой результат мы хотим получить,- вывести на экран сеть или сформировать многоугольники для последующего раскрашивания. Если ставится задача сформировать на экране сеть, то соответствующий фрагмент программы должен выглядеть примерно так:

 for(j=0; j<100; j++)

{

glBegin(GL_LINE_STRIP);

 for(i=0; i<100; i++)

 glEvalCoord2f((float)i/100.0, (float)j/100.0);

glEnd();

  glBegin(GL_LINE_STRIP);

 for(i=0; i<100; i++)

 glEvalCoord2f((float)j/100.0, (float)i/100.0);

glEnd();

}

 Если же желательно сформировать множество многоугольников, то фрагмент должен выглядеть так:

 for(j=0; j<99; j++)

{

 glBegin(GL_QUAD_STRIP)

 for(i=0; i<=100; i++)

 {

 glEvalCoord2f( (float)i/100.0, (float)j/100.0);

 glEvalCoord2f( (float)(i+1)/100.0, (float)j/100.0);

 }

 glEnd();

}

Для работы на равномерной сетке следует использовать функции glMapGrid2*() и glEvalMesh2(). Тогда в самое начало программы, в ту часть, которая отвечает за инициализацию, нужно включить такой фрагмент:

 glMapGrid2f(100, 0.0, 1.0, 100, 0.0, 1.0);

 В функции отображения display() нужно вызвать glEvalMesh2():

glEvalMesh2(GL_FILL, 0, 100, 0, 100);

 Для работы алгоритмов тонирования (закрашивания) сформированной поверхности при настройке режима учета освещения нужно дополнительно вызвать функцию glEnable(), передав ей в качестве аргумента константу GL_AUTO_NORMAL:

glEnable(GL_AUTO_NORMAL);

 Это позволит OpenGL автоматически вычислять вектор нормали к каждому участку формируемой поверхности и использовать этот вектор при закрашивании участков этой поверхности.

Пример программы аппроксимации с помощью поверхности Безье функции z=sin(x+y):

#include <stdlib.h>

#include <GL/glut.h>

#include <math.h>

#include <stdio.h>

GLfloat ctrlpoints[6][6][3];

void initlights(void)

{

  GLfloat ambient[] = {1.0, 1.0, 1.0, 1.0};

  GLfloat position[] = {0.0, 0.0, 2.0, 1.0};

  GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};

  GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};

  GLfloat mat_shininess[] = {50.0};

  glEnable(GL_LIGHTING);

  glEnable(GL_LIGHT0);

  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);

  glLightfv(GL_LIGHT0, GL_POSITION, position);

  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();

  glRotatef(85.0, 1.0, 0.0, 0.0);

glEvalMesh2(GL_FILL, 0, 10, 0, 10);

  glPopMatrix();

  glFlush();

}

void init(void)

{

float x,y;

int i,j;

for (i=0; i<6;i++)

{

x=3.1415/5.0*(float)i;

for(j=0; j<6; j++)

{

 y=3.1415/5.0*(float)j;

 ctrlpoints[i][j][0]=x;

 ctrlpoints[i][j][1]=y;

 ctrlpoints[i][j][2]=sin(x+y);

}

}

  glClearColor(0.0, 0.0, 0.0, 0.0);

  glEnable(GL_DEPTH_TEST);

  glMap2f(GL_MAP2_VERTEX_3, 0, 4, 3, 4,

          0, 4, 18, 4, &ctrlpoints[0][0][0]);

  glEnable(GL_MAP2_VERTEX_3);

  glEnable(GL_AUTO_NORMAL);

 glMapGrid2f(10, 0.0, 4.0, 10, 0.0, 4.0);

  initlights();       /* for lighted version only */

}

void reshape(int w, int h)

{

  glViewport(0, 0, 400, 400);

  glMatrixMode(GL_PROJECTION);

  glLoadIdentity();

        glOrtho(-1.0,2.0, -1.0, 2.0, -2.0, 2.0);

  glMatrixMode(GL_MODELVIEW);

  glLoadIdentity();

}

void keyboard(unsigned char key, int x, int y)

{

  switch (key) {

     case 27:

        exit(0);

        break;

  }

}

int main(int argc, char **argv)

{

  glutInit(&argc, argv);

  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

  glutInitWindowSize (500, 500);

  glutInitWindowPosition (100, 100);

  glutCreateWindow(argv[0]);

  init();

  glutReshapeFunc(reshape);

  glutDisplayFunc(display);

  glutKeyboardFunc(keyboard);

  glutMainLoop();

  return 0;

}


 

А также другие работы, которые могут Вас заинтересовать

40109. Методы штрафных функций и методы центров в выпуклом программировании 90 KB
  Методы штрафных функций и методы центров в выпуклом программировании Метод штрафных функций Постановка задачи Даны непрерывно дифференцируемые целевая функция fx = fx1 xn и функции ограничений gjx = 0 j = 1 m; gjx 0 j = m1 p определяющие множество допустимых решений D. Требуется найти локальный минимум целевой функции на множестве D т. Стратегия поиска Идея метода заключается в сведении задачи на условный минимум к решению последовательности задач поиска безусловного минимума вспомогательной функции: Fx Ck =...
40110. Методы наискорейшего и координатного спуска для минимизации выпуклой функции без ограничений. Их алгоритмы и геометрическая интерпретация 94.5 KB
  Все методы спуска решения задачи безусловной минимизации различаются либо выбором направления спуска, либо способом движения вдоль направления спуска. Решается задача минимизации функции f(x) на всём пространстве Rn. Методы спуска состоят в следующей процедуре построения последовательност
40111. Субградиент как обобщение понятия градиента. Субградиент для функции максимума. Субградиентный метод и его геометрическая интерпретация в R2 141 KB
  Субградиент для функции максимума. Градиентом дифференцируемой функции fx в точке называется вектор частных производных.x0 y0 а значение lim называется частной производной функции f по x в т. Вектор называется субградиентом опорным вектором функции fx в точке если выполняется: Таких с множество но это множество ограничено и замкнуто.
40112. Типичные производственные функции с несколькими ресурсами: линейная ПФ, степенная ПФ, ПФ с постоянными пропорциями. Коэффициенты эффективности использования ресурсов для этих типов функций 162 KB
  Коэффициенты эффективности использования ресурсов для этих типов функций. Производственные возможности н х в любой момент времени определяются 2мя группами факторов: технологические условия производства которые выражают зависимости между затратами разных ресурсов и выпуском продукции объем и качество используемых ресурсов fx производственная функция зависимость результата производства объема выпуска продукции от затрат ресурсов. X = х1 хm вектор затрат ресурсов. ПФ характеризует максимально возможный выпуск продукции при...
40113. Показатели эффективности использования производственных ресурсов (коэффициенты средней и предельной эффективности). Коэффициент эластичности выпуска. Вычисление этих показателей для степенной производственной функции 134.5 KB
  Средняя эффективность использования ресурсов показывает отдачу от каждой единицы iго ресурса. Предельная эффективность показывает предельный прирост выпуска продукции при увеличении затрат iго ресурса на малую величину. При этом важен характер изменения эффективности дополнительных количеств используемого ресурса. Если найдем максимальный то определим от какого ресурса получим наибольшую отдачу т.
40114. Модель оптимального поведения потребителей на рынке товаров в условиях товарно-денежных отношений 85.5 KB
  Модель оптимального поведения потребителей на рынке товаров в условиях товарноденежных отношений. Исследуется поведение некоторой группы потребителей на рынке на котором представлены n товаров которые будем обозначать: y = y1 yn набор товаров услуг р = р1 рn заданные цены на товары услуги. Тогда задача имеет вид: Графическая интерпретация для случая двух товаров: Линии уровня имеют такой вид так как чем больше потребитель потребляет товар тем менее предпочтительным он становится Присутствующий в модели принцип...
40115. Вариантная задача развития и размещения производства. Метод коэффициентов интенсивности 98 KB
  Отраслевая модель перспективного планирования разрабатывается на 5-15 лет. В пределах этого времени очень часто показатели принимаются за постоянные. Если же относительно некоторых экономических показателей нельзя сделать предположение о постоянстве, то учитывается изменение во времени за некоторый период времени. При этом показатели вычисляются приближенно с помощью коэффициента дисконтирования.
40116. Модель с фиксированным размером заказа 51 KB
  Модель с фиксированным размером заказа Целесообразность создания запасов: 1 наличие запасов позволяет быстро удовлетворять потребности потребителей. В рассматриваемой системе размер заказа является постоянной величиной и повторный заказ подается при условии что уровень наличных заказов снижается до определенного критического уровня который в теории управления запасами называется точкой заказа. Система с фиксированным размером заказа основана на выборе размера партии минимизирующего общие издержки управления запасами. При этом...
40117. Модель с фиксированным уровнем запасов 44.5 KB
  Модель с фиксированным уровнем запасов основана на фиксированных моментах подачи заказа. В модели издержки управления запасами в явном виде не рассматриваются и фиксированный размер заказа отсутствует. Mx уровень запасов M определяется по формуле: М = В SL L R 1 где L время выполнения заказа R интервал м у проверками 0 R 2R моменты проверки наличия товара на складе 0 L R L 2R L моменты поставки заказа. примерно в случаев фактический сбыт за время доставки заказа м.