14576

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

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

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

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

Русский

2013-06-08

75 KB

64 чел.

Лабораторная работа № 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;

}


 

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

1218. Базы данных 1.62 MB
  Проектирование однотабличной базы данных. Создание и использование фильтров. Создание многотабличной базы данных. Установление взаимосвязей между таблицами. Создание экранной формы. Создание элементов управления на форме. Создание главной кнопочной формы. Создание отчета. Создание подчиненного отчета. Вычисления в отчетах. Создание и управление базой данных с помощью SQL – операторов.
1219. Основы работы с СУБД MS Access 1.51 MB
  Редактирование таблиц, создание форм и запросов в СУБД MS Access. Изменение структуры таблиц. Редактирование таблиц, сортировка и фильтрация записей. Создание в Конструкторе (самый сложный). Использование макросов, обмен данными между СУБД MS Access и MS Excel, создание сетевых приложений.
1220. Технологический процесс термической обработки деталей машин 1.5 MB
  Основные задачи и исходные данные для курсового проектирования. Общие методические указания к выполнению курсовой работы. Разработка технологического маршрута изготовления детали. Разработка технологического процесса термической обработки. Основные требования к оформлению расчетно-пояснительной записки и чертежей.
1221. Экономика и организация производства 1.01 MB
  Бизнес-план - основной документ для оценки и обоснования реализации проекта в условиях конкуренции. Требования к оформлению и защите курсовой работы. Цели и задачи курсовой работы.
1222. Бухгалтерский финансовый учет 476 KB
  Учет кассовых операций. Учет операций на счетах в банках. Учет материально - производственных запасов. Учет внеоборотных активов. Учет финансовых вложений. Учет кредитов и займов. Ведения кассовых операций с банкнотами и монетой банка России.
1223. Технологический процесс подготовки и производства издания художественной литературы 710.5 KB
  История офсетной печати. Роль офсетной печати в полиграфическом производстве. Тенденции развития современных полиграфических технологий. Анализ действующего предприятия по выпуску аналогичной продукции. Выбор и обоснование выбора способа печати.
1224. Економіка та економічні системи України 901.5 KB
  Агропромисловий комплекс України і його адаптація до ринкових умов. Особливості банківської системи її Україні. Валовий внутрішній продукт та його структура. Валютні операції та їх види. Досконала і недосконала конкуренція. Економічна конкуренція, її форми та методи.
1225. Информационная основа управления финансами 862.5 KB
  Информационное обеспечение финансового менеджмента предприятия. Внешние и внутренние пользователи финансовой отчетности. Финансовая отчетность в системе финансового менеджмента. Использование информационной системы в финансовом менеджменте. Информационное обеспечение контроллинга.
1226. Компьютерное моделирование 1.06 MB
  Язык моделирования GPSS. Неформальное введение в имитационное компьютерное моделирование на языке GPSS. Аналитическое и имитационное моделирование. Проверка адекватности и корректировка модели. Экономико-математические модели и методы.